Findo Findo - 1 year ago 129
PHP Question

How do I sort by nested php array

This is an excerpt from the xml feed I'm accessing:

xml feed

And here's my current code:

$file = file_get_contents('feed.xml');
$file = preg_replace('/(<role[^>]+>)([^<]+)/si', '$1', $file);
$xml = new SimpleXMLElement($file);

$search_term = preg_replace('/[,.\/\\\(\)\[\]\{\}`~!@#\$%\^&*;:\'"\-_<>]*/is', '', $_GET['work']);

$productions = $xml->xpath('//production');

<table width="300px" cellspacing="5px" cellpadding="5px" border="1px" >

foreach($productions as $prod) {

$prod_attrs = $prod->attributes();
$prod_date = $prod_attrs->startdate;

echo "<tr><td>", $prod_date, "</td><td>", html_encode($prod_attrs->company), "</td></tr>";



This is the output:

My question is, how do I get the table to sort in descending numerical order (i.e. most recent year first)? I've searched here and tried to understand the
function (e.g. this answer), but it's a bit beyond me still and I can't figure out how to get that to work here.


I'm playing around with @Chris Goddard's answer below..

This is the code I've got, but it doesn't seem to have done the trick:


function html_encode($var){

$var = html_entity_decode($var, ENT_QUOTES, 'UTF-8');
$var = htmlentities($var, ENT_QUOTES, 'UTF-8');
return $var;

$file = file_get_contents('feed.xml');
$file = preg_replace('/(<role[^>]+>)([^<]+)/si', '$1', $file);
$xml = simplexml_load_string($file);
$json = json_encode($xml);
$array = json_decode($json,TRUE);

$search_term = preg_replace('/[,.\/\\\(\)\[\]\{\}`~!@#\$%\^&*;:\'"\-_<>]*/is', '', $_GET['work']);

$works = $xml->xpath('//work');

foreach($works as $work) {
$Productions = $work->xpath('./production');

$Sorter = array();

foreach ($Productions as $prod) {

$prod_attrs = $prod->attributes();
$Sorter[$key] = $prod_attrs->startdate;
array_multisort($Sorter, SORT_DESC, $Productions);
echo "<pre>".print_r($works, true)."</pre>";

What am I doing wrong?

Answer Source

I dont understand half of that code (what's all the regex for?), but to achieve desired sorted table you can simply do:

$profile = simplexml_load_file('');
$productions = $profile->xpath(

to load the XML and get the list of all productions as they appear in the XML. To sort them you can use a custom sort:

usort($productions, function($a, $b) {
    return $b['startdate'] - $a['startdate'];

which will compare the startdates of the simplexml elements and sort them in descending order. And then it's only a matter of just iterating the productions:

    <?php foreach ($productions as $production): ?>
            <td><?php echo htmlspecialchars($production['startdate'])?></td>
            <td><?php echo htmlspecialchars($production['company'])?></td>
    <?php endforeach; ?>

See demo

Also see this demo for your additional requests in chat, e.g. limit productions to those with a review and sorting works by production startdate.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download