1
0
mirror of https://github.com/php/doc-ru.git synced 2026-03-24 07:42:22 +01:00
Files

336 lines
13 KiB
XML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: cdc9d28d334bbc08386fecf8aade66080004a9dd Maintainer: mch Status: ready -->
<!-- Reviewed: no -->
<sect1 xml:id="control-structures.switch" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>switch</title>
<?phpdoc print-version-for="switch"?>
<simpara>
Инструкция <literal>switch</literal> похожа на серию инструкций IF,
которые проверяют одно и то же выражение. Одну и ту же переменную или выражение
часто сравнивают с разными значениями, чтобы выполнить ту часть кода,
условию выполнения которой соответствует значение переменной или выражения.
Инструкция <literal>switch</literal> выполняет такие проверки.
</simpara>
<note>
<simpara>
Обратите внимание, что в отличие от отдельных языков программирования,
действие инструкции <link linkend="control-structures.continue">continue</link>
распространяется на блок <literal>switch</literal>, а не на отдельный случай,
и ведёт себя аналогично инструкции <literal>break</literal>.
При вызове инструкции <literal>continue 2</literal> выполнение перейдёт к следующей итерации
внешнего цикла, если блок <literal>switch</literal> выполняет проверки внутри цикла.
</simpara>
</note>
<note>
<para>
Обратите внимание, конструкция switch/case выполняет
<link linkend="types.comparisions-loose">нестрогое сравнение</link>.
</para>
</note>
<para>
В следующем примере блоки кода выполняют эквивалентные проверки.
Один блок выполняет проверки через серию инструкций <literal>if</literal> и <literal>elseif</literal>,
другой — через инструкцию <literal>switch</literal>. Каждый блок кода выдаёт одинаковый результат.
<example>
<title>Структура инструкции <literal>switch</literal></title>
<programlisting role="php">
<![CDATA[
<?php
// Инструкция switch:
switch ($i) {
case 0:
echo "Значение переменной \$i равно 0";
break;
case 1:
echo "Значение переменной \$i равно 1";
break;
case 2:
echo "Значение переменной \$i равно 2";
break;
}
// ...эквивалентна:
if ($i == 0) {
echo "Значение переменной \$i равно 0";
} elseif ($i == 1) {
echo "Значение переменной \$i равно 1";
} elseif ($i == 2) {
echo "Значение переменной \$i равно 2";
}
?>
]]>
</programlisting>
</example>
</para>
<para>
Понимание того, в каком порядке инструкция <literal>switch</literal> выполняет инструкции случаев,
помогает избегать ошибок. Инструкция <literal>switch</literal> выполняет
строку за строкой, или точнее — выражение за выражением.
В начале никакой код не выполняется. PHP начинает выполнение инструкции случаев,
только когда находит инструкцию <literal>case</literal>, выражение которой
вычисляется как значение, которое совпадает со значением выражения в инструкции <literal>switch</literal>.
Тогда PHP или продолжает выполнять инструкции случаев до конца блока <literal>switch</literal>,
даже если значение случая не совпадает со значением инструкции switch,
или пока не увидит первую инструкцию <literal>break</literal>.
PHP продолжит выполнять инструкции следующих случаев,
если в конце списка инструкций случая не записали инструкцию <literal>break</literal>.
Приведём пример:
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
switch ($i) {
case 0:
echo "Значение переменной \$i равно 0";
case 1:
echo "Значение переменной \$i равно 1";
case 2:
echo "Значение переменной \$i равно 2";
}
?>
]]>
</programlisting>
</informalexample>
</para>
<simpara>
PHP выполнит инструкцию echo каждого случая, если значение переменной <varname>$i</varname> равно 0!
PHP выполнит инструкции echo двух последних случаев, если значение переменной <varname>$i</varname> равно 1.
Код поведёт себя предсказуемо и выведет «Значение переменной $i равно 2», только если
значение переменной <varname>$i</varname> равно 2. Поэтому лучше помнить об инструкциях
<literal>break</literal>, даже если в конкретных обстоятельствах инструкции прерывания умышленно не указываются.
</simpara>
<simpara>
В инструкции <literal>switch</literal> условие вычисляется
только один раз, а результат сравнивается со значением выражения каждой инструкции
<literal>case</literal>. В инструкции <literal>elseif</literal>
вычисление условия повторяется. Инструкция <literal>switch</literal> часто работает
быстрее, если условие сложнее простого сравнения «и-или» проверяется в плотном цикле.
</simpara>
<para>
Список инструкций в секциях case разрешается оставлять пустым,
тогда управление передаётся списку инструкций следующей секции case.
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
switch ($i) {
case 0:
case 1:
case 2:
echo "Значение переменной \$i меньше 3, но не отрицательно";
break;
case 3:
echo "Значение переменной \$i равно 3";
}
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
Инструкция <literal>default</literal> управляет случаями по умолчанию.
Управление переходит к случаю по умолчанию при несовпадении значения выражения switch
со значениями выражений других случаев.
Приведём пример:
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
switch ($i) {
case 0:
echo "Значение переменной \$i равно 0";
break;
case 1:
echo "Значение переменной \$i равно 1";
break;
case 2:
echo "Значение переменной \$i равно 2";
break;
default:
echo "Значение переменной \$i не равно 0, 1 или 2";
}
?>
]]>
</programlisting>
</informalexample>
<note>
<simpara>
Многократные инструкции default вызовут ошибку уровня <constant>E_COMPILE_ERROR</constant>.
</simpara>
</note>
<note>
<simpara>
Технически инструкцию <literal>default</literal> разрешается указывать в произвольном месте списка случаев.
Инструкции случая по умолчанию выполняются, только если ни один другой случай не совпал.
Однако, по общему правилу, лучше расположить инструкцию по умолчанию в конце, как последнюю ветвь.
</simpara>
</note>
</para>
<para>
Код не выполнится, как если бы ни одна инструкция <literal>if</literal> не оказалась истинной,
если ни одна ветвь инструкций <literal>case</literal> не соответствует значению проверки
и инструкцию <literal>default</literal> не указали.
</para>
<para>
Значение секции case разрешается указывать в виде выражения. Однако это выражение
вычисляется само по себе, а затем нестрого сравнивается со значением инструкции switch.
Поэтому выражение нельзя использовать для сложных оценок значения конструкции switch.
Приведём пример несложной оценки:
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$target = 1;
$start = 3;
switch ($target) {
case $start - 1:
print "A";
break;
case $start - 2:
print "B";
break;
case $start - 3:
print "C";
break;
case $start - 4:
print "D";
break;
}
// Код выведет "B"
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
Для более сложных сравнений в значении инструкции <literal>switch</literal> указывают значение &true;,
или выполняют сравнения альтернативным способом — в блоках <literal>if</literal>-<literal>else</literal>.
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$offset = 1;
$start = 3;
switch (true) {
case $start - $offset === 1:
print "A";
break;
case $start - $offset === 2:
print "B";
break;
case $start - $offset === 3:
print "C";
break;
case $start - $offset === 4:
print "D";
break;
}
// Код выведет "B"
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
Блоки switch поддерживают альтернативный синтаксис управляющих конструкций.
Дополнительную информацию содержит раздел
«<link linkend="control-structures.alternative-syntax">Альтернативный синтаксис управляющих конструкций</link>».
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
switch ($i):
case 0:
echo "Значение переменной \$i равно 0";
break;
case 1:
echo "Значение переменной \$i равно 1";
break;
case 2:
echo "Значение переменной \$i равно 2";
break;
default:
echo "Значение переменной \$i не равно 0, 1 или 2";
endswitch;
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
После выражения инструкции case вместо двоеточия разрешается указывать точку с запятой. Например:
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
switch ($beer) {
case 'Tuborg';
case 'Carlsberg';
case 'Stella';
case 'Heineken';
echo 'Хороший выбор';
break;
default;
echo 'Пожалуйста, выберите заново...';
break;
}
?>
]]>
</programlisting>
</informalexample>
</para>
<sect2 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member>&match;</member>
</simplelist>
</para>
</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
-->