mirror of
https://github.com/php/doc-ru.git
synced 2026-04-29 02:03:25 +02:00
1135 lines
40 KiB
XML
1135 lines
40 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<!-- EN-Revision: 6de2e5772f11997fb9a8c0fa2406fbb2c73b3579 Maintainer: shein Status: ready -->
|
||
<!-- Reviewed: no -->
|
||
<!-- $Revision$ -->
|
||
<sect1 xml:id="language.types.array">
|
||
<title>Массивы</title>
|
||
|
||
<para>
|
||
На самом деле массив в PHP - это упорядоченное отображение, которое устанавливает
|
||
соответствие между <emphasis>значением</emphasis> и <emphasis>ключом</emphasis>.
|
||
Этот тип оптимизирован в нескольких направлениях, поэтому вы можете использовать его как
|
||
собственно массив, список (вектор), хеш-таблицу (являющуюся реализацией карты), словарь,
|
||
коллекцию, стэк, очередь и, возможно, что-то еще. Так как значением массива может быть
|
||
другой массив PHP, можно также создавать деревья и многомерные массивы.
|
||
</para>
|
||
|
||
<para>
|
||
Объяснение этих структур данных выходит за рамки данного
|
||
справочного руководства, но вы найдете как минимум один пример по
|
||
каждой из них. За дополнительной информацией вы можете обратиться к
|
||
соответствующей литературе по этой обширной теме.
|
||
</para>
|
||
|
||
<sect2 xml:id="language.types.array.syntax">
|
||
<title>Синтаксис</title>
|
||
|
||
<sect3 xml:id="language.types.array.syntax.array-func">
|
||
<title>Определение при помощи <function>array</function></title>
|
||
|
||
<para>
|
||
Массив (тип <type>array</type>) может быть создан языковой конструкцией <function>array</function>.
|
||
В качестве параметров она принимает любое количество разделенных запятыми пар
|
||
<literal><replaceable>key</replaceable> => <replaceable>value</replaceable></literal>
|
||
(ключ => значение).
|
||
</para>
|
||
|
||
<synopsis>
|
||
array(
|
||
<optional><replaceable>key</replaceable> => </optional><replaceable>value</replaceable>,
|
||
<optional><replaceable>key2</replaceable> => </optional><replaceable>value2</replaceable>,
|
||
<optional><replaceable>key3</replaceable> => </optional><replaceable>value3</replaceable>,
|
||
...
|
||
)</synopsis>
|
||
<!-- Do not fix the whitespace for the synopsis end element. A limitation of PhD prevents proper trimming -->
|
||
|
||
<para>
|
||
Запятая после последнего элемента массива необязательна и может быть опущена.
|
||
Обычно это делается для однострочных массивов, то есть <literal>array(1, 2)</literal>
|
||
предпочтительней <literal>array(1, 2, )</literal>. Для многострочных массивов с другой
|
||
стороны обычно используется завершающая запятая, так как позволяет легче добавлять
|
||
новые элементы в конец массива.
|
||
</para>
|
||
|
||
<note>
|
||
<para>
|
||
Существует короткий синтаксис массива, который заменяет
|
||
<literal>array()</literal> на <literal>[]</literal>.
|
||
</para>
|
||
</note>
|
||
|
||
<example>
|
||
<title>Простой массив</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$array = array(
|
||
"foo" => "bar",
|
||
"bar" => "foo",
|
||
);
|
||
|
||
// Использование синтаксиса короткого массива
|
||
$array = [
|
||
"foo" => "bar",
|
||
"bar" => "foo",
|
||
];
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<para>
|
||
<replaceable>key</replaceable> может быть либо типа <type>int</type>, либо типа
|
||
<type>string</type>. <replaceable>value</replaceable> может быть любого типа.
|
||
</para>
|
||
|
||
<para xml:id="language.types.array.key-casts">
|
||
Дополнительно с ключом <replaceable>key</replaceable> будут сделаны следующие преобразования:
|
||
<itemizedlist>
|
||
<listitem>
|
||
<simpara>
|
||
Строки (<type>string</type>), содержащие целое число (<type>int</type>) (исключая случаи, когда число предваряется знаком <literal>+</literal>) будут преобразованы к типу <type>int</type>.
|
||
Например, ключ со значением <literal>"8"</literal> будет в действительности сохранен со
|
||
значением <literal>8</literal>. С другой стороны, значение <literal>"08"</literal> не
|
||
будет преобразовано, так как оно не является корректным десятичным целым.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
Числа с плавающей точкой (<type>float</type>) также будут преобразованы к типу
|
||
<type>int</type>, то есть дробная часть будет отброшена. Например, ключ со значением
|
||
<literal>8.7</literal> будет в действительности сохранен со значением <literal>8</literal>.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
Тип <type>bool</type> также преобразовываются к типу <type>int</type>.
|
||
Например, ключ со значением <literal>true</literal> будет сохранен со значением
|
||
<literal>1</literal> и ключ со значением <literal>false</literal> будет сохранен со
|
||
значением <literal>0</literal>.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
Тип <type>null</type> будет преобразован к пустой строке. Например, ключ со
|
||
значением <literal>null</literal> будет в действительности сохранен со значением
|
||
<literal>""</literal>.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
Массивы (<type>array</type>) и объекты (<type>object</type>) <emphasis>не
|
||
могут</emphasis> использоваться в качестве ключей. При подобном использовании будет
|
||
генерироваться предупреждение: <literal>Недопустимый тип смещения (Illegal offset type)</literal>.
|
||
</simpara>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
<para>
|
||
Если несколько элементов в объявлении массива используют одинаковый ключ, то только
|
||
последний будет использоваться, а все другие будут перезаписаны.
|
||
</para>
|
||
|
||
<example>
|
||
<title>Пример преобразования типов и перезаписи элементов</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$array = array(
|
||
1 => "a",
|
||
"1" => "b",
|
||
1.5 => "c",
|
||
true => "d",
|
||
);
|
||
var_dump($array);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
array(1) {
|
||
[1]=>
|
||
string(1) "d"
|
||
}
|
||
]]>
|
||
</screen>
|
||
<para>
|
||
Так как все ключи в вышеприведенном примере преобразуются к <literal>1</literal>,
|
||
значение будет перезаписано на каждый новый элемент и останется только последнее
|
||
присвоенное значение <literal>"d"</literal>.
|
||
</para>
|
||
</example>
|
||
|
||
<para>
|
||
Массивы в PHP могут содержать ключи типов <type>int</type> и <type>string</type>
|
||
одновременно, так как PHP не делает различия между индексированными и ассоциативными
|
||
массивами.
|
||
</para>
|
||
|
||
<example>
|
||
<title>Смешанные ключи типов <type>int</type> и <type>string</type></title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$array = array(
|
||
"foo" => "bar",
|
||
"bar" => "foo",
|
||
100 => -100,
|
||
-100 => 100,
|
||
);
|
||
var_dump($array);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
array(4) {
|
||
["foo"]=>
|
||
string(3) "bar"
|
||
["bar"]=>
|
||
string(3) "foo"
|
||
[100]=>
|
||
int(-100)
|
||
[-100]=>
|
||
int(100)
|
||
}
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
|
||
<para>
|
||
Параметр <replaceable>key</replaceable> является необязательным. Если он не указан,
|
||
PHP будет использовать предыдущее наибольшее значение ключа типа
|
||
<type>int</type>, увеличенное на 1.
|
||
</para>
|
||
|
||
<example>
|
||
<title>Индексированные массивы без ключа</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$array = array("foo", "bar", "hallo", "world");
|
||
var_dump($array);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
array(4) {
|
||
[0]=>
|
||
string(3) "foo"
|
||
[1]=>
|
||
string(3) "bar"
|
||
[2]=>
|
||
string(5) "hallo"
|
||
[3]=>
|
||
string(5) "world"
|
||
}
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
|
||
<para>
|
||
Возможно указать ключ только для некоторых элементов и пропустить для других:
|
||
</para>
|
||
|
||
<example>
|
||
<title>Ключи для некоторых элементов</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$array = array(
|
||
"a",
|
||
"b",
|
||
6 => "c",
|
||
"d",
|
||
);
|
||
var_dump($array);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
array(4) {
|
||
[0]=>
|
||
string(1) "a"
|
||
[1]=>
|
||
string(1) "b"
|
||
[6]=>
|
||
string(1) "c"
|
||
[7]=>
|
||
string(1) "d"
|
||
}
|
||
]]>
|
||
</screen>
|
||
<para>
|
||
Как вы видите последнее значение <literal>"d"</literal> было присвоено ключу
|
||
<literal>7</literal>. Это произошло потому, что самое большое значение ключа целого
|
||
типа перед этим было <literal>6</literal>.
|
||
</para>
|
||
</example>
|
||
</sect3>
|
||
|
||
<sect3 xml:id="language.types.array.syntax.accessing">
|
||
<title>Доступ к элементам массива с помощью квадратных скобок</title>
|
||
|
||
<para>
|
||
Доступ к элементам массива может быть осуществлен с помощью синтаксиса <literal>array[key]</literal>.
|
||
</para>
|
||
|
||
<example>
|
||
<title>Доступ к элементам массива</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$array = array(
|
||
"foo" => "bar",
|
||
42 => 24,
|
||
"multi" => array(
|
||
"dimensional" => array(
|
||
"array" => "foo"
|
||
)
|
||
)
|
||
);
|
||
|
||
var_dump($array["foo"]);
|
||
var_dump($array[42]);
|
||
var_dump($array["multi"]["dimensional"]["array"]);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
string(3) "bar"
|
||
int(24)
|
||
string(3) "foo"
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
<note>
|
||
<para>
|
||
И квадратные и фигурные скобки можно взаимозаменяемо использовать для доступа к
|
||
элементам массива (то есть и <literal>$array[42]</literal> и <literal>$array{42}</literal>
|
||
равнозначны).
|
||
</para>
|
||
</note>
|
||
|
||
<example>
|
||
<title>Разыменование массива</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function getArray() {
|
||
return array(1, 2, 3);
|
||
}
|
||
|
||
$secondElement = getArray()[1];
|
||
|
||
// или так
|
||
list(, $secondElement) = getArray();
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<note>
|
||
<para>
|
||
Попытка доступа к неопределенному ключу в массиве - это то же самое,
|
||
что и попытка доступа к любой другой неопределенной переменной:
|
||
будет сгенерирована ошибка уровня <constant>E_NOTICE</constant>,
|
||
и результат будет &null;.
|
||
</para>
|
||
</note>
|
||
<note>
|
||
<para>
|
||
Массив, разыменовывающий скалярное значение, которое не является строкой
|
||
(<type>string</type>), отдаст &null;. До PHP 7.4.0 не выдается сообщение об ошибке.
|
||
Начиная с PHP 7.4.0, выдается ошибка <constant>E_NOTICE</constant>;
|
||
с PHP 8.0.0 выдается ошибка <constant>E_WARNING</constant>.
|
||
</para>
|
||
</note>
|
||
</sect3>
|
||
|
||
<sect3 xml:id="language.types.array.syntax.modifying">
|
||
<title>Создание/модификация с помощью синтаксиса квадратных скобок</title>
|
||
|
||
<para>
|
||
Существующий массив может быть изменен путем явной установкой значений в нем.
|
||
</para>
|
||
|
||
<para>
|
||
Это выполняется присвоением значений массиву (<type>array</type>) с указанием в
|
||
скобках ключа. Кроме того, ключ можно опустить, в результате получится пустая пара скобок (<literal>[]</literal>).
|
||
</para>
|
||
|
||
<synopsis>
|
||
$arr[<replaceable>key</replaceable>] = <replaceable>value</replaceable>;
|
||
$arr[] = <replaceable>value</replaceable>;
|
||
// <replaceable>key</replaceable> может быть <type>int</type> или <type>string</type>
|
||
// <replaceable>value</replaceable> может быть любым значением любого типа</synopsis>
|
||
|
||
<para>
|
||
Если массив <varname>$arr</varname> еще не существует, он будет создан.
|
||
Таким образом, это еще один способ определить массив <type>array</type>. Однако такой
|
||
способ применять не рекомендуется, так как если переменная <varname>$arr</varname>
|
||
уже содержит некоторое значение (например, значение типа <type>string</type> из
|
||
переменной запроса), то это значение останется на месте и <literal>[]</literal> может на
|
||
самом деле означать <link linkend="language.types.string.substr">доступ к символу в
|
||
строке</link>. Лучше инициализировать переменную путем явного присваивания значения.
|
||
</para>
|
||
<note>
|
||
<simpara>
|
||
Начиная с PHP 7.1.0, используя в оператор "пустой индекс" на строке, приведет к
|
||
фатальной ошибке. Ранее, в этом случае, строка молча преобразовывалась в массив.
|
||
</simpara>
|
||
</note>
|
||
|
||
<para>
|
||
Для изменения определенного значения просто присвойте новое значение элементу,
|
||
используя его ключ. Если вы хотите удалить пару ключ/значение, вам необходимо
|
||
использовать функцию <function>unset</function>.
|
||
</para>
|
||
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$arr = array(5 => 1, 12 => 2);
|
||
|
||
$arr[] = 56; // В этом месте скрипта это
|
||
// то же самое, что и $arr[13] = 56;
|
||
|
||
$arr["x"] = 42; // Это добавляет к массиву новый
|
||
// элемент с ключом "x"
|
||
|
||
unset($arr[5]); // Это удаляет элемент из массива
|
||
|
||
unset($arr); // Это удаляет массив полностью
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
|
||
<note>
|
||
<para>
|
||
Как уже говорилось выше, если ключ не был указан, то будет взят максимальный из
|
||
существующих целочисленных (<type>int</type>) индексов, и новым ключом будет
|
||
это максимальное значение (в крайнем случае 0) плюс 1. Если целочисленных (<type>int</type>) индексов
|
||
еще нет, то ключом будет <literal>0</literal> (ноль).
|
||
</para>
|
||
|
||
<para>
|
||
Учтите, что максимальное целое значение ключа <emphasis>не обязательно
|
||
существует в массиве в данный момент</emphasis>. Оно могло просто существовать
|
||
в массиве какое-то время, с тех пор как он был переиндексирован в последний раз.
|
||
Следующий пример это иллюстрирует:
|
||
</para>
|
||
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
// Создаем простой массив.
|
||
$array = array(1, 2, 3, 4, 5);
|
||
print_r($array);
|
||
|
||
// Теперь удаляем каждый элемент, но сам массив оставляем нетронутым:
|
||
foreach ($array as $i => $value) {
|
||
unset($array[$i]);
|
||
}
|
||
print_r($array);
|
||
|
||
// Добавляем элемент (обратите внимание, что новым ключом будет 5, вместо 0).
|
||
$array[] = 6;
|
||
print_r($array);
|
||
|
||
// Переиндексация:
|
||
$array = array_values($array);
|
||
$array[] = 7;
|
||
print_r($array);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Array
|
||
(
|
||
[0] => 1
|
||
[1] => 2
|
||
[2] => 3
|
||
[3] => 4
|
||
[4] => 5
|
||
)
|
||
Array
|
||
(
|
||
)
|
||
Array
|
||
(
|
||
[5] => 6
|
||
)
|
||
Array
|
||
(
|
||
[0] => 6
|
||
[1] => 7
|
||
)
|
||
]]>
|
||
</screen>
|
||
</informalexample>
|
||
|
||
</note>
|
||
|
||
</sect3>
|
||
</sect2><!-- end syntax -->
|
||
|
||
<sect2 xml:id="language.types.array.useful-funcs">
|
||
<title>Полезные функции</title>
|
||
|
||
<para>
|
||
Для работы с массивами существует достаточное количество полезных
|
||
функций. Смотрите раздел <link linkend="ref.array">функции для работы
|
||
с массивами</link>.
|
||
</para>
|
||
|
||
<note>
|
||
<para>
|
||
Функция <function>unset</function> позволяет удалять ключи массива.
|
||
Обратите внимание, что массив <emphasis>НЕ</emphasis>
|
||
будет переиндексирован. Если вы действительно хотите поведения в стиле
|
||
"удалить и сдвинуть", можно переиндексировать массив
|
||
используя <function>array_values</function>.
|
||
</para>
|
||
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$a = array(1 => 'один', 2 => 'два', 3 => 'три');
|
||
unset($a[2]);
|
||
/* даст массив, представленный так:
|
||
$a = array(1 => 'один', 3 => 'три');
|
||
а НЕ так:
|
||
$a = array(1 => 'один', 2 => 'три');
|
||
*/
|
||
|
||
$b = array_values($a);
|
||
// Теперь $b это array(0 => 'один', 1 => 'три')
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
</note>
|
||
|
||
<para>
|
||
Управляющая конструкция &foreach; существует специально для массивов.
|
||
Она предоставляет возможность легко пройтись по массиву.
|
||
|
||
</para>
|
||
</sect2>
|
||
|
||
<sect2 xml:id="language.types.array.donts">
|
||
<title>Что можно и нельзя делать с массивами</title>
|
||
|
||
<sect3 xml:id="language.types.array.foo-bar">
|
||
<title>Почему <literal>$foo[bar]</literal> неверно?</title>
|
||
|
||
<para>
|
||
Всегда заключайте в кавычки строковый литерал в индексе ассоциативного массива.
|
||
К примеру, пишите <literal>$foo['bar']</literal>, а не
|
||
<literal>$foo[bar]</literal>. Но почему? Часто в старых скриптах можно встретить
|
||
следующий синтаксис:
|
||
</para>
|
||
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$foo[bar] = 'враг';
|
||
echo $foo[bar];
|
||
// и т.д.
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
|
||
<para>
|
||
Это неверно, хотя и работает. Причина в том, что этот код содержит неопределенную
|
||
константу (<literal>bar</literal>), а не строку (<literal>'bar'</literal> - обратите внимание
|
||
на кавычки). Это работает, потому что PHP автоматически преобразует
|
||
<emphasis>"голую строку"</emphasis> (не заключенную в кавычки строку,
|
||
которая не соответствует ни одному из известных символов языка) в строку
|
||
со значением этой "голой строки". Например, если константа с именем <constant>bar</constant>
|
||
не определена, то PHP заменит bar на
|
||
строку <literal>'bar'</literal> и использует ее.
|
||
</para>
|
||
|
||
<warning>
|
||
<simpara>
|
||
Этот резервный вариант для обработки неопределенной константы в качестве
|
||
пустой строки объявлен устаревшим с PHP 7.2.0 и генерирует ошибку уровня
|
||
<constant>E_WARNING</constant>. Ранее выдавалась ошибка уровня
|
||
<constant>E_NOTICE</constant>.
|
||
</simpara>
|
||
</warning>
|
||
|
||
<note>
|
||
<simpara>
|
||
Это не означает, что нужно <emphasis>всегда</emphasis> заключать
|
||
ключ в кавычки. Нет необходимости заключать в кавычки <link
|
||
linkend="language.constants">константы</link> или <link
|
||
linkend="language.variables">переменные</link>, поскольку это
|
||
помешает PHP обрабатывать их.
|
||
</simpara>
|
||
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
error_reporting(E_ALL);
|
||
ini_set('display_errors', true);
|
||
ini_set('html_errors', false);
|
||
// Простой массив:
|
||
$array = array(1, 2);
|
||
$count = count($array);
|
||
for ($i = 0; $i < $count; $i++) {
|
||
echo "\nПроверяем $i: \n";
|
||
echo "Плохо: " . $array['$i'] . "\n";
|
||
echo "Хорошо: " . $array[$i] . "\n";
|
||
echo "Плохо: {$array['$i']}\n";
|
||
echo "Хорошо: {$array[$i]}\n";
|
||
}
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Проверяем 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
|
||
]]>
|
||
</screen>
|
||
</note>
|
||
|
||
<para>
|
||
Дополнительные примеры, демонстрирующие этот факт:
|
||
</para>
|
||
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
// Показываем все ошибки
|
||
error_reporting(E_ALL);
|
||
|
||
$arr = array('fruit' => 'apple', 'veggie' => 'carrot');
|
||
|
||
// Верно
|
||
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
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
|
||
<para>
|
||
Если вы переведете <link linkend="ini.error-reporting">error_reporting</link>
|
||
в режим отображения ошибок уровня
|
||
<constant>E_NOTICE</constant> (например, такой как
|
||
<constant>E_ALL</constant>), вы сразу увидите эти ошибки. По
|
||
умолчанию <link linkend="ini.error-reporting">
|
||
error_reporting</link> установлена их не отображать.
|
||
</para>
|
||
|
||
<para>
|
||
Как указано в разделе <link linkend="language.types.array.syntax">синтаксис</link>,
|
||
внутри квадратных скобок ('<literal>[</literal>'
|
||
и '<literal>]</literal>') должно быть выражение. Это означает, что можно писать вот так:
|
||
</para>
|
||
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
echo $arr[somefunc($bar)];
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
|
||
<para>
|
||
Это пример использования возвращаемого функцией значения
|
||
в качестве индекса массива. PHP известны также и константы:
|
||
</para>
|
||
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$error_descriptions[E_ERROR] = "Произошла фатальная ошибка";
|
||
$error_descriptions[E_WARNING] = "PHP сообщает о предупреждении";
|
||
$error_descriptions[E_NOTICE] = "Это лишь неофициальное замечание";
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
|
||
<para>
|
||
Обратите внимание, что <constant>E_ERROR</constant> - это такой же
|
||
верный идентификатор, как и <literal>bar</literal> в первом примере.
|
||
Но последний пример по сути эквивалентен такой записи:
|
||
</para>
|
||
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$error_descriptions[1] = "Произошла фатальная ошибка";
|
||
$error_descriptions[2] = "PHP сообщает о предупреждении";
|
||
$error_descriptions[8] = "Это лишь неофициальное замечание";
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
|
||
<para>
|
||
поскольку <constant>E_ERROR</constant> соответствует <literal>1</literal> и т.д.
|
||
</para>
|
||
|
||
<sect4 xml:id="language.types.array.foo-bar.why">
|
||
<title>Так что же в этом плохого?</title>
|
||
|
||
<para>
|
||
Когда-нибудь в будущем команда разработчиков PHP возможно пожелает
|
||
добавить еще одну константу или ключевое слово, либо константа из
|
||
другого кода может вмешаться и тогда у вас могут
|
||
возникнуть проблемы. Например, вы уже не можете использовать таким
|
||
образом слова <literal>empty</literal> и
|
||
<literal>default</literal>, поскольку они являются
|
||
<link linkend="reserved">зарезервированными ключевыми словами</link>.
|
||
</para>
|
||
|
||
<note>
|
||
<simpara>
|
||
Повторим, внутри строки (<type>string</type>), заключенной
|
||
в двойные кавычки, корректно не окружать индексы
|
||
массива кавычками, поэтому <literal>"$foo[bar]"</literal>
|
||
является верной записью. Более подробно почему - смотрите
|
||
вышеприведенные примеры, а также раздел по
|
||
<link linkend="language.types.string.parsing">обработке
|
||
переменных в строках</link>.
|
||
</simpara>
|
||
</note>
|
||
|
||
</sect4>
|
||
</sect3>
|
||
</sect2>
|
||
|
||
<sect2 xml:id="language.types.array.casting">
|
||
<title>Преобразование в массив</title>
|
||
|
||
<para>
|
||
Для любого из типов <type>int</type>, <type>float</type>,
|
||
<type>string</type>, <type>bool</type> и <type>resource</type>,
|
||
преобразование значения в массив дает результатом массив с
|
||
одним элементом (с индексом 0), являющимся скалярным значением, с
|
||
которого вы начали. Другими словами, <literal>(array)$scalarValue</literal>
|
||
- это точно то же самое, что и <literal>array($scalarValue)</literal>.
|
||
</para>
|
||
|
||
<para>
|
||
Если вы преобразуете в массив объект (<type>object</type>), вы
|
||
получите в качестве элементов массива свойства (переменные-члены)
|
||
этого объекта. Ключами будут имена переменных-членов, с некоторыми примечательными
|
||
исключениями: целочисленные свойства станут недоступны;
|
||
к закрытым полям класса (private) спереди будет дописано имя класса;
|
||
к защищенным полям класса (protected) спереди будет добавлен символ '*'.
|
||
Эти добавленные значения с обоих сторон также имеют нулевые байты.
|
||
Это может вызвать несколько неожиданное поведение:
|
||
</para>
|
||
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
class A {
|
||
private $A; // Это станет '\0A\0A'
|
||
}
|
||
|
||
class B extends A {
|
||
private $A; // Это станет '\0B\0A'
|
||
public $AA; // Это станет 'AA'
|
||
}
|
||
|
||
var_dump((array) new B());
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
|
||
<para>
|
||
Вышеприведенный код покажет 2 ключа с именем 'AA', хотя один из них на самом деле
|
||
имеет имя '\0A\0A'.
|
||
</para>
|
||
|
||
<para>
|
||
Если вы преобразуете в массив значение &null;, вы получите
|
||
пустой массив.
|
||
</para>
|
||
</sect2>
|
||
|
||
<sect2 xml:id="language.types.array.comparing">
|
||
<title>Сравнение</title>
|
||
|
||
<para>
|
||
Массивы можно сравнивать при помощи функции <function>array_diff</function>
|
||
и <link linkend="language.operators.array">операторов массивов</link>.
|
||
</para>
|
||
</sect2>
|
||
|
||
<sect2 xml:id="language.types.array.examples">
|
||
<title>Примеры</title>
|
||
|
||
<para>
|
||
Тип массив в PHP является очень гибким, вот несколько примеров:
|
||
</para>
|
||
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
// это
|
||
$a = array( 'color' => 'red',
|
||
'taste' => 'sweet',
|
||
'shape' => 'round',
|
||
'name' => 'apple',
|
||
4 // ключом будет 0
|
||
);
|
||
|
||
$b = array('a', 'b', 'c');
|
||
|
||
// . . .полностью соответствует
|
||
$a = array();
|
||
$a['color'] = 'red';
|
||
$a['taste'] = 'sweet';
|
||
$a['shape'] = 'round';
|
||
$a['name'] = 'apple';
|
||
$a[] = 4; // ключом будет 0
|
||
|
||
$b = array();
|
||
$b[] = 'a';
|
||
$b[] = 'b';
|
||
$b[] = 'c';
|
||
|
||
// после выполнения этого кода, $a будет массивом
|
||
// array('color' => 'red', 'taste' => 'sweet', 'shape' => 'round',
|
||
// 'name' => 'apple', 0 => 4), а $b будет
|
||
// array(0 => 'a', 1 => 'b', 2 => 'c'), или просто array('a', 'b', 'c').
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
|
||
<example>
|
||
<title>Использование array()</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
// Массив как карта (свойств)
|
||
$map = array( 'version' => 4,
|
||
'OS' => 'Linux',
|
||
'lang' => 'english',
|
||
'short_tags' => true
|
||
);
|
||
|
||
// исключительно числовые ключи
|
||
$array = array( 7,
|
||
8,
|
||
0,
|
||
156,
|
||
-10
|
||
);
|
||
// это то же самое, что и array(0 => 7, 1 => 8, ...)
|
||
|
||
$switching = array( 10, // ключ = 0
|
||
5 => 6,
|
||
3 => 7,
|
||
'a' => 4,
|
||
11, // ключ = 6 (максимальным числовым индексом было 5)
|
||
'8' => 2, // ключ = 8 (число!)
|
||
'02' => 77, // ключ = '02'
|
||
0 => 12 // значение 10 будет перезаписано на 12
|
||
);
|
||
|
||
// пустой массив
|
||
$empty = array();
|
||
?>
|
||
]]>
|
||
<!-- TODO example of
|
||
- overwriting keys
|
||
- using vars/functions as key/values
|
||
- warning about references
|
||
-->
|
||
</programlisting>
|
||
</example>
|
||
|
||
<example xml:id="language.types.array.examples.loop">
|
||
<title>Коллекция</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$colors = array('red', 'blue', 'green', 'yellow');
|
||
|
||
foreach ($colors as $color) {
|
||
echo "Вам нравится $color?\n";
|
||
}
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Вам нравится red?
|
||
Вам нравится blue?
|
||
Вам нравится green?
|
||
Вам нравится yellow?
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
|
||
<para>
|
||
Изменение значений массива напрямую возможно
|
||
путем передачи их по ссылке.
|
||
</para>
|
||
|
||
<example xml:id="language.types.array.examples.changeloop">
|
||
<title>Изменение элемента в цикле</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
foreach ($colors as &$color) {
|
||
$color = strtoupper($color);
|
||
}
|
||
unset($color); /* это нужно для того, чтобы последующие записи в
|
||
$color не меняли последний элемент массива */
|
||
|
||
print_r($colors);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Array
|
||
(
|
||
[0] => RED
|
||
[1] => BLUE
|
||
[2] => GREEN
|
||
[3] => YELLOW
|
||
)
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
|
||
<para>
|
||
Следующий пример создает массив, начинающийся с единицы.
|
||
</para>
|
||
|
||
<example>
|
||
<title>Индекс, начинающийся с единицы</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$firstquarter = array(1 => 'Январь', 'Февраль', 'Март');
|
||
print_r($firstquarter);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Array
|
||
(
|
||
[1] => 'Январь'
|
||
[2] => 'Февраль'
|
||
[3] => 'Март'
|
||
)
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
|
||
<example>
|
||
<title>Заполнение массива</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
// заполняем массив всеми элементами из директории
|
||
$handle = opendir('.');
|
||
while (false !== ($file = readdir($handle))) {
|
||
$files[] = $file;
|
||
}
|
||
closedir($handle);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<para>
|
||
Массивы упорядочены. Вы можете изменять порядок элементов,
|
||
используя различные функции сортировки. Для дополнительной
|
||
информации смотрите раздел <link linkend="ref.array">функции
|
||
для работы с массивами</link>. Вы можете подсчитать количество
|
||
элементов в массиве с помощью функции <function>count</function>.
|
||
</para>
|
||
|
||
<example>
|
||
<title>Сортировка массива</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
sort($files);
|
||
print_r($files);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<para>
|
||
Поскольку значение массива может быть чем угодно, им также
|
||
может быть другой массив. Таким образом вы можете создавать
|
||
рекурсивные и многомерные массивы.
|
||
</para>
|
||
|
||
<example>
|
||
<title>Рекурсивные и многомерные массивы</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$fruits = array ( "fruits" => array ( "a" => "апельсин",
|
||
"b" => "банан",
|
||
"c" => "яблоко"
|
||
),
|
||
"numbers" => array ( 1,
|
||
2,
|
||
3,
|
||
4,
|
||
5,
|
||
6
|
||
),
|
||
"holes" => array ( "первая",
|
||
5 => "вторая",
|
||
"третья"
|
||
)
|
||
);
|
||
|
||
// Несколько примеров доступа к значениям предыдущего массива
|
||
echo $fruits["holes"][5]; // напечатает "вторая"
|
||
echo $fruits["fruits"]["a"]; // напечатает "апельсин"
|
||
unset($fruits["holes"][0]); // удалит "первая"
|
||
|
||
// Создаст новый многомерный массив
|
||
$juices["apple"]["green"] = "good";
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<para>
|
||
Обратите внимание, что при присваивании массива всегда
|
||
происходит копирование значения. Чтобы скопировать массив по
|
||
ссылке, вам нужно использовать <link linkend="language.operators">оператор ссылки</link>.
|
||
</para>
|
||
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$arr1 = array(2, 3);
|
||
$arr2 = $arr1;
|
||
$arr2[] = 4; // $arr2 изменился,
|
||
// $arr1 все еще array(2, 3)
|
||
|
||
$arr3 = &$arr1;
|
||
$arr3[] = 4; // теперь $arr1 и $arr3 одинаковы
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<!-- Keep this comment at the end of the file
|
||
Local variables:
|
||
mode: sgml
|
||
sgml-omittag:t
|
||
sgml-shorttag:t
|
||
sgml-minimize-attributes:nil
|
||
sgml-always-quote-attributes:t
|
||
sgml-indent-step:1
|
||
sgml-indent-data:t
|
||
indent-tabs-mode:nil
|
||
sgml-parent-document:nil
|
||
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
||
sgml-exposed-tags:nil
|
||
sgml-local-catalogs:nil
|
||
sgml-local-ecat-files:nil
|
||
End:
|
||
vim600: syn=xml fen fdm=syntax fdl=2 si
|
||
vim: et tw=78 syn=sgml
|
||
vi: ts=1 sw=1
|
||
-->
|