Подтвердить что ты не робот

Алгоритм сравнения массивов PHP

При попытке имитировать немного поведения PHP я наткнулся на это:

    $a=array(0 => 1, 'test' => 2);
    $b=array('test' => 3, 0 => 1);
    var_dump($a==$b, $a>$b, $b>$a);

В соответствии с выходом var_dump $b больше, чем $a. В руководстве по PHP есть Транскрипция сравнения стандартных массивов, в которой указано, что значения массивов сравниваются по одному и если ключ из первый массив отсутствует во втором массиве, массивы несравнимы. Все идет нормально. Но если я попробую это (изменение только в первом элементе $a):

    $a=array(0 => 2, 'test' => 2);
    $b=array('test' => 3, 0 => 1);
    var_dump($a==$b, $a>$b, $b>$a);

Все три результата сравнения false. Это выглядит как "несравнимое" для меня (поскольку результат > совпадает с результатом <, тогда как массивы не являются ==, что не имеет смысла), но это не соответствует транскрипции из PHP руководство. Оба ключа присутствуют в обоих массивах, и я ожидал бы, что $a будет больше на этот раз, потому что содержимое ключа 0 больше в $a (2 против 1).

Я попытался вникнуть в исходный код PHP и нашел zend_hash_compare() в zend_hash.c, но код там, похоже, работает как описано в руководстве.

Что здесь происходит?

4b9b3361

Ответ 1

Казалось бы, цикл сравнения в случае > выполнен по правому массиву, а в случае < выполняется над левым массивом, т.е. всегда над якобы "меньшим" массивом. Порядок элементов значим, поскольку цикл foreach в коде транскрипции соответствует порядку массива.

Иными словами;

$a > $b петли над b и сначала обнаруживает "тест". 'test' больше в $b, поэтому $b больше и возвращает false.

$b > $a зацикливается на a и сначала находит "0". '0' больше в $a, поэтому $a больше и возвращает false.

Это действительно имеет смысл, тогда "большему" массиву разрешено содержать элементы, которые "меньший" массив не имеет и все еще больше, если все общие элементы больше.

Ответ 2

РЕДАКТИРОВАТЬ: Как показал Йоахим, речь идет о вызванном порядке. Чтобы украсть его слова: "$ a > $b петли над b и сначала обнаруживает" тест "." test "больше в $b, поэтому $b больше и возвращает false. $b > $a перебирает a и сначала находит" 0 ". 0 'больше в $a, поэтому $a больше и возвращает false."

- Оригинальное сообщение -

Я не уверен на 100%, что я прав; Я этого раньше не видел, и только кратко посмотрел на него (по большому счету, на отличный вопрос!). В любом случае, похоже, что либо документация PHP неверна, либо это ошибка (в этом случае вы можете отправить ее), и вот почему:

в zend_hash_compare() в zend_hash.c, кажется, что есть какая-то путаница в отношении того, что ordered (я смотрю на строку 1514 и 1552-1561, что является моим лучшим предположением, где проблема без проведения большого тестирования).

Вот что я имею в виду; попробуйте следующее:

$a=array(0 => 2, 'test' => 2);
$b=array(0 => 1, 'test' => 3);
var_dump($a==$b, $a>$b, $b>$a);

Примечание. Я просто переключил порядок индексов, а $a>$b возвращает true. Также см. Это:

$x=array(0 => 2, 'test' => 2);
$y = $x;
$y[0] = 1; $y['test'] = 3;
var_dump($x==$y, $x>$y, $y>$x);

Обратите внимание, что $x>$y возвращает true. Другими словами, PHP не просто соответствует ключам массива! Он заботится о порядке этих ключей в массивах! Вы можете предотвратить эту ситуацию, придумав "базовый" массив и "скопировав" его на новые переменные (в моем примере x/y) до изменения, или вы можете создать объект, если хотите.

Чтобы сказать все по-другому и, что еще более кратко, казалось бы, PHP не просто смотрит на ключевые значения, а на оба ключевых значения и порядок клавиш.

Опять же, я подчеркиваю, что я не знаю, было ли это ожидаемое поведение (кажется, что-то, что они должны были заметить в руководстве PHP, если это было), или ошибка/ошибка/etc (что кажется мне гораздо более вероятным). Но в любом случае, я нахожу, что его сначала сравнивают по количеству ключей (строки 1496-1501 in zend_hash.c), а затем как по значению ключа, так и по порядку.

Ответ 3

Я думаю, что здесь сравнивается один за другим, поэтому $a[0]>$b[0], но $a['test']<$b['test']. Вы не можете сказать, какой массив больше.