3 ms·
I make heavy use of a similar thing in PHP. I have a function "lookup" which lets me say: lookup($foo, array('bar', 'baz' 15, 'quux')) This is equivalent
by chriswarbo 13y ago
I make heavy use of a similar thing in PHP. I have a function "lookup" which lets me say:
lookup($foo, array('bar', 'baz' 15, 'quux'))
This is equivalent to any of the following:
$foo->bar->baz[15]->quux
$foo->bar->baz[15]['quux']
$foo->bar['baz'][15]->quux
$foo->bar['baz'][15]['quux']
$foo['bar']->baz[15->quux
... and so on
It's useful in Drupal when the required data is often at the end of a long chain of objects-containing-arrays-containing-objects-....
I've been a bit naughty with its types for the sake of convenience: if a non-array is given as the second argument, it's wrapped as a singleton array, ie.
lookup(array('foo' => 'bar'), 'foo') === 'bar'
Also if any of the components aren't found, it returns NULL, ie.
lookup(array('foo' => NULL), 'foo') === lookup(array(), 'foo')
It would be theoretically better to return an empty array on error and a singleton array on success, since they can be distinguished, but in practice that's so far down the list of problems with PHP that it's not worth the effort of adding such wrappers at the moment.
A really nice thing about this function is that it curries nicely:
$find_in_foo = partially_apply('lookup', $foo)
$get_blah = partially_apply(flip('lookup'), 'blah')
$find_in_foo('x') === lookup($foo, 'x')
$get_blah($foo) === lookup($foo, 'blah')
Actually, my argument-flipping function is already curried, so I can just say:
$get_blah = flip('lookup', $foo)
This currying is great for filtering, mapping, etc.
- Jgrubb 13y agoHi, Drupal dev here. Got to the point yesterday afternoon where I'm going to have to implement exactly what you've already done in order to put out some reasonable JSON from a node_load_multiple call. Don't suppose you have this function in a gist anywhere, do you? Please?
- chriswarbo 13y agoHere's the definition and a few tests. https://gist.github.com/Warbo/9d8425fcdd7c026c795a https://gist.github.com/Warbo/9d8425fcdd7c026c795a The SimpleTest test class probably doesn't work as-is, since it is originally derived from our own class hierarchy, but shouldn't be too hard to fix.
- nubs 13y agoHave you seen guzzle's implementation of this? It's pretty useful and something I'd love to see split out of guzzle and made its own library. https://github.com/guzzle/guzzle/blob/master/src/functions.php#L180-L209 https://github.com/guzzle/guzzle/blob/master/src/functions.p... is the actual code, although it's pulled into the guzzle collection: https://github.com/guzzle/guzzle/blob/master/src/Collection.php https://github.com/guzzle/guzzle/blob/master/src/Collection....
- chriswarbo 13y agoThat smells to me: the path argument given to "get_path" is a string of components, separated by "/". The first thing get_path does is split the path apart at "/". Why doesn't it just take an array? That way, it would be a simple reduction: function get_path($data, $path) { return array_reduce( $path, function($result, $index) { return (is_array($result) && isset($result[$index]))? $result[$index] : NULL; }, $data); } Unfortunately PHP's function namespace is separate from its value namespace. We can't define "get_path" using a couple of combinators :( Also, requiring 'strings without slashes' is a pretty bad idea in PHP in particular, since it's meant for Web programming. This means a) we tend to have / in strings due to URLs and b) someone will inevitably pass user input as one of these components, which would allow a very limited form of code injection attack.
- chx 13y agoWhich version of Drupal? D7 has https://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_array_get_nested_value/7 https://api.drupal.org/api/drupal/includes%21common.inc/func... which does exactly that.
- chriswarbo 13y agoIndeed I haven't seen that before. Still, it doesn't support objects like mine does :)
- e1g 13y agoAnother implementation of this pattern is available as a component from the Symfony2 ecosystem[1]. It is flexible, well-tested, and can be easily used standalone either from Github[2] or through composer[3] [1] http://symfony.com/doc/current/components/property_access/introduction.html http://symfony.com/doc/current/components/property_access/in... [2] https://github.com/symfony/PropertyAccess https://github.com/symfony/PropertyAccess [3] https://packagist.org/packages/symfony/property-access https://packagist.org/packages/symfony/property-access
- Terr_ 13y agoConvenience-wise, you could also make a "varargs" version with `func_get_args()`, e.g: f($structure, 'bar','baz', 15, 'quux');