Всегда заключайте в кавычки строковый литерал в индексе ассоциативного массива.
К примеру, пишите $foo['bar'], а не
$foo[bar]. Но почему? Часто в старых скриптах можно встретить
следующий синтаксис:
$foo[bar] = 'враг'; echo $foo[bar]; // и т.д. ?>
Это неверно, хотя и работает. Причина
в том, что этот код содержит неопределенную константу (bar), а не
строку ('bar' - обратите внимание на кавычки), и PHP в будущем
может определить константу, которая, к несчастью для вашего кода,
будет иметь то же самое имя. Это работает, потому что PHP
автоматически преобразует "голую строку" (не
заключенную в кавычки строку, которая не соответствует ни одному
из известных символов языка) в строку, со значением этой "голой строки".
Например, если константа с именем bar не
определена, то PHP заменит bar на строку 'bar' и
использует ее.
Замечание:
Это не означает, что нужно всегда заключать
ключ в кавычки. Нет необходимости заключать в кавычки константы или переменные, поскольку это
помешает PHP обрабатывать их.
Проверяем 0:
Notice: Undefined index: $i in /path/to/script.html on line 9
Плохо:
Хорошо: 1
Notice: Undefined index: $i in /path/to/script.html on line 11
Плохо:
Хорошо: 1
Проверяем 1:
Notice: Undefined index: $i in /path/to/script.html on line 9
Плохо:
Хорошо: 2
Notice: Undefined index: $i in /path/to/script.html on line 11
Плохо:
Хорошо: 2
Дополнительные примеры, демонстрирующие этот факт:
// Верно print $arr['fruit']; // apple print $arr['veggie']; // carrot
// Неверно. Это работает, но из-за неопределенной константы с // именем fruit также вызывает ошибку PHP уровня E_NOTICE // // Notice: Use of undefined constant fruit - assumed 'fruit' in... print $arr[fruit]; // apple
// Давайте определим константу, чтобы продемонстрировать, что // происходит. Мы присвоим константе с именем fruit значение 'veggie'. define('fruit', 'veggie');
// Теперь обратите внимание на разницу print $arr['fruit']; // apple print $arr[fruit]; // carrot
// Внутри строки это нормально. Внутри строк константы не // рассматриваются, так что ошибки E_NOTICE здесь не произойдет print "Hello $arr[fruit]"; // Hello apple
// С одним исключением: фигурные скобки вокруг массивов внутри // строк позволяют константам там находиться print "Hello {$arr[fruit]}"; // Hello carrot print "Hello {$arr['fruit']}"; // Hello apple
// Это не будет работать и вызовет ошибку обработки, такую как: // Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING' // Это, конечно, также действует и с суперглобальными переменными в строках print "Hello $arr['fruit']"; print "Hello $_GET['foo']";
// Еще одна возможность - конкатенация print "Hello " . $arr['fruit']; // Hello apple ?>
Если вы переведете error_reporting
в режим отображения ошибок уровня
E_NOTICE (например, такой как
E_ALL), вы сразу увидите эти ошибки. По
умолчанию
error_reporting установлена их не отображать.
Как указано в разделе синтаксис,
внутри квадратных скобок ('['
и ']') должно быть выражение. Это означает, что можно писать вот так:
echo $arr[somefunc($bar)]; ?>
Это пример использования возвращаемого функцией значения
в качестве индекса массива. PHP известны также и константы:
$error_descriptions[E_ERROR] = "Произошла фатальная ошибка"; $error_descriptions[E_WARNING] = "PHP сообщает о предупреждении"; $error_descriptions[E_NOTICE] = "Это лишь неофициальное замечание"; ?>
Обратите внимание, что E_ERROR - это такой же
верный идентификатор, как и bar в первом примере.
Но последний пример по сути эквивалентен такой записи:
$error_descriptions[1] = "Произошла фатальная ошибка"; $error_descriptions[2] = "PHP сообщает о предупреждении"; $error_descriptions[8] = "Это лишь неофициальное замечание"; ?>
поскольку E_ERROR соответствует 1, и т.д.
Так что же в этом плохого?
Когда-нибудь в будущем, команда разработчиков PHP, возможно, пожелает
добавить еще одну константу или ключевое слово, либо константа из
другого кода может вмешаться и тогда у вас могут
возникнуть проблемы. Например, вы уже не можете использовать таким
образом слова empty и
default, поскольку они являются
зарезервированными ключевыми словами.
Замечание:
Повторим, внутри строки (string), заключенной
в двойные кавычки, корректно не окружать индексы
массива кавычками, поэтому "$foo[bar]"
является верной записью. Более подробно почему - смотрите
вышеприведенные примеры, а также раздел
обработка
переменных в строках.
Преобразование в массив
Для любого из типов: integer, float,
string, boolean и resource,
преобразование значения в массив дает результатом массив с
одним элементом (с индексом 0), являющимся скалярным значением, с
которого вы начали. Другими словами, (array)$scalarValue
- это точно то же самое, что и array($scalarValue).
Если вы преобразуете в массив объект (object), вы
получите в качестве элементов массива свойства (переменные-члены)
этого объекта. Ключами будут имена переменных-членов, с некоторыми примечательными
исключениями: целочисленные свойства станут недоступны;
к закрытым полям класса (private) спереди будет дописано имя класса;
к защищенным полям класса (protected) спереди будет добавлен символ '*'.
Эти добавленные значения с обоих сторон также имеют нулевые байты.
Это может вызвать несколько неожиданное поведение:
class A { private $A; // Это станет '\0A\0A' }
class B extends A { private $A; // Это станет '\0B\0A' public $AA; // Это станет 'AA' }
var_dump((array) new B()); ?>
Вышеприведенный код покажет 2 ключа с именем 'AA', хотя один из них на самом деле
имеет имя '\0A\0A'.
Если вы преобразуете в массив значение NULL, вы получите
пустой массив.
Изменение значений массива напрямую стало возможным с версии PHP 5 путем
передачи их по ссылке. До этого необходим следующий обходной прием:
Пример #3 Изменение элемента в цикле
// PHP 5 foreach ($colors as &$color) { $color = strtoupper($color); } unset($color); /* это нужно для того, чтобы последующие записи в $color не меняли последний элемент массива */
// Обходной прием для старых версий foreach ($colors as $key => $color) { $colors[$key] = strtoupper($color); }
print_r($colors); ?>
Результат выполнения данного примера:
Array
(
[0] => RED
[1] => BLUE
[2] => GREEN
[3] => YELLOW
)
Следующий пример создает массив, начинающийся с единицы.
// заполняем массив всеми элементами из директории $handle = opendir('.'); while (false !== ($file = readdir($handle))) { $files[] = $file; } closedir($handle); ?>
Массивы упорядочены. Вы можете изменять порядок элементов,
используя различные функции сортировки. Для дополнительной
информации смотрите раздел функции
для работы с массивами. Вы можете подсчитать количество
элементов в массиве с помощью функции count().
Пример #6 Сортировка массива
sort($files); print_r($files); ?>
Поскольку значение массива может быть чем угодно, им также
может быть другой массив. Таким образом вы можете создавать
рекурсивные и многомерные массивы.
// Несколько примеров доступа к значениям предыдущего массива echo $fruits["дырки"][5]; // напечатает "вторая" echo $fruits["фрукты"]["a"]; // напечатает "апельсин" unset($fruits["дырки"][0]); // удалит "первая"
// Создаст новый многомерный массив $juices["apple"]["green"] = "good"; ?>
Обратите внимание, что при присваивании массива всегда
происходит копирование значения. Чтобы скопировать массив по
ссылке, вам нужно использовать оператор ссылки.
$arr1 = array(2, 3); $arr2 = $arr1; $arr2[] = 4; // $arr2 изменился, // $arr1 все еще array(2, 3)
$arr3 = &$arr1; $arr3[] = 4; // теперь $arr1 и $arr3 одинаковы ?>