简体   繁体   English

排序对象(SimpleXMLElement)php

[英]Sort object(SimpleXMLElement) php

I'm trying to find a way to sort my array from SimpleXMLElement. 我正在尝试找到一种方法,可以对来自SimpleXMLElement的数组进行排序。 I'd like to sort by start time which I can get from event_start_dt. 我想按可以从event_start_dt获得的开始时间进行排序。 I'd also like to sort by room ID as a separate process. 我还想按房间ID进行排序,这是一个单独的过程。 Currently the array is in order by object(SimpleXMLElement) #. 当前,该数组按object(SimpleXMLElement)#的顺序排列。 Here is the var_dump($array): 这是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"
    }
} }

I've tried usort and asort but haven't gotten it to work with either method. 我已经尝试过usort和asort,但是还没有使其与任何一种方法一起使用。

usort 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);

Trying the code below gives me warning: usort() expects parameter 1 to be array, object given. 尝试下面的代码会给我警告:usort()期望参数1为数组,给定对象。

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);

}

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. 我有一个来自控制器的数组,但无法使usort正常工作:我得到了:usort()期望参数1为数组,给定的对象或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"
        }
    } }

Request for print_r: 要求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" 
}

Use array_multisort 使用array_multisort

            foreach ($rez->reservation as $value)
            { 
                     $dateTime[] = $value->event_start_dt;
            }

           array_multisort($dateTime,SORT_ASC,SORT_STRING,$rez->reservation);   
           echo "<pre>";
           print_r($rez->reservation);

Check it. 核实。 this is my code 这是我的代码

<?php
        $myarray=array(
                    0 => array
                        (
                            'dateTime' => '2013-12-02T10:00:00-08:00',
                            'chanl1' => '20.10',
                            'chanl2' => '45.4',
                            'chanl3' => '',
                        ),

                    1 => array
                        (
                            'dateTime' => '2013-12-02T11:00:00-08:00',
                            'chanl1' => '20.11',
                            'chanl2' => '45.4',
                            'chanl3' => '',
                        ),
                  2 => array
                        (
                            'dateTime' => '2013-12-02T12:00:00-08:00',
                            'chanl1' => '20.12',
                            'chanl2' => '33.8',
                            'chanl3' => '',
                        ),

                    3 => array
                        (
                            'dateTime' => '2013-12-02T09:00:00-08:00',
                            'chanl1' => '20.9',
                            'chanl2' => '33.9',
                            'chanl3' => ''
                        ));

            foreach($myarray as $c=>$key) {
                    $dateTime[] = $key['dateTime'];                      
            }           


        array_multisort($dateTime,SORT_ASC,SORT_STRING,$myarray);   
        echo "<pre>";
        print_r($myarray);
        ?>

Output is : 输出为:

Array
(
    [0] => Array
        (
            [dateTime] => 2013-12-02T09:00:00-08:00
            [chanl1] => 20.9
            [chanl2] => 33.9
            [chanl3] => 
        )

    [1] => Array
        (
            [dateTime] => 2013-12-02T10:00:00-08:00
            [chanl1] => 20.10
            [chanl2] => 45.4
            [chanl3] => 
        )

    [2] => Array
        (
            [dateTime] => 2013-12-02T11:00:00-08:00
            [chanl1] => 20.11
            [chanl2] => 45.4
            [chanl3] => 
        )

    [3] => Array
        (
            [dateTime] => 2013-12-02T12:00:00-08:00
            [chanl1] => 20.12
            [chanl2] => 33.8
            [chanl3] => 
        )

)

FIDDLE 小提琴

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). 从调试输出中,这些是输入XML中的多个<reservation>节点,它们是这些示例中以$array / $this->data表示的元素的子元素(无论它是文档的根目录还是否,SimpleXML没有Document对象)。

Your print_r and var_dump output shows that you do not currently have such an array, only a SimpleXML object: 您的print_rvar_dump输出显示您当前没有这样的数组,只有一个SimpleXML对象:

  • 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. 您的第一个示例显示var_dump($array)给出输出开始的object(SimpleXMLElement)#275 (1) { -进一步忽略单词array ,这就是var_dump渲染对象内部的方式。
  • Later, you have a print_r($array); 后来,您有了一个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) { ... . 开头的array(1) { -但这只是因为您已经将实际数据包装在上面一行( $array = array($this->data); )和一个元素( $array[0] )显示为object(SimpleXMLElement)#280 (1) { ...

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

Once you have a sortable list, you need a callback function for usort which compares its two parameters. 一旦有了可排序的列表,就需要一个用于usort的回调函数,该函数将比较其两个参数。 The attempt you've made is along the right lines, but refers to the non-existent (in that function) variable $array ; 您进行的尝试是正确的,但指向不存在的变量(在该函数中) $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) . 需要比较的值是函数的参数,分别称为$a$b具体来说,您想将strtotime($a->event_start_dt)strtotime($b->event_start_dt)

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 . 您也可以使功能更简单,因为它遵循普遍的误解,认为回调的返回值应该是-101 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. 实际上,它可以是任何整数,只有其符号重要-返回-42与返回-999具有相同的效果,即在结果数组中将项目$a放在$b之前。

I can't easily give a tested example, because you haven't provided the underlying XML to reproduce your input (eg echo $this->data->asXML(); ), but the basic approach I would take would be this: 我不能轻易给出一个经过测试的示例,因为您没有提供底层XML来再现您的输入(例如echo $this->data->asXML(); ),但是我要采用的基本方法是:

// 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>';

I would just cast it as an array using this function (example function from php.net). 我只是使用此函数将其转换为数组(来自php.net的示例函数)。 But note that this will not sort the XML, rather sort the new array 但是请注意,这不会对XML进行排序,而是对新数组进行排序

/**
* function xml2array
*
* This function is part of the PHP manual.
*
* The PHP manual text and comments are covered by the Creative Commons 
* Attribution 3.0 License, copyright (c) the PHP Documentation Group
*
* @author  k dot antczak at livedata dot pl
* @date    2011-04-22 06:08 UTC
* @link    http://www.php.net/manual/en/ref.simplexml.php#103617
* @license http://www.php.net/license/index.php#doc-lic
* @license http://creativecommons.org/licenses/by/3.0/
* @license CC-BY-3.0 <http://spdx.org/licenses/CC-BY-3.0>
*/
function xml2array ( $xmlObject, $out = array () )
{
  foreach ( (array) $xmlObject as $index => $node )
    $out[$index] = ( is_object ( $node ) ) ? xml2array ( $node ) : $node;

   return $out;
 }

and pass it the XMLObject 并将其传递给XMLObject

$arrTimes = xml2array(YourSimpleXMLElement);

and then use your original usort function on the new array 然后在新数组上使用原始的usort函数

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

Finally 最后

usort($arrTimes, 'sortByTime');

You have to convert frist in to xml to array using json encode decode 您必须使用json编码解码器将frist转换为xml到数组

$xml_array = json_decode(json_encode((array)$xml), TRUE); $ xml_array = json_decode(json_encode((array)$ xml),TRUE);

u will get list of array....than u can sory according to date using strtotime function. 你会得到数组列表。。。。然后你可以使用strtotime函数根据日期进行排序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM