Multidimensional Array Search Using Xpath Wildcards in PHP

As part of some ongoing improvements to my Validation Class I had need to be able to validate posted data from dynamically generated forms.

It's still a little rough around the edges and doesn't fully replicate the Xpath syntax, but it gives just enough functionality to be able to easily search a large multidimensional array. 

Download

Click here to start the downloadFile NameKP-Array-Xpath-vCurrent.zip
Version: 1.2 (05/12/2012)
File Size: 13kb
Contains: KP-Array-Xpath class and example.

How it works

Lets say we have a form for adding car manufacturers that allows us to add multiple manufacturers and multiple models in one go, which posts the following data...

$testData = array(
	'manufacturer' => array(
		'1' => array(
			'name' => 'Ford',
			'models' => array(
				'1' => array(
					'model-name' => 'Fiesta',
					'model-type' => 'Car',
				),
				'2' => array(
					'model-name' => 'Transit',
					'model-type' => 'Van',
				),
			),
		),
		'2' => array(
			'name' => 'Volkswagen',
			'models' => array(
				'1' => array(
					'model-name' => 'Golf',
					'model-type' => 'Car',
				),
			),
		),
	),
);

Now, lets say we need to validate the model-types to make sure they don't contain any silly characters etc. 

We instantiate a new arrXpath object and pass it our data, it will then process that array and produce an array of all the key paths found in the data.

// instantiate a new class and pass it our data
$fact = new arrayXpathFactory();
$inst = $fact->createInstance($testData);
// this will build the array key paths for the whole data structure
Array
(
    [0] => manufacturer
    [1] => manufacturer/1
    [2] => manufacturer/1/name
    [3] => manufacturer/1/models
    [4] => manufacturer/1/models/1
    [5] => manufacturer/1/models/1/model-name
    [6] => manufacturer/1/models/1/model-type
    [7] => manufacturer/1/models/2
    [8] => manufacturer/1/models/2/model-name
    [9] => manufacturer/1/models/2/model-type
    [10] => manufacturer/2
    [11] => manufacturer/2/name
    [12] => manufacturer/2/models
    [13] => manufacturer/2/models/1
    [14] => manufacturer/2/models/1/model-name
    [15] => manufacturer/2/models/1/model-type
)

 Now we can filter that data using our xpath like syntax and pull out just the data we need.

// now filter using a wildcard
$arrFiltered = $inst->filter('manufacturer/*/models/*/model-type');
// gives us...
Array
(
    [manufacturer/1/models/1/model-type] => Car
    [manufacturer/1/models/2/model-type] => Van
    [manufacturer/2/models/1/model-type] => Car
)

That's pretty much alll there is to it.

There's also a fully working version of the above example in the download.

Version History

VersionRelease DateComments
v1.1 05/12/2012 Created this readme.txt!
Changed to use a factory class so it works better with dependency injection.
Changed name of class from arrXpath to arrayXpath.
Updated demo accordingly.
v1.0 04/12/2012 Initial release.

License

The boring bit, GPL v3 basically, click the logo for more info.

 GNU GPL v3 Logo

By Karl Payne

Comments

There are no comments, don't be shy, somebody has to be first.

Leave a comment