Scripts are composed of statements, and statements rely on process control to implement functions. This section mainly introduces the use of several keywords.
elseif
elseif
behaves exactly the same as else if
. If you use a colon to define the if/elseif
condition, you cannot use the two-word else if
, otherwise PHP will generate a parsing error.
<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>
Alternative syntax
The following keywords can use the alternative syntax of flow control. The basic form is to replace the left curly brace with a colon and the right curly brace with the following characters.
<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>
Attention! PHP does not support mixing the two syntaxes within the same control block.
do-while
This loop looks familiar at first glance, but some of its uses are overlooked.
The manual says that experienced C language users may be familiar with a different do-while
loop usage, which puts the statement inside do-while(0)
. This is the first time I have heard of this technique. It seems that I am still a novice in C language.
By the way, let’s search and sort out the benefits of this special usage of do-while(0)
.
break
to skip the remaining section of code. goto
statement. This post explains very well, the role of do{}while(0) - c++ - SegmentFault.
foreach
foreach
can only be applied to array and object traversal. The foreach
syntax structure provides a simple way to traverse an array. There are two syntaxes below.
<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>
To modify the value of an array element, you need to use reference assignment, which is achieved by adding &
before $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> }</code>
Attention! The $value
reference of the last element of the array will still be retained after the foreach
loop. It is recommended to use unset()
to destroy it.
list-each
In the sample program, a special traversal method was also found, tentatively called list-each
.
When foreach
starts executing, the pointer inside the array will automatically point to the first unit, so there is no need to call reset()
before the foreach
loop. But for list-each
in while
, the array internal pointer $arr
will always exist, so reset($arr)
is needed before the next loop.
<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>; }</code>
In the above code, the first reset
can be omitted, but the second reset
cannot be omitted.
list
PHP 5.5 adds the ability to iterate over an array of arrays and unpack nested arrays into loop variables. The number of cells in
<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>; }</code>
list()
can be less than that of the nested array, and the extra array cells will be ignored. If more, an error message will be issued.
break
break
is used to end the execution of the current for/foreach/while/do-while/switch
structure. break
can accept an optional numeric parameter to decide how many loops to break out of, but the parameter cannot be a variable.
break
This is the first time I encountered breaking out of multiple loops, so I wrote a small program to try it out.
<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>;</code>
I tried it in C language and got a syntax error.
continue
Similar to break
, continue
can also accept an optional numeric parameter to determine how many loops to skip to the end of the loop.
Attention! In PHP, the switch
statement is considered a loop structure that can use continue
. The
switch
manual says that PHP is different from other languages. The continue
statement acting on switch
is similar to break
. What does it mean?
switch/case
does a loose comparison ==
instead of a strict comparison ===
. In terms of efficiency, the condition in the switch
statement is only evaluated once and used to compare with each case
statement. case
Expression can be any expression that evaluates to a simple type, arrays or objects cannot be used. It is allowed to use a semicolon instead of a colon after a case
statement. The
declare
declare
structure is used to set the execution instructions of a piece of code. The syntax structure is as follows:
<code><span>declare</span>(directive) statement</code>
directive
allows you to set the behavior of the declare
code segment. Currently, only two commands are recognized: ticks
and encoding
. The declare
structure can also be used in global scope, affecting all code after expiration. But if a file with a declare
structure is included by other files, it will not work on the parent file that contains it.
Tick (clock cycle) is an event that occurs every time the interpreter executes N timeable low-level statements in the declare
code segment. The events that occur in each tick are specified by register_tick_function()
. The usage is roughly as follows.
<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>;</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> }</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>; }</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>; }</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>;</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>;</code>
因为include
和require
是一种特殊的语言结构,其参数不需要括号。如果文件被包含两次,PHP会发出致命错误,因为函数已经被定义。推荐使用include_once
。
require_once
require_once
语句和require
语句完全相同,唯一区别是,PHP会检查该文件是否已经被包含过,如果是则不会再次包含。
include_once
include_once
语句和include
语句类似,唯一区别是如果该文件已经被包含过,则不会再次包含。
goto
goto
操作符用于跳转到程序的另一位置,目标位置可以用目标名称加上冒号来标记。PHP中的goto
有一定限制,目标位置只能位于同一个文件和作用域。也就是说无法跳出一个函数或类方法,也无法跳入到任何循环或者switch
结构。
(全文完)
以上就介绍了浅谈PHP语音里的流程控制及实现方法,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。