tdammers / aquery
Lenient traversal of nested arrays and objects
Requires
- php: >=5.3.0
Requires (Dev)
- phpunit/phpunit: 3.7.*
This package is not auto-updated.
Last update: 2024-12-17 05:53:00 UTC
README
Lenient traversal of objects and arrays
Installing
By far the easiest way is to use composer and install AQuery from packagist. The package can be found here.
Refer to the composer documentation for installation instructions; the AQuery
class is in the AQuery namespace, that is, \AQuery\AQuery
.
If you're feeling sassy, or you just want to see the source code, check out the bitbucket repo.
What It Does
AQuery provides a unified query interface for objects, arrays, and ArrayAccess objects. It encapsulates the following common pattern:
if (isset($array['foo']['bar']['baz'])) {
return $array['foo']['bar']['baz'];
}
else {
return $defValue;
}
Note how this code sample violates the DRY principle: the path into the nested
array appears twice. This means that if we want to change it, we have to change
it twice, and if we mistype one of the two, we'll get strange errors. However,
because isset
is a language construct, not a function, we cannot combine the
two statements. The following won't work:
if (isset($value = $array['foo']['bar']['baz'])) {
return $value;
}
else {
return $defValue;
}
Neither will this:
$value = $array['foo']['bar']['baz'];
if (isset($value)) {
return $value;
}
else {
return $defValue;
}
AQuery provides a nice way out, and a super-simple little query language along with it. Here's what the above example looks like with AQuery:
return AQuery::query('foo/bar/baz', $array, $defValue);
Not only does this descend into our array, it also fails gracefully by
returning the default value if the query doesn't resolve, no matter at which
level (i.e., if $array['foo']
doesn't contain a key at 'bar'
, AQuery
short-circuits and returns the default value, rather than raise a warning or
crash.
AQuery works not only on associative arrays, but also on numeric arrays, plain
objects (note, however, that if you implement __get()
, you have to also
provide a suitable __isset()
for the same keys, otherwise AQuery will not
see the magic properties thus defined), and objects that implement ArrayAccess.
Basic Usage Example
<?php
use \AQuery\AQuery;
$myArray = array(
'foo' => array(
'bar' => array(
'baz' => 'quux')));
echo AQuery::query('foo/bar/baz', $myArray);
// Or, equivalent:
echo AQuery::query(array('foo', 'bar', 'baz'), $myArray);
// For more control, or if you want to run the same query over several
// input data structures, instantiate an AQuery object explicitly:
$aquery = new AQuery('foo/bar/baz');
// Or, equivalent (overriding the separator character):
$aquery = new AQuery('foo:bar:baz', ':');
$aquery->run($myArray, "Sorry, didn't find a thing.");