2013-05-07 5 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); 
} 

... 열두주의 사항 ("Notice: Array to string conversion ...") 던지는 동안은 Update_time에 따라 $workTables의 모든 요소를 ​​주문하여 예상로 작동합니다.

합니다 ('X'열이 원래 코드에서 타임 스탬프 다음에 고정 된 접두어 Name와 아무 상관이 있음을 배제 할 내 시도의 일부 (예 : work_table_1367940392, work_table_1367940395, ...) . 의 설명에 부합하는 ...

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

: 제작 Update_time 의해 정렬로 Name 등가로 정렬)

분명히 I don't want to program by coincidence 때문에,이가는 최소한이 대체 될 array_multisort() 우리가 원하는 것을 수행하며, 우리 얼굴에주의를 던지지 않습니다.

하지만 제가 관심이있는 것은 입니다. 이유는 무엇이든 이전 코드가 작동합니다 (고지에도 불구하고).

부분적인 이유는 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

+0

@Raidenace : 하하, 나도 알아, 그렇지? 그것은 * 모든 것을 설명합니다 *. :) (호감을 얻으려면 희미한 주석을 쓰는 것이 희박합니다.) – pinkgothic

답변

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

+0

"(그러나 통지도 내리지 않습니다!)"그런데, 내 컴퓨터에서는 사실이 아니지만 완성을위한 사이드 노트로도 마찬가지입니다. 나는이 말에, 당신의 찌르기에 너무 감사합니다. :) 나는 당신에게 줄 많은 upvote가 있었으면 좋겠다. – pinkgothic