views:

111

answers:

4

Here's what I am trying to accomplish:

function foo($args) {
 switch($args['type']) {
  case 'bar':
  bar($args['data']);   // do something
  break;
 }
}

// or something like that

Which is basically a way of using named parameters in PHP.

Now, in order to build this $args array, I am forced to write ugly syntax like:

$builtArgs = array('type' => 'bar',
     'data' => array(1, 2, 3),
     'data2' => array(5, 10, 20)
  );

foo($builtArgs);

Which gets uglier as I add more dimensions to the array, and also forces me to write tons of array(...) constructs. Is there a prettier way to do this?

For one thing, it could be done if we could use Python-like syntax:

$buildArgs = {'type' : 'bar', 'data' : [1, 2, 3], 'data2' : [5, 10, 20]};

But it is PHP.

+2  A: 

No. Alternative syntaxes for creating arrays have been proposed several times (the link lists 5 separate threads in the dev mailing list), but they were rejected.

Artefacto
I've seen the proposals, but I don't see their rationale for not implementing it.
quantumSoup
@Aircule there is a number of links at the bottom of the page where it says: *Discussion on the List*. Plenty rationale to read through.
Gordon
+2  A: 

No, there is no "short-syntax" to write arrays nor objects, in PHP : you have to write all those array().
(At least, there is no such syntax... yet ; might come in a future version of PHP ; who knows ^^ )

But note that have too many imbricated arrays like that will makes things harder for people who will have to call your functions : using real-parameters means auto-completion and type-hinting in the IDE...

Pascal MARTIN
+2  A: 

There are no alternatives to constructing these nested arrays-- but there are options in how you can format your code that makes it readable. This is strictly preference:

return array
(
    'text' => array
    (
        'name'      => 'this is the second',
        'this'      => 'this is the third',
        'newarr'    => array
        (
            'example'
        ),
    )
);


// Or using the long way

$array = array();

$array += array
(
    'this' => 'is the first array'
);
Jon
+4  A: 

You could create a JSON-encoded string and use json_decode() to convert it into a variable. This has syntax very similar to the Python-like syntax you mentioned.

$argstr = '{"type" : "bar", "data" : [1, 2, 3], "data2" : [5, 10, 20]}';
$buildArgs = json_decode($argstr, true);

EDIT: Updated code to accommodate @therefromhere's suggestion.

okalex
+1 for cleverness
Scott Evernden
It's just that I'm worried that someone might start doing this... :D
Jani Hartikainen
if you pass in true as the second parameter to json_decode then it will return nested arrays as desired. http://php.net/manual/en/function.json-decode.phpUpvoting you since does what the OP is asking for, but I have my reservations about using this - for one thing you'd not get any syntax checking until you decode the string.
therefromhere
Well, I'm not saying I recommend it. It's definitely better to suck it up and use PHP's built-in array declarations, but it does make it easier to visualize complex variables, IMO. Especially because the string can span multiple lines and use indentation to show information hierarchy.
okalex
@therefromhere: I didn't realize that. Thanks for the catch. I updated the code accordingly.
okalex
@Jani, what's wrong with that? I don't know PHP, that's why I'm asking.
OscarRyz
Uhm, I can't explain it very well but it just seems wrong to me to use such a convoluted/hacky workaround to having to type array and one extra character per variable... You're writing two lines of code instead of those 5 + n characters. I mean if you got a huge benefit from doing it like that, sure, but I don't see one here.
Jani Hartikainen
Actually, it's not *that* clever because it will fail once you want to pass in any typed objects: `var_dump(json_decode(json_encode(new ArrayObject(array('foo'=>'bar')))));` will return the ArrayObject as StdClass.
Gordon
That's why the second argument to `json_decode()` is `true`. `var_dump(json_decode(json_encode(new ArrayObject(array('foo'=>'bar'))), true));` returns an array, as expected.
okalex
No, you're missing the point. It doesn't matter if you specify the second argument or not. After decoding, the ArrayObject is either an Array or a StdClass object. It will lose it's type. Imagine you use this approach to inject a database adapter to a class. There is no way to pass in, for instance, a PDO object through Json, because Json only knows arrays and objects, but not typed objects. You could encode the PDO object to Json, but you would not be able to decode it into a PDO then. It will be a plain object, with no methods whatsoever.
Gordon
That may be true, but the OP simply wanted a cleaner syntax to create arrays, not PDO objects or any objects whatsoever.
okalex
@okalex, the answer provides a cleaner syntax to create *some* arrays, but will fail with certain content, because JSON only allows very basic types (string, number, boolean, null, and arrays and objects containing only those types). Which is to say that while this "solution" accommodates data like `{ "foo": "bar", ["zig", "zag"] }`, it will never accommodate data like `{ "foo": someClassInstance }`, which the Python-like syntax requested would allow. In short, the question is asking for syntactic sugar for PHP arrays (and all that encompasses), not how to parse JSON.
eyelidlessness