【php手册:流程控制】declare,return , require , include,goto,declarerequire
declare
declare 结构用来设定一段代码的执行指令。
declare 的语法:
declare (directive)
statement
directive 部分允许设定 declare 代码段的行为。
目前只认识两个指令:ticks , encoding( PHP 5.3.0 )。
declare 代码段中的 statement 部分将被执行——怎样执行以及执行中有什么副作用出现取决于 directive 中设定的指令。
declare 结构也可用于全局范围,影响到其后的所有代码(但如果有 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
?>
Ticks
Tick(时钟周期)是一个在 declare 代码段中解释器每执行 N 条可计时的低级语句就会发生的事件。N 的值是在 declare 中的 directive 部分用 ticks=N 来指定的。
通常条件表达式和参数表达式都不可计时。
在每个 tick 中出现的事件是由 register_tick_function() 来指定的。
Example #1 Tick 的用法示例
<?php
declare(ticks=1);
// A function called on each tick event
function tick_handler()
{
echo "tick_handler() called\n";
}
register_tick_function('tick_handler');
$a = 1;
if ($a > 0) {
$a += 2;
print($a);
}
?>
Example #2 Ticks 的用法示例
<?php
function tick_handler()
{
echo "tick_handler() called\n";
}
$a = 1;
tick_handler();
if ($a > 0) {
$a += 2;
tick_handler();
print($a);
tick_handler();
}
tick_handler();
?>
Encoding
对每段脚本指定其编码方式。
Example #3 对脚本指定编码方式
<?php
declare(encoding='ISO-8859-1');
// code here
?>
declare(encoding=’编码的值’) {} 将在与命名空间结合时产生解析错误
在 PHP 5.3 中,不指定 –enable-zend-multibyte,忽略declare 中的 encoding 值
不用 phpinfo(), PHP 不显示是否在编译时指定了 –enable-zend-multibyte。
在PHP 7中,<?php declare(encoding =’…’);如果Zend Multibyte关闭,抛出一个E_WARNING。
return
如果在全局范围中调用,则当前脚本文件中止运行。
如果当前脚本文件是被 include 的或者 require 的,则控制交回调用文件。
如果当前脚本是被 include 的,则 return 的值会被当作 include 调用的返回值。
如果在主脚本文件中调用 return,则脚本中止运行。
Note: return 是语言结构而不是函数,因此其参数没有必要用括号将其括起来。
通常不用括号,可以降低 PHP 的负担。
Note: 如果没有提供参数,则一定不能用括号,此时返回 NULL。
如果调用 return 时加上了括号却又没有参数会导致解析错误。
Note: 当用引用返回值时永远不要使用括号,这样行不通。
只能通过引用返回变量,而不是语句的结果。
对于那些认为在脚本中使用return的人来说,和使用exit注意一样:使用return只是退出当前脚本的执行,exit是退出整个执行。
a.php
<?php
include("b.php");
echo "a";
?>
b.php
<?php
echo "b";
return;
?>
(executing a.php:) will echo "ba".
whereas (b.php modified):
a.php
<?php
include("b.php");
echo "a";
?>
b.php
<?php
echo "b";
exit;
?>
(executing a.php:) will echo "b".
请注意,由于PHP在运行文件之前处理文件,即使未执行该文件,在包含文件中定义的任何函数仍然可用。
a.php
<?php
include 'b.php';
foo();
?>
b.php
<?php
return;
function foo() {
echo 'foo';
}
?>
Executing a.php will output "foo".
即使PHP允许您在全局范围内使用“return”,设计也是非常糟糕的。
require(include)
【以include为例,对requere也适用】
require 在出错时产生 E_COMPILE_ERROR 级别的错误,即导致脚本中止;
include 只产生警告(E_WARNING),脚本会继续运行。
发出警告的原理:被包含文件先按参数给出的路径寻找,如果没有给出目录(只有文件名)时则按照 include_path 指定的目录寻找。如果在 include_path 下没找到该文件则 include 最后才在调用脚本文件所在的目录和当前工作目录下寻找。如果最后仍未找到文件则 include 结构会发出一条警告。而require会发出一个致命错误。
如果定义了路径include_path 会被完全忽略。
当一个文件被包含时,其中所包含的代码继承了 include 所在行的变量范围。从该处开始,调用文件在该行处可用的任何变量在被调用的文件中也都可用。不过所有在包含文件中定义的函数和类都具有全局作用域。
当使用require时是语句不是函数,即写成require 'somefile.php';
,而没必要加括号:require('somefile.php');
Be carfull if you have a newline or blank space befor your php tags in the included/required file it will read as html and outputed.
If your running your output through javascript string evaluations which would be sensitive to newlines/white spaces be carfull that the first chars in the file are the php tages eg <?php
Example #1 基本的 include 例子
vars.php
<?php
$color = 'green';
$fruit = 'apple';
?>
test.php
<?php
echo "A $color $fruit"; // A
include 'vars.php';
echo "A $color $fruit"; // A green apple
?>
include 在调用文件中的一个函数里,则被调用的文件中变量将遵循该函数的变量范围(魔术常量例外,它们在发生包含前已被解析器处理)
Example #2 函数中的包含
<?php
function foo()
{
global $color;
include 'vars.php';
echo "A $color $fruit";
}
/* vars.php is in the scope of foo() so *
* $fruit is NOT available outside of this *
* scope. $color is because we declared it *
* as global. */
foo(); // A green apple
echo "A $color $fruit"; // A green
?>
当一个文件被包含时,语法解析器在目标文件的开头脱离 PHP 模式并进入 HTML 模式,到文件结尾处恢复。
如果“URL fopen wrappers”在 PHP 中被激活(默认配置),可以用 URL指定要被包含的文件。
如果目标服务器将目标文件作为 PHP 代码解释,则可以用适用于 HTTP GET 的 URL 请求字符串来向被包括的文件传递变量。
严格的说这和包含一个文件并继承父文件的变量空间并不是一回事;该脚本文件实际上已经在远程服务器上运行了,而本地脚本则包括了其结果。
注意:Windows 版本的 PHP 在 4.3.0 版之前不支持通过此函数访问远程文件
Example #3 通过 HTTP 进行的 include
<?php
/* This example assumes that www.example.com is configured to parse .php *
* files and not .txt files. Also, 'Works' here means that the variables *
* $foo and $bar are available within the included file. */
// Won't work; file.txt wasn't handled by www.example.com as PHP
include 'http://www.example.com/file.txt?foo=1&bar=2';
// Won't work; looks for a file named 'file.php?foo=1&bar=2' on the
// local filesystem.
include 'file.php?foo=1&bar=2';
// Works.
include 'http://www.example.com/file.php?foo=1&bar=2';
$foo = 1;
$bar = 2;
include 'file.txt'; // Works.
include 'file.php'; // Works.
?>
返回值:
失败时 include 返回 FALSE 并且发出警告。
成功的包含则返回 1,除非在包含文件中另外给出了返回值。
可以在被包括的文件中使用 return 语句来终止该文件中程序的执行并返回调用它的脚本。同样也可以从被包含的文件中返回值。可以像普通函数一样获得 include 调用的返回值。
不过这在包含远程文件时却不行,除非远程文件的输出具有合法的 PHP 开始和结束标记(如同任何本地文件一样)。可以在标记内定义所需的变量,该变量在文件被包含的位置之后就可用了。
因为 include 是一个特殊的语言结构,其参数不需要括号。在比较其返回值时要注意。
Example #4 比较 include 的返回值
//index2.php
<?php
$color = 'green';
$fruit = 'apple';
//return 2 调用文件的返回值将变为 int(2)
?>
<?php
// won't work
if (include('index2.php') == 1) {
echo 'OK';
}
// works
if ((include 'index2.php') == 1) {
echo 'OK';
}
//var_dump(include 'index2.php');
?>
如果在包含文件中定义有函数,这些函数不管是在 return 之前还是之后定义的,都可以独立在主文件中使用。
include_once(require_once)
【include_once为例,也适用require_once】
include_once 语句在脚本执行期间包含并运行指定文件。
与include 语句区别 : 如果该文件中已经被包含过,则不会再次包含。只会包含一次。
用于在脚本执行期间同一个文件只被包含一次以避免函数重定义,变量重新赋值等问题。
Example #1 include_once 在 PHP 4 运行于不区分大小写的操作系统中(例如 Windows)
<?php
include_once "a.php"; // 这将包含 a.php
include_once "A.php"; // 这将再次包含 a.php!(仅 PHP 4)
//此行为在 PHP 5 中修改
?>
Example:
<?php
var_dump(include_once 'fakefile.ext'); // bool(false)
var_dump(include_once 'fakefile.ext'); // bool(true)
/*This is because according to php the file was already included once (even though it does not exist).
php 5.0 以上都为false
*/
?>
goto
作用:用来跳转到程序中的另一位置。
语法:
goto tName;
tName : statement;
目标位置用目标名称加上冒号来标记,而跳转指令是 goto 之后接上目标位置的标记。
限制:
目标位置只能位于同一个文件和作用域
也就是说无法跳出一个函数或类方法,也无法跳入到另一个函数。
也无法跳入到任何循环或者 switch 结构中。
可以跳出循环或者 switch
Example #1 goto 示例
<?php
goto moon;
echo '1';//被忽略
moon:
echo '2';//输出2
?>
Example #2 goto 跳出循环示例
<?php
for($i=0,$j=50; $i<100; $i++) {
while($j--) {
if($j==17) goto end;
}
}
echo "i = $i";//被忽略
end:
echo 'j hit 17';//输出
?>
Example #3 跳入循环无效
<?php
goto loop;
for($i=0,$j=50; $i<100; $i++) {
while($j--) {
loop:
}
}
echo "$i = $i";
/*
输出Fatal error: 'goto' into loop or switch statement is disallowed inscript on line 2
*/
?>
大神:goto 循环输出
<?php
$headers = Array('subject', 'bcc', 'to', 'cc', 'date', 'sender');
$position = 0;
hIterator: {
$c = 0;
echo $headers[$position] . PHP_EOL;
cIterator: {
echo ' ' . $headers[$position][$c] . PHP_EOL;
if(!isset($headers[$position][++$c])) {
goto cIteratorExit;
}
goto cIterator;
}
cIteratorExit: {
if(isset($headers[++$position])) {
goto hIterator;
}
}
}
?>
PHP之友评论