2013-05-07 46 views
0

我目前正在觸摸一些遺留代碼,試圖清理它並遇到了一些難題。 我解決這個問題甚至不是關鍵任務,所以最多隻考慮一個運動問題,但它仍然令我困惑。讓我好奇。錯誤地使用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); 
} 

...當投擲12個通知( 「Notice: Array to string conversion ...」),作品預期,通過根據Update_time訂貨在$workTables所有元素。

(的「x」列是我的企圖排除它有什麼關係Name,這在原代碼是一個固定的前綴,後跟一個時間戳的一部分(例如work_table_1367940392work_table_1367940395,...) ,使得通過Name相當於排序,以通過排序Update_time

很明顯,因爲I don't want to program by coincidence,這是怎麼回事最起碼要替換爲:

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

...這符合的說明array_multisort(),做我們想要的,並不會在我們的臉上扔Notices。

但我真正感興趣的是爲什麼舊代碼的作品(儘管有通知)。

的部分原因似乎是asort()和共同行爲。,其具有(部分地)未公開的特性,他們可以通過根據數組的內容作用與多維數組工作,通過工作從「從左到右」的結構(至少在PHP 5.4.7 (cli))...但是...我被困在試圖理解什麼是$workTables$sort'可互換'。

我想看看PHP的C源代碼來弄明白,但我被困在試圖瞭解發生在這裏:

/* Do the actual sort magic - bada-bim, bada-boom. */ 
zend_qsort(indirect, array_size, sizeof(Bucket **), php_multisort_compare TSRMLS_CC); 

...因爲我的C的知識已經生鏽可怕的是,zend_qsort()本身就是剛剛脫離我的聯盟。

任何接受者?

請記住,我不是絕望的答案,所以不要沉溺於此太多時間,但也許別人也喜歡一個謎題? :)

就我個人而言,我已經投入了一些時間,因爲我更喜歡徹底理解代碼,尤其是當我試圖清理它時 - 即使它只是巧合運行的代碼。當談到進一步理解時,我剛剛達到了死衚衕,所以stackoverflow似乎是進一步啓發的最佳機會。因此,如果你對幕後發生的事情有一個想法(我懷疑這是微不足道的事情,但我忽略了這一點;在我回過頭一段時間後,這往往是我的問題),我很樂意聽到!:)

+0

bada-bim,bada-boom的評論真的給了它。 – raidenace 2013-05-07 16:20:21

+0

@Raidenace:哈哈,我知道,對嗎?它解釋了*一切*。 :)(公平地說,我認爲這是偉大的 - 幽默的評論是一種罕見的(如果含糊不清)高興看到。) – pinkgothic 2013-05-08 07:15:10

回答

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(),但如果是,我認爲這是解釋。

+0

嗯,我沒有看到任何'serialize()'的證據(這將是奇怪的'serialize()'拋出轉換警告),但是......這也可能是由於我在C代碼中完全迷失方向。 :)我相當確定排序本身是由於sort()和co的多維數組處理('sort()'也使用'zend_qsort()'),對我而言,這個奇怪的問題仍然是陣列。 – pinkgothic 2013-05-08 07:22:58

+0

「(但是它們都沒有發出通知!)」順便說一下,在我的機器上並不是這樣,但這只是完成的一個旁註。不過,我得說,非常感謝你的刺傷! :)我希望我有不止一個upvote給你。 – pinkgothic 2013-05-08 07:25:01