I've read what I've found on Stackoverflow and am still unclear on this.
I have an array of SimpleXML objects something like this:
array(2) {
[0]=>
object(SimpleXMLElement)#2 (2) {
["name"]=>
string(15) "Andrew"
["age"]=>
string(2) "21"
}
[1]=>
object(SimpleXMLElement)#3 (2) {
["name"]=>
string(12) "Beth"
["age"]=>
string(2) "56"
}
}
And I want to be able to sort by whatever column, ascending or descending. Something like:
sort($data, 'name', 'asc');
Where I can pass in the above array of objects and sort by the value of whichever key I like.
For reference, a similar .NET solution would be along these lines:
XmlSortOrder order = XmlSortOrder.Ascending;
if ( sortDirection == "asc" ) {
order = XmlSortOrder.Ascending;
}
expression.AddSort( columnSortingOn + "/text()", order,
XmlCaseOrder.UpperFirst, "en-us", XmlDataType.Text );
I've seen people say
"Use usort"
Followed by a basic example from the PHP manual but this doesn't really explain it. At least not to me. I've also seen people suggest using an external library like SimpleDOM but I want to avoid using something external for this (seemingly, though I cannot yet solve it) little thing.
Any help is appreciated, Thanks!
Josh Davis' solution doesn't seem to work when loading an XML file via:
I get the following error:
Warning: array_multisort() [function.array-multisort]: Argument #3 is expected to be an array or a sort flag in /home/usr/public_html/feeds/deadlines.php on line 8
It relates to: array_multisort($sort_proxy, $order, $nodes);
I was ready to recommend
usort()
until I realized you already beat me to it. Since code examples haven't done much good in the past, I'll try to just explain it in plain English and hopefully that'll get you pointed in the right direction.By using
usort()
, you create your own user-generated "algorithm". Theusort()
function calls your own comparison function to determine how each of your objects relates to one another. When writing your comparison function, you will get passed in two objects within your array. With those two objects, you return a result that essentially tellsusort()
whether the first object isLESS THAN
,EQUAL TO
, orGREATER THAN
the second object. You do this by returning -1, 0, or 1 (respectively). That's it. You only have to concern yourself with how two objects compare to each other and the actual sorting mechanics are handled byusort()
for you.Ok, now for a semi-practical example:
This is pretty much the example in the PHP Manual, but hopefully it makes sense in context now. Let me know if I'm not being clear on something.
it's a old thread but here is my solution that a use to extract information from a rss feed in order to sort by title
Here's another example of using
usort()
. This one allows you to specify the object variable and the sort direction:Test code;
The
usort
function allows to you tell PHPIt has nothing specifically to do with SimpleXML. It's a generic function for sorting PHP built-in array data collection.
You need to write a function, instance method, or static method to sort the array. The second argument to usort accepts a PHP Callback, which is a pseudo-type that lets you specify which function, instance method, or static method.
The function you write will accept two arguments. These will be two different values from your array
You need to write this function to return one of three values.
When you call usort, PHP will run through your array, calling your sorting function/method (in this case
cmp
over and over again until the array is sorted. In your example, $a and $b will be SimpleXML objects.I guess the people suggesting to use SimpleDOM would be me. :)
I've written SimpleDOM::sort() exactly for that situation, because in order to sort SimpleXMLElements by an arbitration expression (or arbitrary expressions) you need to use
array_multisort()
which is boring and won't teach you anything useful.Here's the short version of how it works: first you create a proxy array of key=>value pairs corresponding to each SimpleXMLElement and the value with which they'll be sorted. In your example, if you want to sort them by
<age/>
, the array would bearray(21, 56)
. Then you callarray_multisort()
with the "proxy array" as first argument, followed by any number of sorting modifiers such as SORT_DESC or SORT_NUMERIC then finally the array you want to sort, which will be passed by reference.You will end up with something like that:
But really, instead of burdening yourself with more code you'll have to maintain and possibly ending up rewriting
array_multisort()
in userspace, you should leverage existing solutions. There's nothing interesting in such a sorting algorithm/routine, your time would be better spent on something that doesn't already exist.