脚本由语句构成,语句靠流程控制实现功能,这一节主要介绍了几个关键字的使用。

elseif

elseifelse if的行为完全一样,如果用冒号来定义if/elseif条件,那就不能用两个单词的else if,否则PHP会产生解析错误。

<?php
$a = 1;
$b = 2;
if($a > $b) :
echo "$a is greater than $b";
elseif($a == $b) :
echo "$a equals $b";
else :
echo "$a is neither greater than or equal to $b";
endif;

替代语法

下面的这些关键字可以使用流程控制的替代语法,基本形式是把左花括号换成冒号,右花括号换为下面的字符。

if - endif
while - endwhile
for - endfor
foreach - endforeach
switch - endswitch

注意!PHP不支持在同一控制块内混合使用两种语法。

do-while

这个循环乍看起来挺熟悉的,但是却忽略了它的某些用法。

手册中说,资深的C语言用户可能熟悉另一种不同的do-while循环用法,把语句放在do-while(0)之中。我竟然第一次听说有这种技巧,看来我还是C语言小白。

顺便搜索整理一下do-while(0)这种特殊用法的好处吧。

  1. 代码分块,比仅仅使用花括号更直观。
  2. 使用break跳过剩余的一段代码。
  3. 有利于宏定义函数,使用时句尾可以加分号,看起来更像函数调用。
  4. 块级作用域,避免变量名扩散到上层作用域。
  5. 变形的goto语句。

这个帖子讲的挺好的,do{}while(0) 的作用 - c++ - SegmentFault

foreach

foreach仅能够应用于数组和对象的遍历。foreach语法结构提供了遍历数组的简单方式,有下面两种语法。

foreach(array_expression as $value)
statement
foreach(array_expression as $key => $value)
statement

要修改数组元素的值需要使用引用赋值,通过在$value前加&实现。

<?php
$arr = array(1, 2, 3, 4);
foreach($arr as &$value) {
$value = $value * 2;
}
unset($value);
foreach($arr as $value) {
echo "$value "; // 2 4 6 8
}

注意!数组最后一个元素的$value引用在foreach循环之后仍会保留,建议使用unset()将其销毁。

list-each

在示例程序中,还发现了一种特殊的遍历方法,姑且称作list-each

foreach开始执行时,数组内部的指针会自动指向第一个单元,因此不需要在foreach循环之前调用reset()。但是对于while中的list-each,数组内部指针$arr会一直存在着,因此在下次循环前需要reset($arr)

<?php
$arr = array('one', 'two', 'three');
// reset($arr);
while(list($key, $value) = each($arr)) {
echo "Key: $key; Value: $value ";
}
reset($arr);
while(list($key, $value) = each($arr)) {
echo "Key: $key; Value: $value ";
}

在上面这段代码中,第一个reset可以省略,但第二个reset不能省。

list

PHP 5.5增添了遍历一个数组的数组的功能,并且把嵌套的数组解包到循环变量中。

<?php
$array = [
[1, 2],
[3, 4],
];
foreach($array as list($a, $b)) {
echo "A: $a; B: $b";
}

list()中的单元可以少于嵌套数组的,此时多出来的数组单元将被忽略。若多于,将发出错误信息。

break

break用来结束当前for/foreach/while/do-while/switch结构的执行。break可以接受一个可选的数字参数来决定跳出几重循环,但参数不能为变量。

break跳出多重循环还是第一次遇到,特意写了个小程序尝试了一下。

<?php
while(1) {
while(1) {
echo 'hello ';
break 2;
}
}
echo 'world';

特地在C语言里尝试了一下,提示语法错误。

continue

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

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

switch

手册中说,PHP和其它语言不同,continue语句作用到switch上的作用类似于break。这是什么意思呢?

switch/case做的是松散比较==,而不是严格比较===。效率方面,switch语句中条件只求值一次并用来和每个case语句比较。case表达式可以是任何求值为简单类型的表达式,不能用数组或对象。允许使用分号代替case语句后的冒号。

declare

declare结构用来设定一段代码的执行指令,语法结构如下:

declare(directive)
statement

directive部分允许设定declare代码段的行为,目前只认识两个命令:ticksencodingdeclare结构也可用于全局范围,影响到期后的所有代码。但如果有declare结构的文件被其它文件包含,则对包含它的父文件不起作用。

Tick(时钟周期)是一个在declare代码段中解释器每执行N条可计时的低级语句就会发生的事件。在每个tick中出现的事件由register_tick_function()来指定。用法大致如下。

declare(ticks = 1);
function tick_handler() {
echo "tick_hander() called.\n";
}
register_tick_function('tick_hander');

可计时的低级语句有很多,register_tick_function()后会调用一次周期事件,每条语句后会调用一次周期事件,花括号结束时会调用一次周期事件。

注意,PHP中表达式不能用逗号隔开,不然会出现语法错误。这点与C语言不同,刚注意到。

可以用encoding指令来对每段脚本指定其编码方式。用法如下:

declare(encoding = 'ISO-8859-1);

return

如果是在全局范围中调用,则当前脚本文件中止运行。如果当前脚本文件是被include或者require,则控制交回调用文件。如果当前脚本时被include的,则return的值会被当作include调用的返回值,那require呢?

require

requireinclude几乎完全一样,除了处理失败的方式不同之外。

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中返回的内容输出。

<?php
$string = get_include_contents('vars.php');
function get_include_contents($filename) {
if(is_file($filename)) {
ob_start();
include $filename;
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
return false;
}
echo $string;

因为includerequire是一种特殊的语言结构,其参数不需要括号。如果文件被包含两次,PHP会发出致命错误,因为函数已经被定义。推荐使用include_once

require_once

require_once语句和require语句完全相同,唯一区别是,PHP会检查该文件是否已经被包含过,如果是则不会再次包含。

include_once

include_once语句和include语句类似,唯一区别是如果该文件已经被包含过,则不会再次包含。

goto

goto操作符用于跳转到程序的另一位置,目标位置可以用目标名称加上冒号来标记。PHP中的goto有一定限制,目标位置只能位于同一个文件和作用域。也就是说无法跳出一个函数或类方法,也无法跳入到任何循环或者switch结构。

(全文完)

流程控制 - PHP手册笔记的更多相关文章

  1. No1_2. 流程控制_java学习笔记

    import java.util.Scanner; import java.lang.Math; public class HelloForWhile { /** * 文档注释,程序名称:HelloF ...

  2. Java学习笔记之:Java流程控制

    一.介绍 Java流程控制包括顺序控制.条件控制和循环控制. 顺序控制,就是从头到尾依次执行每条语句操作.条件控制,基于条件选择执行语句,比方说,如果条件成立,则执行操作A,或者如果条件成立,则执行操 ...

  3. 《Node.js In Action》笔记之流程控制

    转向Javascript后,开始学习了node.js,选择的第一本书是<Node.js in Action> 将近一个月时间,断断续续看完,选几个点做下笔记 1.实现串行化流程控制 var ...

  4. [原创]java WEB学习笔记43:jstl 介绍,core库详解:表达式操作,流程控制,迭代操作,url操作

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  5. [Java入门笔记] Java语言基础(四):流程控制

    流程控制指的是在程序运行的过程中控制程序运行走向的方式.主要分为以下几种: 顺序结构 顺序结构,顾名思义,是指程序从上往下逐步顺序执行.中间没有任何的判断和跳转. 分支结构 Java提供两种分支结构: ...

  6. 高性能JavaScript笔记二(算法和流程控制、快速响应用户界面、Ajax)

    循环 在javaScript中的四种循环中(for.for-in.while.do-while),只有for-in循环比其它几种明显要慢,另外三种速度区别不大 有一点需要注意的是,javascript ...

  7. JavaScript学习笔记——流程控制

    javascript流程控制流程:就是程序代码的执行顺序.流程控制:通过规定的语句让程序代码有条件的按照一定的方式执行. 一.顺序结构 按照书写顺序来执行,是程序中最基本的流程结构. 二.选择结构(分 ...

  8. [java学习笔记]java语言基础概述之运算符&程序流程控制&for循环嵌套

    一.运算符 算数运算符 +,-,*,/,%,++,-- 1.+,-,*,/ 整数除以整数的结果为舍弃了小数部分的整数. 2.%:取余 %左右都为正数,左边小于右边结果为左边值,如,4%5=4 %左边大 ...

  9. javascript笔记整理(流程控制)

    流程:就是程序代码的执行顺序 流程控制:通过规定的语句让程序代码有条件的按照一定的方式执行 1.顺序结构(按照书写顺序来执行,是程序中最基本的流程结构) 2.选择结构(分支结构.条件结构):根据给定的 ...

随机推荐

  1. R语言学习笔记(数据预处理)

    setwd("d:/r/r-data/")data=read.table("salary.txt",header=T)attach(data)mean(Sala ...

  2. WPF笔记(1.1 WPF基础)——Hello,WPF!

    原文:WPF笔记(1.1 WPF基础)--Hello,WPF! Example 1-1. Minimal C# WPF application// MyApp.csusing System;using ...

  3. jdk8预览

    原文:http://www.techempower.com/blog/2013/03/26/everything-about-java-8/ 1.接口增强 (1)接口可以定义static方法 java ...

  4. perl 爬取csdn

    <pre name="code" class="python">use LWP::UserAgent; use POSIX; use HTML::T ...

  5. 绘图工具graphviz学习使用

    画图工具: http://www.tuicool.com/articles/r2iAfa http://www.tuicool.com/articles/RjQfey 绘图工具graphviz学习使用 ...

  6. 【转】Android LCD(二):LCD常用接口原理篇

    关键词:android LCD TFT TTL(RGB)  LVDS  EDP MIPI  TTL-LVDS  TTL-EDP 平台信息:内核:linux2.6/linux3.0系统:android/ ...

  7. [转]Traceroute网络排障实用指南(2)

    五.优先级与限速 5.1 Traceroute延时判断影响因素 Traceroute延时包括三点: 探测包到达一个特定路由器的时间 路由器生成IPMI TTL Exceed的时间 ICMP TTL E ...

  8. php 中利用json_encode和json_decode传递包括特殊字符的数据

    </pre><span style="font-size:24px"></span><pre name="code" ...

  9. 自定义view(自定义view的时候,三个构造函数各自的作用)

    package com.timeshare.tmband.Utils; import android.content.Context; import android.content.res.Typed ...

  10. cc1plus: fatal error: emeralddb-pmdMain.d: No such file or directory

    签名autoscan, aclocal, config啥的都没错,最后make 报下面的错,查了各个文件没发现有啥问题,请哪位帮忙卡看 make[1]: Entering directory `/ro ...