mirror of
https://github.com/php/doc-zh.git
synced 2026-03-24 07:02:15 +01:00
301 lines
7.7 KiB
XML
301 lines
7.7 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<!-- $Revision$ -->
|
||
<!-- EN-Revision: cdc9d28d334bbc08386fecf8aade66080004a9dd Maintainer: dallas Status: ready -->
|
||
<!-- CREDITS: Luffy, mowangjuanzi -->
|
||
<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> 语句类似于具有同一个表达式的一系列 <literal>if</literal>
|
||
语句。很多场合下需要把同一个变量(或表达式)与很多不同的值比较,并根据它等于哪个值来执行不同的代码。这正是
|
||
<literal>switch</literal> 语句的用途。
|
||
</simpara>
|
||
<note>
|
||
<simpara>
|
||
注意和其它语言不同,<link linkend="control-structures.continue">continue</link>
|
||
语句作用到 switch 上的作用类似于 <literal>break</literal>。如果在循环中有一个
|
||
switch 并希望 continue 到外层循环中的下一轮循环,用 <literal>continue 2</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[
|
||
// 这是 switch 语句
|
||
|
||
switch ($i) {
|
||
case 0:
|
||
echo "i equals 0";
|
||
break;
|
||
case 1:
|
||
echo "i equals 1";
|
||
break;
|
||
case 2:
|
||
echo "i equals 2";
|
||
break;
|
||
}
|
||
|
||
// 相当于:
|
||
|
||
if ($i == 0) {
|
||
echo "i equals 0";
|
||
} elseif ($i == 1) {
|
||
echo "i equals 1";
|
||
} elseif ($i == 2) {
|
||
echo "i equals 2";
|
||
}
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
为避免错误,理解 <literal>switch</literal> 是怎样执行的非常重要。<literal>switch</literal>
|
||
语句一行接一行地执行(实际上是语句接语句)。开始时没有代码被执行。仅当一个
|
||
<literal>case</literal> 语句中的值和 <literal>switch</literal>
|
||
表达式的值匹配时 PHP 才开始执行语句,直到 <literal>switch</literal>
|
||
的程序段结束或者遇到第一个 <literal>break</literal>
|
||
语句为止。如果不在 case 的语句段最后写上 <literal>break</literal>
|
||
的话,PHP 将继续执行下一个 case 中的语句段。例如:
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
switch ($i) {
|
||
case 0:
|
||
echo "i equals 0";
|
||
case 1:
|
||
echo "i equals 1";
|
||
case 2:
|
||
echo "i equals 2";
|
||
}
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
</para>
|
||
<simpara>
|
||
这里如果 <varname>$i</varname> 等于 0,PHP 将执行所有的 echo 语句!如果
|
||
<varname>$i</varname> 等于 1,PHP 将执行后面两条 echo 语句。只有当
|
||
<varname>$i</varname> 等于 2 时,才会得到“预期”的结果——只显示“i equals 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 is less than 3 but not negative";
|
||
break;
|
||
case 3:
|
||
echo "i is 3";
|
||
}
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
</para>
|
||
<para>
|
||
一个 case 的特例是 <literal>default</literal>。它匹配了任何和其它
|
||
case 都不匹配的情况。例如:
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
switch ($i) {
|
||
case 0:
|
||
echo "i equals 0";
|
||
break;
|
||
case 1:
|
||
echo "i equals 1";
|
||
break;
|
||
case 2:
|
||
echo "i equals 2";
|
||
break;
|
||
default:
|
||
echo "i is not equal to 0, 1 or 2";
|
||
}
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
<note>
|
||
<simpara>
|
||
如果有多个 default 将导致
|
||
<constant>E_COMPILE_ERROR</constant> 错误。
|
||
</simpara>
|
||
</note>
|
||
<note>
|
||
<simpara>
|
||
从技术上讲,<literal>default</literal> case
|
||
可以按照任何顺序列出。只有在没有匹配到其它的 case
|
||
时才会使用它。但是最好按照惯例,将其作为最后一个分支放在最后。
|
||
</simpara>
|
||
</note>
|
||
</para>
|
||
<para>
|
||
如果没有匹配到 <literal>case</literal> 分支且没有 <literal>default</literal>
|
||
分支,则不会执行任何代码,就像 <literal>if</literal> 不为 true 一样。
|
||
</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>
|
||
对于更复杂的比较,值 &true; 可用于 switch 的值。或使用
|
||
<literal>if</literal>-<literal>else</literal> 代替 <literal>switch</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>
|
||
<literal>switch</literal> 支持替代语法的流程控制。更多信息见<link
|
||
linkend="control-structures.alternative-syntax">流程控制的替代语法</link>一节。
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
switch ($i):
|
||
case 0:
|
||
echo "i equals 0";
|
||
break;
|
||
case 1:
|
||
echo "i equals 1";
|
||
break;
|
||
case 2:
|
||
echo "i equals 2";
|
||
break;
|
||
default:
|
||
echo "i is not equal to 0, 1 or 2";
|
||
endswitch;
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
</para>
|
||
<para>
|
||
允许使用分号代替 case 语句后的冒号,例如:
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
switch($beer)
|
||
{
|
||
case 'tuborg';
|
||
case 'carlsberg';
|
||
case 'stella';
|
||
case 'heineken';
|
||
echo 'Good choice';
|
||
break;
|
||
default;
|
||
echo 'Please make a new selection...';
|
||
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
|
||
-->
|