Implementing Ruby-Like Arrays in PHP

I program in PHP most of the time, and Ruby sometimes I need a way to implement these "hash arguments" in my PHP functions (like, say, the HTML picker)

draw_select :name => :id, :onclick => 'alert(this.value)'

      

The problem in PHP is that I will need to define the order of the arguments to implement the many possible attributes.

I thought to just define 1 string argument and use json_decode (), so I can pass arguments like this:

draw_select("'name': 'id', 'onclick': 'alert(this.value)' ")

      

the definition will be as follows:

function draw_select($string) {
// use json_decode here and pass them as variables
}

      

Do you know a smarter way to do this .. or do you think hovering over this in PHP really makes some sense?

Edited to add: I'm looking for an alternative alternative to just pass the signle array as an argument, like function (array (...))

+1


a source to share


6 answers


PHP definitely lacks sugar in this aspect. I am a lot of python too, and I really miss named arguments when using PHP. With PHP, however, whenever I have a function that needs to take many parameters, I just accept one or two required / important arguments and an array for the rest:

function draw_select($name, $options = array(), $html_options = array()) {

}

      



This is how libraries like CodeIgniter and CakePHP handle the same script <select>

.

Personally, using JSON in this situation doesn't really do much good when PHP's associative arrays are so powerful. Just stick with what the language gives you and this is the way to do it with PHP.

+3


a source


Why not pass an array instead?



draw_select(array(
  'name'=> 'id', 
  'onclick'=> 'alert(this.value)'
));

      

+5


a source


There is no way 1 to do this in any PHP version up to PHP 5.3.

PHP does not support named parameters and / or smalltalk / objective-c / ruby ​​styles. PHP does not offer a way to override this part of the language. If you want this in PHP, you're out of luck. PHP has never been the best choice of language for so-called "metaprogramming".

As others have noted, it is best to use PHP with an array with key / value pairs in combination with fetch.

myFunction(array(
    'theThing'=>0,
    'param2'=>'another value',
));

function myFunction($params){
    extract($params);
    echo $param2;
}   

      

  • Perhaps you could write an extension in C / C ++ to extend PHP with this ability, but you would be a masochist. :)
+1


a source


Since all the options here involve a call array

, and it looks like this is the "PHPish" way of doing things, I'll use that if you do this all the time, it might make sense to have a function z()

(I just think line by line $()

in jQuery), which pseudonizes to array()

. Apart from the length of the array of names, I don't see how the Ruby version is more elegant. There are fewer symbols, but I am somewhat uncomfortable that you cannot tell the difference between a function parameter and a key / value pair right away in this code example.

0


a source


The solution is to use variable arguments.

I sometimes use this with languages ​​that don't natively support associative arrays.

function AssociativeArrayFromFlatArray($args)
{
    $nbArgs = count($args);
    if( $nbArgs % 2 != 0 )
    {
        die('This function must have an even number of arguments');
    }

    $ret = array();
    for( $i = 0; $i < $nbArgs; $i += 2 )
    {
        $key = $args[$i];
        $value = $args[$i + 1];
        $ret[$key] = $value;
    }
    return $ret;
}

function DoSomething(/*...*/)
{
    $args = AssociativeArrayFromFlatArray(func_get_args());

    if( $args['action'] == 'greet' )
    {
        $count = $args['count'] or 1;
        for( $i = 0; $i < $count; $i += 1 )
        {
            echo $args['text'];
        }
    }
}

DoSomething('action', 'greet', 'count', 10, 'text', 'Hello World! ');

      

Although it's a shame to use this for PHP as it supports associative arrays ...

0


a source


You can use the " func_get_args()

" function and just use every first parameter as var name and every second as value. This is probably as close as you are going to get to the ruby ​​path (I've searched ages along the way to this, I understand exactly what you mean about the ruby ​​graceful array solution). Hopefully in the future PHP will open it up to reprogram to do as ruby ​​might be (don't know what it's actually called, but that's what makes ruby ​​and ruby ​​on rails so brilliant).

0


a source







All Articles