7

I'm sure there is a better to this. Any help will be greatly appreciated.

I want to pass an array to a php function that contains the argument and all the arguments are optional. I'm using code ignitor and am by no means an expert. Below is what i have been using so far:

function addLinkPost($postDetailArray) {

    if (isset($postDetailArray['title'])) {
        $title = $postDetailArray['title']; }
    else {
        $title = "Error: No Title";
    }

    if (isset($postDetailArray['url'])) {
        $url        = $postDetailArray['url'];
    } else {
        $url        = "no url";
    }
    if (isset($postDetailArray['caption'])) {
        $caption    = $postDetailArray['caption'];
    } else {
        $caption    = "";
    }
    if (isset($postDetailArray['publish'])) {
        $publish    = $postDetailArray['publish'];
    } else {
        $publish    = TRUE;
    }
    if (isset($postDetailArray['postdate'])) {
        $postdate   = $postDetailArray['postdate'];
    } else {
        $postdate   = "NOW()";
    }
    if (isset($postDetailArray['tagString'])) {
        $tagString  = $postDetailArray['tagString'];
    } else {
        $tagString = "";
    }

6 Answers 6

27

You can use an array of defaults and then merge the argument array with the defaults. The defaults will be overridden if they appear in the argument array. A simple example:

$defaults = array(
    'foo' => 'aaa',
    'bar' => 'bbb',
    'baz' => 'ccc',
);

$options = array(
    'foo' => 'ddd',
);


$merged = array_merge($defaults, $options);

print_r($merged);

/*

Array
(
    [foo] => ddd
    [bar] => bbb
    [baz] => ccc
)

*/

In your case, that would be:

function addLinkPost($postDetailArray) {
    static $defaults = array(
        'title'     => 'Error: No Title',
        'url'       => 'no url',
        'caption'   => '',
        'publish'   => true,
        'postdate'  => 'NOW()',
        'tagString' => '',
    );

    $merged = array_merge($defaults, $postDetailArray);

    $title     = $merged['title'];
    $url       = $merged['url'];
    $caption   = $merged['caption'];
    $publish   = $merged['publish'];
    $postdate  = $merged['postdate'];
    $tagString = $merged['$tagString'];
}
Sign up to request clarification or add additional context in comments.

3 Comments

This is the way to do it. You get the desired result and you get a very readable summary of what the default values are. It's essentially letting PHP do for you instead of looping, yourself. PHP provides so many wonderful array functions, that I abhor looping over an array -- whenever I see looping through an array, I smell something that can probably be replaced by native array functions.
Agree - this is by far the most readable way to do this. Less LOC is not always better.
Elegant! Note, however, that a use of a separate "merged' array is not strictly necessary. I'm adding the following as a drop-in improvement to my existing code: $argsR = array_merge ($defaultsR, $argsR; ($argsR being the existing function arguments array passed to and processed by the existing function).
10

You could do it like this:

function addLinkPost(array $postDetailArray)
{
    $fields = array(
        'key' => 'default value',
        'title' => 'Error: No Title',
    );

    foreach ($fields as $key => $default) {
        $$key = isset($postDetailArray[$key]) ? $postDetailArray[$key] : $default;
    }
}

Simply edit the $fields array with your key and its default value.

3 Comments

You should be a bit careful doing stuff like this, especially if the data is user-supplied, because it is similar to register_globals.
@Tom Although personally I'd implement it using an array to store the values as opposed to the function local variable scope he used in his question and I used in my response, you could implement a quick check in the foreach loop to ignore any supplied keys that are not in the $fields array
Actually on second thought my example iterates over the $fields array as opposed to $postDetailArray so the key check wouldn't be necessary.
4

Using the array as an argument is a good idea in this case. However, you could simplify the code in the function a bit by using the ternary operator (http://dk.php.net/ternary):

$title = isset($postDetailArray['title']) ? $postDetailArray['title'] : 'Error: No Title';

You could simplify it even more by doing the following:

function addLinkPost($data) {

$arguments = array('title', 'url', 'caption', 'publish', 'postdate', 'tagString');

foreach ($arguments as $value) {
    $$value = isset($data[$value]) ? $data[$value] : 'Error: No '.$value;
}

}

1 Comment

Just noticed that it shouldn't be 'Error: No ...' for all of the options, but still... You get the idea.
0

Try this:

function addLinkPost($postDetailArray) {

   foreach($array as $key=>$value){
     $$key = (isset($value) && !empty($value)) ? $value : ('no '.$key);
   }
   //all keys are available as variables 
   var_dump($url); var_dump($publish); //etc
}

Comments

0

You could make all elements of the array parameters of the function. Check if the first is an array in the function and if so, extract the array.

 function addLinkPost($title = null, $url = null, $caption = null, $publish = null, $postDate = null, $tagString = null)
 {
      if(is_array($title)) {
           extract($title);
      }

      ....
 }

Maybe that makes the code a little more clear.

Comments

0

How about:

function getdefault($value, $default = null) {
  return isset($value) ? $value : $default;
}

function addLinkPost($postDetailArray) {
  $title = getdefault($postDetailArray['title'], 'Error: No Title');
  $url = getdefault($postDetailArray['url'], 'no url');
  $caption = getdefault($postDetailArray['caption'], '');
  $publish = getdefault($postDetailArray['publish'], TRUE);
  $postdate = getdefault($postDetailArray['postdate'], 'NOW()');
  $tagString = getdefault($postDetailArray['tagString'], '');
}

or alternatively:

$defaults = array(
  'title' => 'Error: No Title',
  'url' => 'no url',
  'caption' => '',
  'publish' => TRUE,
  'postdate' => 'NOW()',
  'tagString' => '',
);

function addLinkPost($postDetailArray) {
  global $defaults;
  foreach ($defaults as $k => $v) {
    $$k = isset($postDetailArray[$k]) ? $postDetailArray[$k] : $v;
  }
}

With the one warning that if you have an array key of 'defaults' in $defaults, it will overwrite the global $defaults.

1 Comment

That ($postDetailArray['title']) would issue a Notice.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.