[英]Sort object(SimpleXMLElement) php
我正在尝试找到一种方法,可以对来自SimpleXMLElement的数组进行排序。 我想按可以从event_start_dt获得的开始时间进行排序。 我还想按房间ID进行排序,这是一个单独的过程。 当前,该数组按object(SimpleXMLElement)#的顺序排列。 这是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,但是还没有使其与任何一种方法一起使用。
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为数组,给定对象。
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。
$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"
}
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);
核实。 这是我的代码
<?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);
?>
输出为:
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] =>
)
)
在对数据进行排序之前,需要创建一个数组,其中包含要排序的单独项目作为其值。 从调试输出中,这些是输入XML中的多个<reservation>
节点,它们是这些示例中以$array
/ $this->data
表示的元素的子元素(无论它是文档的根目录还是否,SimpleXML没有Document对象)。
您的print_r
和var_dump
输出显示您当前没有这样的数组,只有一个SimpleXML对象:
var_dump($array)
给出输出开始的object(SimpleXMLElement)#275 (1) {
-进一步忽略单词array
,这就是var_dump
渲染对象内部的方式。 print_r($array);
开头的array(1) {
-但这只是因为您已经将实际数据包装在上面一行( $array = array($this->data);
)和一个元素( $array[0]
)显示为object(SimpleXMLElement)#280 (1) { ...
请注意,没有必要进一步将所有内部SimpleXML对象转换为数组-您只需要一个可排序的列表,其中包含您感兴趣的项目。我个人将使用一个简单而明确的foreach
循环,以实现最大的代码可读性,尽管有“更聪明”的解决方案。
一旦有了可排序的列表,就需要一个用于usort
的回调函数,该函数将比较其两个参数。 您进行的尝试是正确的,但指向不存在的变量(在该函数中) $array
; 需要比较的值是函数的参数,分别称为$a
和$b
具体来说,您想将strtotime($a->event_start_dt)
与strtotime($b->event_start_dt)
。
您也可以使功能更简单,因为它遵循普遍的误解,认为回调的返回值应该是-1
, 0
或1
。 实际上,它可以是任何整数,只有其符号重要-返回-42
与返回-999
具有相同的效果,即在结果数组中将项目$a
放在$b
之前。
我不能轻易给出一个经过测试的示例,因为您没有提供底层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>';
我只是使用此函数将其转换为数组(来自php.net的示例函数)。 但是请注意,这不会对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;
}
并将其传递给XMLObject
$arrTimes = xml2array(YourSimpleXMLElement);
然后在新数组上使用原始的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;
}
最后
usort($arrTimes, 'sortByTime');
您必须使用json编码解码器将frist转换为xml到数组
$ xml_array = json_decode(json_encode((array)$ xml),TRUE);
你会得到数组列表。。。。然后你可以使用strtotime函数根据日期进行排序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.