错误地使用array_multisort()给出正确的结果?

时间:2013-05-07 15:45:15

标签: php array-multisort

我正在触摸一些遗留代码,试图清理它并遇到了一些难题。 我解决它并不是远程任务关键,所以最多考虑这个问题,但它仍然让我感到困惑。让我很好奇。

此代码:

// 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 ...”)时,按照$workTablesUpdate_time排序Name中的所有元素,按预期工作 。 / p>

('x'列是我尝试排除它与work_table_1367940392有关的一部分,work_table_1367940395在原始代码中是固定前缀后跟时间戳(例如NameUpdate_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似乎是进一步启蒙的最佳机会。

所以,如果你对幕后发生的事情有所了解(我怀疑这是一件微不足道的事情,我已经忽略了;经过一段时间的圈子后,这往往是我的问题),我很乐意听到它! :)

1 个答案:

答案 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(),但如果是,我认为这是解释。