views:

272

answers:

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 = "";
 }
A: 

i think that the example is fine. i don't think there is much more optimization to be done here, except of maybe leaving out few brackets.

optionally, you can check extract function in PHP

dusoft
A: 

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.

cletus
That (`$postDetailArray['title']`) would issue a Notice.
Ionuț G. Stan
+4  A: 

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($postDetailArray) {

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

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

}

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

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
}
andreas
A: 

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.

smack0007
+5  A: 

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.

Inspire
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 Haigh
@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
Inspire
Actually on second thought my example iterates over the $fields array as opposed to $postDetailArray so the key check wouldn't be necessary.
Inspire
oh yeah, you are right, sorry
Tom Haigh
+2  A: 

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'];
}
Ionuț G. Stan
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.
grantwparks