tags:

views:

40

answers:

3

Hi.

I've created several helper functions which I use when creating templates for Wordpress. An example is this:

function the_related_image_scaled($w="150", $h="150", $cropratio="1:1", $alt="", $key="related" )

The problem is, if I only want to pass along the $alt parameter, I also have to populate $w, $h and $cropratio.

In one of my plugins, I use the following code:

function shortcode_display_event($attr) { 
    extract(shortcode_atts(array(
        'type' => 'simple',
        'parent_id' => '',
        'category' => 'Default',
        'count' => '10',
        'link' => ''
    ), $attr));

  $ec->displayCalendarList($data); 
}

This allows me to call the function only using e.g.count=30.

How can I achieve the same thing in my own functions?

SOLUTION
Thanks to my name brother (steven_desu), I have come up with a solution that works.

I added a extra function (which I found on the net) to create value - pair from a string.

The code looks as follows:

// This turns the string 'intro=mini, read_more=false' into a value - pair array
function pairstr2Arr ($str, $separator='=', $delim=',') {
    $elems = explode($delim, $str);
    foreach( $elems as $elem => $val ) {
        $val = trim($val);
        $nameVal[] = explode($separator, $val);
        $arr[trim(strtolower($nameVal[$elem][0]))] = trim($nameVal[$elem][1]);
    }
        return $arr;
}

function some_name($attr) {
  $attr = pairstr2Arr($attr);

  $result = array_merge(array(
        'intro' => 'main',
        'num_words' => '20',
        'read_more' => 'true',
        'link_text' => __('Read more')
    ), $attr);

  extract($result);

  // $intro will no longer contain'main' but will contain 'mini'
  echo $intro;
}

some_name('intro=mini, read_more=false')

Info
With good feedback from Pekka, I googled and found some info regarding the Named Arguments and why it's not in PHP: http://www.seoegghead.com/software/php-parameter-skipping-and-named-parameters.seo

A: 

New Answer:

Could you not write the function using the extract function's default EXTR_OVERWRITE option?

function the_related_image_scaled($params) {
    $w="150"; $h="150"; $cropratio="1:1"; $alt=""; $key="related";
    extract($params);
    //Do Stuff
}

Called with:

the_Related_image_scaled(array("alt"=>"Alt Text"));

You have the option of defaulting the parameters to null and only using them if they are not null:

function the_related_image_scaled($w=null, $h=null, $cropratio=null, $alt=null, $key = null) {
    $output = //Get the base of the image tag
              //including src leave a trailing space and don't close
    if($w!==null) {
        $output .= "width=\"$w\"";
    }
    //... Through all your parameters
    return $output;
}

So only passing the alt parameter would look like:

echo the_related_image_scaled(null,null,null,$alt);
Kevin Stich
That's not really a good solution - to go through all your parameters. A better solution would be to use `extract` (http://php.net/manual/en/function.extract.php) as Pekka has explained in another post (http://stackoverflow.com/questions/1870917/help-with-passing-arguments-to-function)
Steven
Right, just giving you the alternative.
Kevin Stich
+1  A: 

I would suggest using array_merge() and extract() at the beginning of your function, then passing parameters as arrays if this is a possibility.

function whatever($new_values){
    $result = array_merge(array(
        "var1" => "value1",
        "var2" => "value2",
        "var3" => "value3"
    ), $new_values);
    extract($result);

    echo "$var1, $var2, $var3";
}

whatever(array("var2"=>"new_value"));

The above will output:

value1, new_value, value3

it's a bit sloppy and uses more memory since it has to allocate the arrays, so it's the less efficient solution. But it does allow you to avoid redundancy. I'm sure a better method exists using magic meta-code, but I can't think of it off-hand.

steven_desu
I think there is a problem with this. Quote from http://no2.php.net/manual/en/function.array-merge.php : "If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended." So if `var2 = 3` and `value2 = 2` then `var2` will have 32 (or 5 - not sure if it adds it)
Steven
But maybe the "" or '' will solve this and handle it as a string?
Steven
I added an extra function in order to make it easier to pass value - pairs. See updated code above.
Steven
An additional downside to simulating named arguments this way is that the parameters can't be defined using PHPDocumentor any more. What I like to do against that is declare all the parameters in the function, but make all of them but the first one optional. The first one can then be the associative array containing the values.
Pekka
A: 

Say this is your function:

function related_image_scaled($w="150", $h="150", $alt="", $key="related")

You can do this:

class ImageScaleParams {
    public $w = 150;
    public $h = 150;
    public $cropratio = "1:1";
    public $alt = "";
    public $key = "related";
}

function related_image_scaled(ImageScaleParams $params) { ... }

Then call it like this:

$imgscale = new ImageScaleParams();
$imgscale.alt="New Alt";
related_image_scaled($imgscale);

You can also have various factories in ImageScaleParams such as:

class ImageScaleParams {
    static function altFactory($alt) {
        $imgscale = new ImageScaleParams();
        $imgscale->alt = $alt;
        return $imgscale;
    }
}

Which you could call like this (equivalent to previous example):

related_image_scaled(ImageScaleParams::altFactory("New Alt"));
dkamins