строки в PHP действительно массив символов или что-то еще? - PullRequest
2 голосов
/ 10 сентября 2011

Рассмотрим

$foo = "abcdefg";

echo $foo[0]; //outputs a

Так что кажется, что строки похожи на массив символов, но почему

foreach($foo as $char)
{
echo $char;
}

не работает и выдает следующее предупреждение ??

Warning: Invalid argument supplied for foreach() 

Ответы [ 4 ]

1 голос
/ 10 сентября 2011

В ответе NikiC объясняется, почему сделать это напрямую невозможно.

Если вы хотите выполнить итерацию по строке, как если бы это был массив, вы можете явно указать, используя str_split:

foreach(str_split($foo) as $char) 
{ 
    echo $char; 
} 

Предупреждение: str_split не поддерживает кодировку, поэтому вы закончите итерацией по байтам и не по символам . Итерации по символам немного сложнее, так как не существует эквивалентной многобайтовой функции разделения. Вы можете свернуть свои собственные, используя регулярное выражение mb_split, посмотрите на комментарии из PHP.net для идей.

Есть и другие ответы, предлагающие вам привести строку к массиву, но я не понимаю, почему это сработает. Документация довольно явная:

Для любого из типов: целое число, число с плавающей запятой, строка, логическое значение и ресурс, преобразование значения в массив приводит к массиву с одним элемент с нулевым индексом и значением скаляра, который был преобразованный. Другими словами, (массив) $ scalarValue точно такой же, как массив ($ scalarValue).

И действительно, это не работает, как предлагалось .

1 голос
/ 10 сентября 2011

Добавление поддержки итерации строки к foreach обсуждалось , но отклонено .В основном это было две причины:

  • Это затрудняет отладку приложений.Обычно вы не хотите перебирать символы строки.Это нужно вам очень редко.Поэтому, если вы выполняете итерацию по строке, вы, вероятно, просто допустили ошибку в программировании - и PHP скажет вам об этом.Если вводить итерацию строки, такую ​​ошибку будет трудно отследить.
  • Что такое «символ»?Должен ли PHP перебирать каждый байт?Должен ли он перебирать символы (которые могут быть несколькими байтами)?Если это так, что он должен делать, если он сталкивается с искаженной многобайтовой последовательностью?И откуда он берет кодировку?

Для решения обеих проблем было предложено ввести TextIterator, в который вы передаете строку и кодировку.Таким образом, вы не можете случайно выполнить итерацию строки, и проблема байтов против символов не существует.Я не уверен, что сейчас состояние TextIterator.

0 голосов
/ 10 сентября 2011

это называется "синтаксический сахар".

Например, в 5.4 вы сможете сделать так echo func()[0];
Что не означает , чтоФункция действительно массив символов.
Это просто синтаксис.

0 голосов
/ 10 сентября 2011

Даже если их символы можно адресовать в квадратных скобках, строки не являются массивами . Акцент мой:

Символы в строках могут быть доступны и изменены путем указания смещения нуля нужного символа после строки с использованием квадратных скобок массива, как в $ str [42]. Для этого нужно представить строку как массив символов .

...