2006/02/20

learn:php学习笔记 流程控制

tags:learn,php,学习笔记,流程控制
任何 PHP 脚本都是由一系列语句构成的。一条语句可以是一个赋值语句,一个函数调用,一个循环,甚至一个什么也不做的(空语句)条件语句。语句通常以分号结束。此外,还可以用花括号将一组语句封装成一个语句组。语句组本身可以当作是一行语句。
if
else
elseif
if ($a > $b) {
echo "a is bigger than b" ;
} elseif ($a == $b) {
echo "a is equal to b" ;
} else {
echo "a is smaller than b";
}
流程控制的替代语法
PHP 提供了一些流程控制的替代语法,包括 if,while,for,foreach 和 switch。替代语法的基本形式是把左花括号({)换成冒号(:),把右花括号(})分别换成 endif;,endwhile;,endfor;,endforeach; 以及 endswitch;。
if ($a == 5):
echo
"a equals 5";
echo
"...";
elseif (
$a == 6):
echo
"a equals 6";
echo
"!!!";
else:
echo
"a is neither 5 nor 6" ;
endif;
while
while (expr)
statement
do-while
do {
if (
$i < 5) {
echo
"i is not big enough";
break;
}
$i *= $factor;
if (
$i < $minimum_limit) {
break;
}
echo
"i is ok" ;

/* process i */

} while(0);
for
for (expr1; expr2; expr3)
statement
/* example 1 */

for ($i = 1; $i <= 10; $i++) {
echo
$i;
}

/* example 2 */

for ($i = 1; ; $i ++) {
if (
$i > 10) {
break;
}
echo
$i;
}

/* example 3 */

$i = 1 ;
for (;;) {
if (
$i > 10) {
break;
}
echo
$i;
$i++;
}

/* example 4 */

for ($i = 1; $i <= 10; echo $i, $i ++);
foreach
PHP 4 引入了 foreach 结构,和 Perl 以及其他语言很像。这只是一种遍历数组简便方法。foreach 仅能用于数组,当试图将其用于其它数据类型或者一个未初始化的变量时会产生错误。有两种语法,第二种比较次要但却是第一种的有用的扩展。
foreach (array_expression as $value)
statement
foreach (array_expression as $key => $value)
statement

第一种格式遍历给定的 array_expression 数组。每次循环中,当前单元的值被赋给 $value 并且数组内部的指针向前移一步(因此下一次循环中将会得到下一个单元)。

第二种格式做同样的事,只除了当前单元的键名也会在每次循环中被赋给变量 $key。

自PHP 5 起,还可能遍历对象。

注: 当 foreach 开始执行时,数组内部的指针会自动指向第一个单元。这意味着不需要在 foreach 循环之前调用 reset()。

注: 除非数组是被引用,foreach 所操作的是指定数组的一个拷贝,而不是该数组本身。因此数组指针不会被 each() 结构改变,对返回的数组单元的修改也不会影响原数组。不过原数组的内部指针的确在处理数组的过程中向前移动了。假定 foreach 循环运行到结束,原数组的内部指针将指向数组的结尾。

自 PHP 5 起,可以很容易地通过在 $value 之前加上 & 来修改数组的单元。此方法将以引用赋值而不是拷贝一个值。
$arr = array(1, 2, 3 , 4);
foreach (
$arr as & $value) {
$value = $value * 2;
}
// $arr is now array(2, 4, 6, 8)

此方法仅在被遍历的数组可以被引用时才可用(例如是个变量)。

注: foreach 不支持用"@"来抑制错误信息的能力。

$arr = array("one", "two", "three" );
reset($arr);
while (list(, $value) = each($arr )) {
echo "Value: $value<br>\n";
}
===
foreach ($arr as $value) {
echo "Value: $value<br />\n";
}

$arr = array("one", "two", "three" );
reset ($arr);
while (list($key, $value) = each( $arr)) {
echo "Key: $key; Value: $value<br />\n";
}
===
foreach ($arr as $key => $value ) {
echo "Key: $key; Value: $value<br />\n" ;
}


foreach ( array_keys ($myArray ) as $key ) {
$element =& $myArray[$key ];
...
}
foreach( $myArray as $key => $element ) {
$element =& $myArray[ $key ];
...
unset($element);
}
reset ( $myArray);
while ( list($key ) = each ( $myArray) ) {
$element =& $myArray[ $key];
...
unset($element );
}
break

break 结束当前 for,foreach,while,do-while 或者 switch 结构的执行。

break 可以接受一个可选的数字参数来决定跳出几重循环。

try {
$query = "SELECT myAttr FROM myTable";
$db = DB::connect ( $dbUrl);
if (DB::isError($db )) {
throw new
Exception ("Connection failed");
}
/* ... */
} catch (Exception $e) {
echo
"Error: " .$e->getMessage(). "</br>";
}
操作文件
$num = 0;
$file = fopen("input.txt", "r" );
while (!
feof($file)) {
$line = fgets($file, 80 );
for (
$i = 0; $i < strlen($line); ++$i) {
switch (
$line{$i}) {
// Arbitrary code here--the details aren't important
case 'i': // increment
echo ++$num." ";
break;
case
'f': // find factors
for ($factor = 1; $factor <= $num; ++$factor) {
if (
$num % $factor == 0) {
echo
"[".$factor."] " ;
// stop processing file if 7 is a factor
if ($factor == 7)
break
3; // break out of while loop
}
}
}
}
}
fclose($file);

continue

continue 在循环结构用用来跳过本次循环中剩余的代码并在条件求值为真时开始执行下一次循环。

注: 注意在 PHP 中 switch 语句被认为是可以使用 continue 的一种循环结构。

continue 接受一个可选的数字参数来决定跳过几重循环到循环结尾。

省略 continue 后面的分号会导致混淆。以下例子示意了不应该这样做。
for ($i = 0 ; $i < 5; ++$i ) {
if (
$i == 2)
continue
print
"$i ";
}
希望得到的结果是:0 1 3 4
可实际的输出是:2
因为 print() 调用的返回值是 int(1),看上去作为了上述可选的数字参数。
switch

switch 语句和具有同样表达式的一系列的 IF 语句相似。很多场合下需要把同一个变量(或表达式)与很多不同的值比较,并根据它等于哪个值来执行不同的代码。这正是 switch 语句的用途。

注: 注意和其它语言不同,continue 语句作用到 switch 上的作用类似于 break。如果在循环中有一个 switch 并希望 continue 到外层循环中的下一个轮回,用 continue 2。

为避免错误,理解 switch 是怎样执行的非常重要。switch 语句一行接一行地执行(实际上是语句接语句)。开始时没有代码被执行。仅当一个 case 语句中的值和 switch 表达式的值匹配时 PHP 才开始执行语句,直到 switch 的程序段结束或者遇到第一个 break 语句为止。如果不在 case 的语句段最后写上 break 的话,PHP 将继续执行下一个 case 中的语句段。
一个 case 的特例是 default。它匹配了任何和其它 case 都不匹配的情况,并且应该是最后一条 case 语句。
case 表达式可以是任何求值为简单类型的表达式,即整型或浮点数以及字符串。不能用数组或对象,除非它们被解除引用成为简单类型。
switch (TRUE) {
case in_array('rma_tac', $userGroup):
$home = "tac_home.php";
break;
case in_array('rma_vp', $userGroup):
$home = "vpmgr_home.php";
break;
case in_array('rma_mgr', $userGroup):
$home = "vpmgr_home.php";
break;
case in_array('rma_rma', $userGroup):
$home = "rma_home.php";
break;
}



declare 结构用来设定一段代码的执行指令。
declare (directive)     statement
directive 部分允许设定 declare 代码段的行为。目前只认识一个指令:ticks(更多信息见下面 ticks 指令)。
declare 代码段中的 statement 部分将被执行――怎样执行以及执行中有什么副作用出现取决于 directive 中设定的指令。
declare 结构也可用于全局范围,影响到其后的所有代码。
<?php
// these are the same:

// you can use this:
declare(ticks= 1
) {
// entire script here
}

// or you can use this:
declare(ticks=1
);
// entire script here
?>

Tick 是一个在 declare 代码段中解释器每执行 N 条低级语句就会发生的事件。N 的值是在 declare 中的 directive 部分用 ticks=N 来指定的。

在每个 tick 中出现的事件是由 register_tick_function() 来指定的。更多细节见下面的例子。注意每个 tick 中可以出现多个事件。

这个例子没有仔细阅读,等有需求的时候再看吧

// A function that records the time when it is called
function profile($dump = FALSE
)
{
static
$profile
;

// Return the times stored in profile, then erase it
if ($dump
) {
$temp = $profile
;
unset(
$profile
);
return (
$temp
);
}

$profile[] = microtime
();
}

// Set up a tick handler
register_tick_function ("profile"
);

// Initialize the function before the declare block
profile
();

// Run a block of code, throw a tick every 2nd statement
declare( ticks =2
) {
for (
$x = 1 ; $x < 50; ++$x
) {
echo
similar_text(md5 ($x ), md5 ($x* $x )), "<br />;"
;
}
}

// Display the data stored in the profiler

这个例子评估"declare"中的 PHP 代码,每执行两条低级语句就记录一次时间。此信息可以用来找到一段特定代码中速度慢的部分。这个过程也可以用其它方法完成,但用 tick 更方便也更容易实现。

如果在一个函数中调用 return() 语句,将立即结束此函数的执行并将它的参数作为函数的值返回。 return() 也会终止 eval() 语句或者脚本文件的执行。

如果在全局范围中调用,则当前脚本文件中止运行。如果当前脚本文件是被 include() 的或者 require() 的,则控制交回调用文件。此外,如果当前脚本是被 include() 的,则 return() 的值会被当作 include() 调用的返回值。如果在主脚本文件中调用 return() ,则脚本中止运行。如果当前脚本文件是在 php.ini 中的配置选项 auto_prepend_file 或者 auto_append_file 所指定的,则此脚本文件中止运行。

更多信息见返回值。

注: 注意既然 return() 是语言结构而不是函数,仅在参数包含表达式时才需要用括号将其括起来。当返回一个变量时通常不用括号,也建议不要用,这样可以降低 PHP 的负担。

注: 当用引用返回值时永远不要使用括号,这样行不通。只能通过引用返回变量,而不是语句的结果。如果使用 return ($a); 时其实不是返回一个变量,而是表达式 ($a) 的值(当然,此时该值也正是 $a 的值)。

eval eval -- Evaluate a string as PHP code

mixed eval ( string code_str )

require() 语句包含并运行指定文件。
require() 和 include() 除了怎样处理失败之外在各方面都完全一样。 include() 产生一个警告而 require() 则导致一个致命错误。换句话说,如果想在丢失文件时停止处理页面,那就别犹豫了,用 require() 吧。include() 就不是这样,脚本会继续运行。同时也要确认设置了合适的include_path 。
include() 语句包含并运行指定文件。
寻找包含文件的顺序先是在当前工作目录的相对的 include_path 下寻找,然后是当前运行脚本所在目录相对的 include_path 下寻找。例如 include_path 是 .,当前工作目录是 /www/,脚本中要 include 一个 include/a.php 并且在该文件中有一句 include "b.php",则寻找 b.php 的顺序先是 /www/,然后是 /www/include/。如果文件名以 ../ 开始,则只在当前工作目录相对的 include_path 下寻找。
当一个文件被包含时,其中所包含的代码继承了 include 所在行的变量范围。从该处开始,调用文件在该行处可用的任何变量在被调用的文件中也都可用。不过所有在包含文件中定义的函数和类都具有全局作用域。
include_once()
require_once() 语句在脚本执行期间包含并运行指定文件。此行为和 require() 语句类似,唯一区别是如果该文件中的代码已经被包含了,则不会再次包含。
The include_once() 语句在脚本执行期间包含并运行指定文件。此行为和 include() 语句类似,唯一区别是如果该文件中的代码已经被包含了,则不会再次包含。如同此语句名字暗示的那样,只会包含一次。
注: 要注意 require_once() 和 include_once() 在大小写不敏感的操作系统中(例如 Windows)的行为可能不是所期望的。

没有评论: