Rumah > Artikel > pembangunan bahagian belakang > 浅谈PHP语音里的流程控制及实现方法
脚本由语句构成,语句靠流程控制实现功能,这一节主要介绍了几个关键字的使用。
elseif
elseif
和else if
的行为完全一样,如果用冒号来定义if/elseif
条件,那就不能用两个单词的else if
,否则PHP会产生解析错误。
<code><span><?php </span><span>$a</span> = <span>1</span>; <span>$b</span> = <span>2</span>; <span>if</span>(<span>$a</span> > <span>$b</span>) : <span>echo</span><span>"$a is greater than $b"</span>; <span>elseif</span>(<span>$a</span> == <span>$b</span>) : <span>echo</span><span>"$a equals $b"</span>; <span>else</span> : <span>echo</span><span>"$a is neither greater than or equal to $b"</span>; <span>endif</span>;</span></code>
替代语法
下面的这些关键字可以使用流程控制的替代语法,基本形式是把左花括号换成冒号,右花括号换为下面的字符。
<code><span>if</span> - <span>endif</span><span>while</span> - <span>endwhile</span><span>for</span> - <span>endfor</span><span>foreach</span> - <span>endforeach</span><span>switch</span> - <span>endswitch</span></code>
注意!PHP不支持在同一控制块内混合使用两种语法。
do-while
这个循环乍看起来挺熟悉的,但是却忽略了它的某些用法。
手册中说,资深的C语言用户可能熟悉另一种不同的do-while
循环用法,把语句放在do-while(0)
之中。我竟然第一次听说有这种技巧,看来我还是C语言小白。
顺便搜索整理一下do-while(0)
这种特殊用法的好处吧。
break
跳过剩余的一段代码。goto
语句。这个帖子讲的挺好的,do{}while(0) 的作用 - c++ - SegmentFault。
foreach
foreach
仅能够应用于数组和对象的遍历。foreach
语法结构提供了遍历数组的简单方式,有下面两种语法。
<code><span>foreach</span>(array_expression <span>as</span><span>$value</span>) statement <span>foreach</span>(array_expression <span>as</span><span>$key</span> => <span>$value</span>) statement</code>
要修改数组元素的值需要使用引用赋值,通过在$value
前加&
实现。
<code><span><?php </span><span>$arr</span> = <span>array</span>(<span>1</span>, <span>2</span>, <span>3</span>, <span>4</span>); <span>foreach</span>(<span>$arr</span><span>as</span> &<span>$value</span>) { <span>$value</span> = <span>$value</span> * <span>2</span>; } <span>unset</span>(<span>$value</span>); <span>foreach</span>(<span>$arr</span><span>as</span><span>$value</span>) { <span>echo</span><span>"$value "</span>; <span>// 2 4 6 8</span> }</span></code>
注意!数组最后一个元素的$value
引用在foreach
循环之后仍会保留,建议使用unset()
将其销毁。
list-each
在示例程序中,还发现了一种特殊的遍历方法,姑且称作list-each
。
当foreach
开始执行时,数组内部的指针会自动指向第一个单元,因此不需要在foreach
循环之前调用reset()
。但是对于while
中的list-each
,数组内部指针$arr
会一直存在着,因此在下次循环前需要reset($arr)
。
<code><span><?php </span><span>$arr</span> = <span>array</span>(<span>'one'</span>, <span>'two'</span>, <span>'three'</span>); <span>// reset($arr);</span><span>while</span>(<span>list</span>(<span>$key</span>, <span>$value</span>) = each(<span>$arr</span>)) { <span>echo</span><span>"Key: $key; Value: $value "</span>; } reset(<span>$arr</span>); <span>while</span>(<span>list</span>(<span>$key</span>, <span>$value</span>) = each(<span>$arr</span>)) { <span>echo</span><span>"Key: $key; Value: $value "</span>; }</span></code>
在上面这段代码中,第一个reset
可以省略,但第二个reset
不能省。
list
PHP 5.5增添了遍历一个数组的数组的功能,并且把嵌套的数组解包到循环变量中。
<code><span><?php </span><span>$array</span> = [ [<span>1</span>, <span>2</span>], [<span>3</span>, <span>4</span>], ]; <span>foreach</span>(<span>$array</span><span>as</span><span>list</span>(<span>$a</span>, <span>$b</span>)) { <span>echo</span><span>"A: $a; B: $b"</span>; }</span></code>
list()
中的单元可以少于嵌套数组的,此时多出来的数组单元将被忽略。若多于,将发出错误信息。
break
break
用来结束当前for/foreach/while/do-while/switch
结构的执行。break
可以接受一个可选的数字参数来决定跳出几重循环,但参数不能为变量。
break
跳出多重循环还是第一次遇到,特意写了个小程序尝试了一下。
<code><span><?php </span><span>while</span>(<span>1</span>) { <span>while</span>(<span>1</span>) { <span>echo</span><span>'hello '</span>; <span>break</span><span>2</span>; } } <span>echo</span><span>'world'</span>;</span></code>
特地在C语言里尝试了一下,提示语法错误。
continue
与break
相似,continue
也可以接受一个可选的数字参数来决定跳过几重循环到循环结尾。
注意!在PHP中switch
语句被认为是可以使用continue
的一种循环结构。
switch
手册中说,PHP和其它语言不同,continue
语句作用到switch
上的作用类似于break
。这是什么意思呢?
switch/case
做的是松散比较==
,而不是严格比较===
。效率方面,switch
语句中条件只求值一次并用来和每个case
语句比较。case
表达式可以是任何求值为简单类型的表达式,不能用数组或对象。允许使用分号代替case
语句后的冒号。
declare
declare
结构用来设定一段代码的执行指令,语法结构如下:
<code><span>declare</span>(directive) statement</code>
directive
部分允许设定declare
代码段的行为,目前只认识两个命令:ticks
和encoding
。declare
结构也可用于全局范围,影响到期后的所有代码。但如果有declare
结构的文件被其它文件包含,则对包含它的父文件不起作用。
Tick(时钟周期)是一个在declare
代码段中解释器每执行N条可计时的低级语句就会发生的事件。在每个tick中出现的事件由register_tick_function()
来指定。用法大致如下。
<code><span>declare</span>(ticks = <span>1</span>); <span><span>function</span><span>tick_handler</span><span>()</span></span>{ <span>echo</span><span>"tick_hander() called.\n"</span>; } register_tick_function(<span>'tick_hander'</span>);</code>
可计时的低级语句有很多,register_tick_function()
后会调用一次周期事件,每条语句后会调用一次周期事件,花括号结束时会调用一次周期事件。
注意,PHP中表达式不能用逗号隔开,不然会出现语法错误。这点与C语言不同,刚注意到。
可以用encoding指令来对每段脚本指定其编码方式。用法如下:
<code><span>declare</span>(encoding = <span>'ISO-8859-1);</span></code>
return
如果是在全局范围中调用,则当前脚本文件中止运行。如果当前脚本文件是被include
或者require
,则控制交回调用文件。如果当前脚本时被include
的,则return
的值会被当作include
调用的返回值,那require
呢?
require
require
和include
几乎完全一样,除了处理失败的方式不同之外。
require
在出错时产生E_COMPILE_ERROR
级别的错误,脚本中止。而include
只产生警告E_WARNING
,脚本继续执行。
include
include
语句包含并运行指定文件,这里要注意一下指定文件的寻找次序。
include_path
会被完全忽略。include_path
指定的目录寻找。若没找到才在调用脚本文件所在目录和当前工作目录下寻找。那么问题来了,调用脚本文件所在目录和当前工作目录有什么区别呢?include
结构会发出一条警告,require
结构会发出一个致命错误。当一个文件被包含时,其中包含的代码继承了include
所在行的变量范围。从该处开始,被调用文件中定义的变量才可在调用文件中使用。当一个文件被包含时,语法解析器在目标文件的开头脱离PHP模式并进入HTML模式,当文件结尾回复。
对于返回值,在失败时include
返回FALSE
并且发出警告。成功的包含则返回1,除非在包含文件中另外给出了返回值。如果在包含文件中定义有函数,这些函数不管是在return
之前还是之后定义的,都可以独立在主文件中使用。
如果来自远程服务器的文件应该在远端运行而只输出结果,那用readfile()
函数更好。另一种将PHP文件包含到一个变量中的方法是用输出控制函数结合include
来捕获其输出。第一次遇到,比较陌生。下面这段代码能将脚本vars.php
中返回的内容输出。
<code><span><?php </span><span>$string</span> = get_include_contents(<span>'vars.php'</span>); <span><span>function</span><span>get_include_contents</span><span>(<span>$filename</span>)</span></span>{ <span>if</span>(is_file(<span>$filename</span>)) { ob_start(); <span>include</span><span>$filename</span>; <span>$contents</span> = ob_get_contents(); ob_end_clean(); <span>return</span><span>$contents</span>; } <span>return</span><span>false</span>; } <span>echo</span><span>$string</span>;</span></code>
因为include
和require
是一种特殊的语言结构,其参数不需要括号。如果文件被包含两次,PHP会发出致命错误,因为函数已经被定义。推荐使用include_once
。
require_once
require_once
语句和require
语句完全相同,唯一区别是,PHP会检查该文件是否已经被包含过,如果是则不会再次包含。
include_once
include_once
语句和include
语句类似,唯一区别是如果该文件已经被包含过,则不会再次包含。
goto
goto
操作符用于跳转到程序的另一位置,目标位置可以用目标名称加上冒号来标记。PHP中的goto
有一定限制,目标位置只能位于同一个文件和作用域。也就是说无法跳出一个函数或类方法,也无法跳入到任何循环或者switch
结构。
(全文完)
脚本由语句构成,语句靠流程控制实现功能,这一节主要介绍了几个关键字的使用。
elseif
elseif
和else if
的行为完全一样,如果用冒号来定义if/elseif
条件,那就不能用两个单词的else if
,否则PHP会产生解析错误。
<code><span><?php </span><span>$a</span> = <span>1</span>; <span>$b</span> = <span>2</span>; <span>if</span>(<span>$a</span> > <span>$b</span>) : <span>echo</span><span>"$a is greater than $b"</span>; <span>elseif</span>(<span>$a</span> == <span>$b</span>) : <span>echo</span><span>"$a equals $b"</span>; <span>else</span> : <span>echo</span><span>"$a is neither greater than or equal to $b"</span>; <span>endif</span>;</span></code>
替代语法
下面的这些关键字可以使用流程控制的替代语法,基本形式是把左花括号换成冒号,右花括号换为下面的字符。
<code><span>if</span> - <span>endif</span><span>while</span> - <span>endwhile</span><span>for</span> - <span>endfor</span><span>foreach</span> - <span>endforeach</span><span>switch</span> - <span>endswitch</span></code>
注意!PHP不支持在同一控制块内混合使用两种语法。
do-while
这个循环乍看起来挺熟悉的,但是却忽略了它的某些用法。
手册中说,资深的C语言用户可能熟悉另一种不同的do-while
循环用法,把语句放在do-while(0)
之中。我竟然第一次听说有这种技巧,看来我还是C语言小白。
顺便搜索整理一下do-while(0)
这种特殊用法的好处吧。
break
跳过剩余的一段代码。goto
语句。这个帖子讲的挺好的,do{}while(0) 的作用 - c++ - SegmentFault。
淮安掼蛋下载(http://www.gamefrye.com/)
foreach
foreach
仅能够应用于数组和对象的遍历。foreach
语法结构提供了遍历数组的简单方式,有下面两种语法。
<code><span>foreach</span>(array_expression <span>as</span><span>$value</span>) statement <span>foreach</span>(array_expression <span>as</span><span>$key</span> => <span>$value</span>) statement</code>
要修改数组元素的值需要使用引用赋值,通过在$value
前加&
实现。
<code><span><?php </span><span>$arr</span> = <span>array</span>(<span>1</span>, <span>2</span>, <span>3</span>, <span>4</span>); <span>foreach</span>(<span>$arr</span><span>as</span> &<span>$value</span>) { <span>$value</span> = <span>$value</span> * <span>2</span>; } <span>unset</span>(<span>$value</span>); <span>foreach</span>(<span>$arr</span><span>as</span><span>$value</span>) { <span>echo</span><span>"$value "</span>; <span>// 2 4 6 8</span> }</span></code>
注意!数组最后一个元素的$value
引用在foreach
循环之后仍会保留,建议使用unset()
将其销毁。
list-each
在示例程序中,还发现了一种特殊的遍历方法,姑且称作list-each
。
当foreach
开始执行时,数组内部的指针会自动指向第一个单元,因此不需要在foreach
循环之前调用reset()
。但是对于while
中的list-each
,数组内部指针$arr
会一直存在着,因此在下次循环前需要reset($arr)
。
<code><span><?php </span><span>$arr</span> = <span>array</span>(<span>'one'</span>, <span>'two'</span>, <span>'three'</span>); <span>// reset($arr);</span><span>while</span>(<span>list</span>(<span>$key</span>, <span>$value</span>) = each(<span>$arr</span>)) { <span>echo</span><span>"Key: $key; Value: $value "</span>; } reset(<span>$arr</span>); <span>while</span>(<span>list</span>(<span>$key</span>, <span>$value</span>) = each(<span>$arr</span>)) { <span>echo</span><span>"Key: $key; Value: $value "</span>; }</span></code>
在上面这段代码中,第一个reset
可以省略,但第二个reset
不能省。
list
PHP 5.5增添了遍历一个数组的数组的功能,并且把嵌套的数组解包到循环变量中。
<code><span><?php </span><span>$array</span> = [ [<span>1</span>, <span>2</span>], [<span>3</span>, <span>4</span>], ]; <span>foreach</span>(<span>$array</span><span>as</span><span>list</span>(<span>$a</span>, <span>$b</span>)) { <span>echo</span><span>"A: $a; B: $b"</span>; }</span></code>
list()
中的单元可以少于嵌套数组的,此时多出来的数组单元将被忽略。若多于,将发出错误信息。
break
break
用来结束当前for/foreach/while/do-while/switch
结构的执行。break
可以接受一个可选的数字参数来决定跳出几重循环,但参数不能为变量。
break
跳出多重循环还是第一次遇到,特意写了个小程序尝试了一下。
<code><span><?php </span><span>while</span>(<span>1</span>) { <span>while</span>(<span>1</span>) { <span>echo</span><span>'hello '</span>; <span>break</span><span>2</span>; } } <span>echo</span><span>'world'</span>;</span></code>
特地在C语言里尝试了一下,提示语法错误。
continue
与break
相似,continue
也可以接受一个可选的数字参数来决定跳过几重循环到循环结尾。
注意!在PHP中switch
语句被认为是可以使用continue
的一种循环结构。
switch
手册中说,PHP和其它语言不同,continue
语句作用到switch
上的作用类似于break
。这是什么意思呢?
switch/case
做的是松散比较==
,而不是严格比较===
。效率方面,switch
语句中条件只求值一次并用来和每个case
语句比较。case
表达式可以是任何求值为简单类型的表达式,不能用数组或对象。允许使用分号代替case
语句后的冒号。
declare
declare
结构用来设定一段代码的执行指令,语法结构如下:
<code><span>declare</span>(directive) statement</code>
directive
部分允许设定declare
代码段的行为,目前只认识两个命令:ticks
和encoding
。declare
结构也可用于全局范围,影响到期后的所有代码。但如果有declare
结构的文件被其它文件包含,则对包含它的父文件不起作用。
Tick(时钟周期)是一个在declare
代码段中解释器每执行N条可计时的低级语句就会发生的事件。在每个tick中出现的事件由register_tick_function()
来指定。用法大致如下。
<code><span>declare</span>(ticks = <span>1</span>); <span><span>function</span><span>tick_handler</span><span>()</span></span>{ <span>echo</span><span>"tick_hander() called.\n"</span>; } register_tick_function(<span>'tick_hander'</span>);</code>
可计时的低级语句有很多,register_tick_function()
后会调用一次周期事件,每条语句后会调用一次周期事件,花括号结束时会调用一次周期事件。
注意,PHP中表达式不能用逗号隔开,不然会出现语法错误。这点与C语言不同,刚注意到。
可以用encoding指令来对每段脚本指定其编码方式。用法如下:
<code><span>declare</span>(encoding = <span>'ISO-8859-1);</span></code>
return
如果是在全局范围中调用,则当前脚本文件中止运行。如果当前脚本文件是被include
或者require
,则控制交回调用文件。如果当前脚本时被include
的,则return
的值会被当作include
调用的返回值,那require
呢?
require
require
和include
几乎完全一样,除了处理失败的方式不同之外。
require
在出错时产生E_COMPILE_ERROR
级别的错误,脚本中止。而include
只产生警告E_WARNING
,脚本继续执行。
include
include
语句包含并运行指定文件,这里要注意一下指定文件的寻找次序。
include_path
会被完全忽略。include_path
指定的目录寻找。若没找到才在调用脚本文件所在目录和当前工作目录下寻找。那么问题来了,调用脚本文件所在目录和当前工作目录有什么区别呢?include
结构会发出一条警告,require
结构会发出一个致命错误。当一个文件被包含时,其中包含的代码继承了include
所在行的变量范围。从该处开始,被调用文件中定义的变量才可在调用文件中使用。当一个文件被包含时,语法解析器在目标文件的开头脱离PHP模式并进入HTML模式,当文件结尾回复。
对于返回值,在失败时include
返回FALSE
并且发出警告。成功的包含则返回1,除非在包含文件中另外给出了返回值。如果在包含文件中定义有函数,这些函数不管是在return
之前还是之后定义的,都可以独立在主文件中使用。
如果来自远程服务器的文件应该在远端运行而只输出结果,那用readfile()
函数更好。另一种将PHP文件包含到一个变量中的方法是用输出控制函数结合include
来捕获其输出。第一次遇到,比较陌生。下面这段代码能将脚本vars.php
中返回的内容输出。
<code><span><?php </span><span>$string</span> = get_include_contents(<span>'vars.php'</span>); <span><span>function</span><span>get_include_contents</span><span>(<span>$filename</span>)</span></span>{ <span>if</span>(is_file(<span>$filename</span>)) { ob_start(); <span>include</span><span>$filename</span>; <span>$contents</span> = ob_get_contents(); ob_end_clean(); <span>return</span><span>$contents</span>; } <span>return</span><span>false</span>; } <span>echo</span><span>$string</span>;</span></code>
因为include
和require
是一种特殊的语言结构,其参数不需要括号。如果文件被包含两次,PHP会发出致命错误,因为函数已经被定义。推荐使用include_once
。
require_once
require_once
语句和require
语句完全相同,唯一区别是,PHP会检查该文件是否已经被包含过,如果是则不会再次包含。
include_once
include_once
语句和include
语句类似,唯一区别是如果该文件已经被包含过,则不会再次包含。
goto
goto
操作符用于跳转到程序的另一位置,目标位置可以用目标名称加上冒号来标记。PHP中的goto
有一定限制,目标位置只能位于同一个文件和作用域。也就是说无法跳出一个函数或类方法,也无法跳入到任何循环或者switch
结构。
(全文完)
以上就介绍了浅谈PHP语音里的流程控制及实现方法,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。