declare
declare结构用来设定一段代码的执行指令。declare的语法和其他流程控制结构相似:
declare (directive)
statement
directive部分允许设定declare代码段的行为。
目前只认识三个指令:
ticks
encoding
strict_types
因为该指令是在文件编译时处理的,所以指令只接受字面量的值,无法使用变量和常量,如下:
// 有效
declare(ticks=1);
// 无效
const TICK_VALUE = 1;
declare(ticks=TICK_VALUE);
declare结构也可以用于全局范围,影响到其后的所有代码(但如果有 declare 结构的文件被其它文件包含,则对包含它的父文件不起作用)。
// 两者相等:
// 可以这样用:
declare(ticks=1) {
// 这里写完整的脚本
}
// 也可以这样用:
declare(ticks=1);
// 这里写完整的脚本
Tick(时钟周期)是一个在 declare 代码段中解释器每执行 N 条可计时的低级语句就会发生的事件。N 的值是在 declare 中的 directive 部分用 ticks=N 来指定的。
不是所有语句都可计时。通常条件表达式和参数表达式都不可计时。
在每个 tick 中出现的事件是由 register_tick_function() 来指定的。注意每个 tick 中可以出现多个事件。
declare(ticks=1);
function tick_handler(){
echo "tick_handler() called\n";
}
register_tick_function('tick_handler');
$a = 1;
if($a > 0){
$a += 2;
print($a);
}
结果:
如果ticks=3
declare(ticks=3);
function tick_handler(){
echo "tick_handler() called\n";
}
register_tick_function('tick_handler');
$a = 1;
if($a > 0){
$a += 2;
print($a);
}
Ticks的用法示例2:
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();
结果:
以下是转载
拿declare(ticks=1)来说,这句话主要作用有两种:
1.Zend引擎每执行一条低级语句就去执行一次register_tick_function()注册的函数。可以粗略的理解为每执行一句php代码(例如:$num=1;)就去执行下已经注册的tick函数。
一个用途就是控制某段代码执行时间,例如下面的代码虽然最后有个死循环,但是执行时间不会超过5秒。
declare (ticks=1);
// 开始时间
$time_start = time();
// 检查是否已经超时
function check_timeout(){
// 开始时间
global $time_start ;
// 5秒超时
$timeout = 5;
if (time()- $time_start > $timeout ){
exit ( "超时{
$timeout}秒\n" );
}
}
// Zend引擎每执行一次低级语句就执行一下check_timeout
register_tick_function( 'check_timeout' );
// 模拟一段耗时的业务逻辑
while (1){
$num = 1;
}
// 模拟一段耗时的业务逻辑,虽然是死循环,但是执行时间不会超过$timeout=5秒
while (1){
$num = 1;
}
结果:
5s后超时
2.declare(ticks=1);每执行一次低级语句会检查一次该进程是否有未处理过的信号,测试代码如下:
运行 php signal.php
然后CTL+c 或者 kill -SIGINT PID 会导致运行代码跳出死循环去运行pcntl_signal注册的函数,效果就是脚本exit打印“Get signal SIGINT and exi”退出
declare (ticks=1);
pcntl_signal(SIGINT, function (){
exit ( "Get signal SIGINT and exit\n" );
});
echo "Ctl + c or run cmd : kill -SIGINT " . posix_getpid(). "\n" ;
while (1){
$num = 1;
}