排序对象(SimpleXMLElement)php [英] Sort object(SimpleXMLElement) php

查看:68
本文介绍了排序对象(SimpleXMLElement)php的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试寻找一种方法来对SimpleXMLElement中的数组进行排序.我想按可以从event_start_dt获得的开始时间进行排序.我还想按房间ID进行排序,这是一个单独的过程.当前,该数组按object(SimpleXMLElement)#的顺序排列.这是var_dump($ array):

I'm trying to find a way to sort my array from SimpleXMLElement. I'd like to sort by start time which I can get from event_start_dt. I'd also like to sort by room ID as a separate process. Currently the array is in order by object(SimpleXMLElement) #. Here is the var_dump($array):

    object(SimpleXMLElement)#275 (1) { 
["reservation"]=> array(3) 
    { 
    [0]=> object(SimpleXMLElement)#287 (28) { 
        ["reservation_id"]=> string(7) "8644894" 
        ["event_start_dt"]=> string(25) "2013-12-02T12:00:00-08:00" 
        ["event_end_dt"]=> string(25) "2013-12-02T13:00:00-08:00" 
        ["event_id"]=> string(6) "314147" 
        ["event_name"]=> string(24) "Practice" 
        ["room_id"]=> string(3) "202"
    }
    [1]=> object(SimpleXMLElement)#288 (28) { 
        ["reservation_id"]=> string(7) "8595185" 
        ["event_start_dt"]=> string(25) "2013-12-02T08:00:00-08:00" 
        ["event_end_dt"]=> string(25) "2013-12-02T09:00:00-08:00" 
        ["event_id"]=> string(6) "314005"
        ["event_name"]=> string(24) "Meeting" 
        ["room_id"]=> string(3) "207"
    }
    [2]=> object(SimpleXMLElement)#289 (28) { 
        ["reservation_id"]=> string(7) "8718654" 
        ["event_start_dt"]=> string(25) "2013-12-02T10:00:00-08:00" 
        ["event_end_dt"]=> string(25) "2013-12-02T11:00:00-08:00" 
        ["event_id"]=> string(6) "315811" 
        ["event_name"]=> string(20) "Maintenance" 
        ["room_id"]=> string(3) "202"
    }
} }

我已经尝试过usort和asort,但是还没有使它与任何一种方法一起工作.

I've tried usort and asort but haven't gotten it to work with either method.

usort方法:

function sortByTime($a, $b){
    $a = strtotime($array->event_start_dt);
    $b = strtotime($array->event_start_dt);
        if ($a==$b) return 0;
        return ($a < $b) ?-1 : 1;
        }

        usort($arrTimes, 'sortByTime');

        var_dump($arrTimes);

尝试下面的代码会给我警告:usort()期望参数1为数组,给定对象.

Trying the code below gives me warning: usort() expects parameter 1 to be array, object given.

foreach ($rez->reservation as $value){ 
    $var1 = $value->space_reservation->space_name;
    $var2 = substr($value->event_start_dt,11,5);
}
sort_obj_arr($value,$var1,SORT_DESC);

echo "<pre>SORTED ";
print_r($value);
echo "</pre>";

function sort_obj_arr(& $arr, $sort_field, $sort_direction)
{
    $sort_func = function($obj_1, $obj_2) use ($sort_field, &$sort_direction)
    {
        if ($sort_direction == SORT_ASC) {
            return strnatcasecmp($obj_1->$sort_field, $obj_2->$sort_field);
        } else {
            return strnatcasecmp($obj_2->$sort_field, $obj_1->$sort_field);
        }
    };
    usort($arr, $sort_func);

}

我有一个来自控制器的数组,但无法使用usort进行工作: 我得到了一个:usort()期望参数1为数组,给定的对象或为null.

I have an array from my controler but cannot get usort working: I get either: usort() expects parameter 1 to be array, object given or null.

$array = array($this->data);
print_r($array);

array(1) { 
[0]=> object(SimpleXMLElement)#280 (1) { ["reservation"]=> array(3) { 
        [0]=> object(SimpleXMLElement)#287 (28) { 
            ["reservation_id"]=> string(7) "8644894" 
            ["event_start_dt"]=> string(25) "2013-12-02T12:00:00-08:00" 
            ["event_end_dt"]=> string(25) "2013-12-02T13:00:00-08:00" 
            ["event_id"]=> string(6) "314147" 
            ["event_name"]=> string(24) "Practice" 
            ["room_id"]=> string(3) "202"
        }
        [1]=> object(SimpleXMLElement)#288 (28) { 
            ["reservation_id"]=> string(7) "8595185" 
            ["event_start_dt"]=> string(25) "2013-12-02T08:00:00-08:00" 
            ["event_end_dt"]=> string(25) "2013-12-02T09:00:00-08:00" 
            ["event_id"]=> string(6) "314005"
            ["event_name"]=> string(24) "Meeting" 
            ["room_id"]=> string(3) "207"
        }
        [2]=> object(SimpleXMLElement)#289 (28) { 
            ["reservation_id"]=> string(7) "8718654" 
            ["event_start_dt"]=> string(25) "2013-12-02T10:00:00-08:00" 
            ["event_end_dt"]=> string(25) "2013-12-02T11:00:00-08:00" 
            ["event_id"]=> string(6) "315811" 
            ["event_name"]=> string(20) "Maintenance" 
            ["room_id"]=> string(3) "202"
        }
    } }

请求print_r:

SimpleXMLElement Object
(
    [reservation] => Array(3)
        (
            [0] => SimpleXMLElement Object
                (
                    [reservation_id] => 8604174
                    [event_start_dt] => 2013-12-31T06:00:00-08:00
                    [event_end_dt] => 2013-12-31T08:00:00-08:00
                    [event_id] => 314147
                    [event_name] => Practice
                    [room_id] => 202
                 )
         [1] => SimpleXMLElement Object
                (
                    [reservation_id] => 8604177
                    [event_start_dt] => 2013-12-31T05:00:00-08:00
                    [event_end_dt] => 2013-12-31T06:00:00-08:00
                    [event_id] => 314150
                    [event_name] => Meeting
                    [room_id] => 216
                 )
         [2] => SimpleXMLElement Object
                (
                    [reservation_id] => 8604189
                    [event_start_dt] => 2013-12-31T10:00:00-08:00
                    [event_end_dt] => 2013-12-31T11:00:00-08:00
                    [event_id] => 314150
                    [event_name] => Maintenance
                    [room_id] => 220
                 )
)
)

$arrTimes = xml2array($array->reservation);

var_dump($arrTimes)

array(5) { 
["reservation_id"]=> string(7) "8604175" 
["event_start_dt"]=> string(25) "2014-01-02T06:00:00-08:00" 
["event_end_dt"]=> string(25) "2014-01-02T08:00:00-08:00" 
["event_id"]=> string(6) "314147" 
["event_name"]=> string(24) "Practice" 
}

推荐答案

在对数据进行排序之前,需要创建一个数组,该数组包含要排序的各个项目作为其值.从调试输出中,这些是输入XML中的多个<reservation>节点,它们是这些示例中由$array/$this->data表示的元素的子元素(无论它是否是文档的根, ,SimpleXML没有Document对象).

Before you can sort the data, you need to create an array which contains as its values the separate items you want to sort. From your debug outputs, these are multiple <reservation> nodes in the input XML, which are children of the element represented by $array/$this->data in those samples (it doesn't matter if it's the root of the document or not, SimpleXML has no Document object).

您的print_rvar_dump输出显示您当前没有这样的数组,只有一个SimpleXML对象:

Your print_r and var_dump output shows that you do not currently have such an array, only a SimpleXML object:

  • 您的第一个示例显示var_dump($array)以输出object(SimpleXMLElement)#275 (1) {开头-进一步忽略单词array,这就是var_dump呈现对象的 insides 的方式.
  • 后来,您有一个以array(1) {开头的print_r($array);-但这仅是因为您已将实际数据包装在($array = array($this->data);)上一行的单元素数组中,并将该数据包装在一个元素($array[0] >)显示为object(SimpleXMLElement)#280 (1) { ....
  • Your first example shows var_dump($array) giving output beginning object(SimpleXMLElement)#275 (1) { - ignore the word array further in, that's just how var_dump is rendering the insides of the object.
  • Later, you have a print_r($array); beginning array(1) { - but this is only because you've wrapped the real data in a single-element array on the line above ($array = array($this->data);) and that one element ($array[0]) shows as object(SimpleXMLElement)#280 (1) { ....

请注意,没有必要进一步将所有内部SimpleXML对象转换为数组-您只需要一个可排序的列表,其中包含您感兴趣的项目.我个人将使用一个简单而明确的foreach循环,尽管可以使用更聪明"的解决方案,但代码具有最大的可读性.

Note that there's no need to go further and convert all the inner SimpleXML objects into arrays - you just need a list that is sortable, containing the items you are interested in. I would personally use a simple and explicit foreach loop, for maximum code readability, although "cleverer" solutions are available.

一旦有了可排序的列表,就需要usort的回调函数,该函数将比较其两个参数.您所做的尝试是正确的,但指向的是该函数中不存在的变量($array);需要比较的值是函数的参数,分别称为$a$b-具体来说,您想将strtotime($a->event_start_dt)strtotime($b->event_start_dt)进行比较.

Once you have a sortable list, you need a callback function for usort which compares its two parameters. The attempt you've made is along the right lines, but refers to the non-existent (in that function) variable $array; the values you need to compare are the function's arguments, which you've called $a and $b - specifically, you want to compare strtotime($a->event_start_dt) with strtotime($b->event_start_dt).

您还可以使函数更加简单,因为它遵循常见的误解,即回调的返回值应为-101.实际上,它可以是任何整数,只有其符号重要-返回-42与返回-999具有相同的效果,即将项$a放置在结果数组中的$b之前.

You can also make the function much simpler, because it follows the common misconception that the return value of the callback should be -1, 0, or 1. In fact, it can be any integer, and only its sign matters - returning -42 will have the same effect as returning -999, namely placing item $a before $b in the resulting array.

我不能轻易给出一个经过测试的示例,因为您没有提供底层XML来再现您的输入(例如echo $this->data->asXML();),但是我采用的基本方法是:

I can't easily give a tested example, because you haven't provided the underlying XML to reproduce your input (e.g. echo $this->data->asXML();), but the basic approach I would take would be this:

// Start with an empty array, and add all the items we're interested in to it
$sortable_array = array();
// Loop over all <reservation> children of the SimpleXML object $this->data
// See http://php.net/manual/en/simplexml.examples-basic.php
foreach ( $this->data->reservation as $reservation_node )
{
    // Add the individual node to our array
    $sortable_array[] = $reservation_node;
}

// Now let's sort out the callback function for the sorting
// This could also be an anonymous function passed directly to usort
function sort_callback_event_start($a, $b)
{
    // $a and $b are both items in our $sortable_array, and therefore
    // <reservation> nodes which we expect to each have a child
    // called <event_start_dt>

    // If we convert both dates to Unix timestamps, we have two integers 
    // to compare, and a simple subtraction gives the desired result
    // of <0, 0, or >0 as documented at http://php.net/usort

    return
        strtotime((string)$a->event_start_dt)
        -
        strtotime((string)$b->event_start_dt);
}

// Now, we have everything we need to do the actual sorting
usort($sortable_array, 'sort_callback_event_start');
// $sortable_array is now sorted as desired! :D

// Note that the items within it are still SimpleXML objects, 
// so you still need to access their properties to do something useful
// e.g. some HTML output with the names listed in order of their start date:
echo '<ol>';
foreach ( $sortable_array as $reservation_node )
{
    echo '<li>', (string)$reservation_node->event_name, '</li>';
}
echo '</ol>';

这篇关于排序对象(SimpleXMLElement)php的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆