2012-05-06 3 views
4

Я смутно вспоминаю из первых чтений PHP-документов (более 10 лет назад), что синтаксис типа массива для доступа к символам в массивах ($string[0]) создает некоторую неопределенность или неопределенное поведение.string - неоднозначность массива в PHP

O'Reilly PHP Карманный справочник (2-й изд) гласит:

Чтобы решить проблему неоднозначности между строками и массивами, нового синтаксис был введен разыменовать отдельные символы из строк:

$string{2}

Этот синтаксис эквивалентен $string[2] и является предпочтительным.

Я понимаю, что $string[2] может быть запутанным, но я не уверен, как он может быть неоднозначным?

Кроме того: Интересно, как the new syntax$string{2} устраняет неоднозначность/путаницы, принимая во внимание, что фигурные скобки (apparently) также работают на «реальных» массивов.

+0

Я не уверен, правильно ли я это понимаю, но я не вижу здесь проблемы, так как $ string {2} (или $ string [2]) используется либо с точки зрения того, что это строка, выберите 2-го символа или с точки зрения массива, отыщите второй элемент, который в основном является тем же самым для интерпретатора, поскольку строка является просто массивом для интерпретатора. – Garuda

+0

Последняя версия php получает странный '$ str = 'hi'; echo $ str [0] [0] [0] [0] [0] [0] [0]; // выводит h', просто рекурсивно делает substr для первого char – goat

ответ

6

Единственная двусмысленность в том, что если вы ожидаете массив, но на самом деле имеете строку, то $var[0] предоставит вам первый байт строки вместо первого элемента массива. Это может привести к большому сбою в голове и удивлению, почему PHP дает вам только первый символ, а не весь массив. Это даже более верно для нечисловых индексов, таких как $var['foo'], что фактически работает, если $var - это строка (да, пожалуйста, не спрашивайте). То есть это может сделать отладку несколько сложнее, если ваша программа в первую очередь ошибочна.

Не существует двусмысленности для правильных программ, поскольку переменная не может быть строкой и массивом одновременно.

+1

+1 и rant: Это типичный PHP «решение», которое ... ничего не решает. С '[]' по ошибке на строке вы получаете неожиданный результат, а с '{}' по ошибке на массиве вы также получаете неожиданный результат, так как вы всегда ожидали только одного символа.Конечно, это неверно, потому что, поскольку OP говорит, что '{}' работает нормально "на массивах тоже, так что теперь' {} 'имеет ту же проблему, что' [] 'это привело к' {} ', введенному. Возможно, будущей попытке удастся добиться этого, прежде чем мы закончим пунктуальность. Тьфу. – Jon

+0

'$ var ['foo']' работает, потому что PHP знает, что это не массив, 'foo' не является допустимым ключом для этого не-массива, поэтому его принудительно вставляется в 0 и становится '$ var [0]' –

+0

@ Марк Да, есть объяснение, но это не делает его лучше. :) Поведение в 5.4, по крайней мере, вызвав уведомление, дает гораздо больше смысла. – deceze

1

Ну, я проверил некоторые переменные с этим кодом:

<pre><?php 

dumpling(array("php")); 
dumpling(array()); 
dumpling(0); 
dumpling(1); 
dumpling(TRUE); 
dumpling(FALSE); 
dumpling(NULL); 
dumpling("php"); 

function dumpling($var){ 
    var_dump($var[0]); 
    var_dump($var{0}); 
} 

?> 

и там, казалось, не будет какая-то разница между этими двумя.

Выход был:

string(3) "php" 
string(3) "php" 
NULL 
NULL 
NULL 
NULL 
NULL 
NULL 
NULL 
NULL 
NULL 
NULL 
NULL 
NULL 
string(1) "p" 
string(1) "p" 
+0

Вывод 'array (TRUE)' был 'bool (TRUE); bool (TRUE);' BTW, если кто-то задается вопросом :) –

2

Многие проблемы, связанные с неоднозначностью между строк смещений и смещений массива, были удалены с изменениями в 5.4, которые после даты опубликования вашей ссылки. http://php.net/manual/en/migration54.incompatible.php

По этой причине я рекомендую [] для смещений строк в новом коде.

Смежные вопросы