我正在触摸一些遗留代码,试图清理它并遇到了一些难题。 我解决它并不是远程任务关键,所以最多考虑这个问题,但它仍然让我感到困惑。让我很好奇。
此代码:
// dummy data for the sake of testing / abstract visualisation;
// x is thrown in as an experiment:
$workTables = array(
array('x' => 5, 'Name' => 'foo3', 'Update_time' => '2013-04-04 04:40',),
array('x' => 4, 'Name' => 'foo4', 'Update_time' => '2013-04-01 04:40',),
array('x' => 3, 'Name' => 'foo2', 'Update_time' => '2013-04-04 09:40',),
array('x' => 2, 'Name' => 'foo1', 'Update_time' => '2013-04-12 04:40',),
array('x' => 1, 'Name' => 'foo5', 'Update_time' => '2012-12-04 04:40',),
);
// original legacy code:
if (!empty($workTables)) {
$sort = array();
foreach ($workTables as $key => $value) {
$sort[$key]["Update_time"] = $value["Update_time"];
}
array_multisort($workTables, SORT_ASC, SORT_STRING, $sort);
}
...在投掷十二个通知(“Notice: Array to string conversion ...
”)时,按照$workTables
按Update_time
排序Name
中的所有元素,按预期工作 。 / p>
('x'列是我尝试排除它与work_table_1367940392
有关的一部分,work_table_1367940395
在原始代码中是固定前缀后跟时间戳(例如Name
,Update_time
,...),按// new code:
if (!empty($workTables)) {
$sort = array();
foreach ($workTables as $key => $value) {
$sort[$key] = $value["Update_time"];
}
array_multisort($sort, SORT_ASC, SORT_STRING, $workTables);
}
进行排序,相当于按PHP 5.4.7 (cli)
排序。)
显然,自I don't want to program by coincidence起,至少会被替换为:
$workTables
...符合 array_multisort()
的描述,也执行我们想要的操作,并且不会在我们面前抛出通知。
但我真正感兴趣的是为什么旧代码有效(尽管有通知)。
部分原因似乎是 asort()
和co。的行为,它们具有(部分)未记录的功能,可以通过根据数组的内容,通过“从左到右”的结构(至少在$sort
中)......但是......我试图理解正在制作的/* Do the actual sort magic - bada-bim, bada-boom. */
zend_qsort(indirect, array_size, sizeof(Bucket **), php_multisort_compare TSRMLS_CC);
和{{1 }}' interchangable '。
我试图查看PHP的C源代码来解决这个问题,但我仍然试图理解这里发生的事情:
zend_qsort()
...因为我对C的了解非常严重,{{1}}本身就完全脱离了我的联盟。
任何参赛者?
请记住,我并不急于寻求答案,所以不要沉溺太多时间,但也许其他人也喜欢拼图? :)
就个人而言,我已经投入了一些时间,因为我更喜欢彻底理解代码,特别是当我试图清理代码时 - 即使它的代码只是巧合。当谈到进一步的理解时,我刚刚达到了一个死胡同,所以stackoverflow似乎是进一步启蒙的最佳机会。
所以,如果你对幕后发生的事情有所了解(我怀疑这是一件微不足道的事情,我已经忽略了;经过一段时间的圈子后,这往往是我的问题),我很乐意听到它! :)
答案 0 :(得分:1)
根据我的理解,正在创建一个数组并将其存储在$sort[$key]
中。然后,一旦调用array_multisort()
,它就会将数组转换回字符串,并使用该字符串作为定义顺序的值进行排序 - 就像警告所说的那样。然后,此字符串用作订单定义值。
这个转换数组 - >字符串是如何执行的?只是做echo $anArrayValueHere;
没有帮助;它打印出Array
。类似的技巧,echo "" . $anArrayValueHere . "";
也没有产生任何有用的东西。 (但它也没有发出通知!)
很有可能使用serialize()
。假设,让我们看看什么将被用作订单定义值:
#!/usr/bin/php5
<?php
$sort[0]["Update_time"] = '2012-12-04 04:40';
echo serialize($sort[0]);
然后
$ ./php tmp.php
a:1:{s:11:"Update_time";s:16:"2012-12-04 04:40";}
看起来密钥足够明确,可以产生可用于定义排序顺序的东西,就像Update_time
值一样。
我不确定是否使用serialize()
,但如果是,我认为这是解释。