php的declare使用
declare是php的设置项,可以改变php运行的默认行为.declare(strict_types=1)
:启用严格类型检查模式,declare(encoding='UTF-8')
:这个指令用于设置脚本的默认字符编码。declare(ticks=1)
:信号处理器.
参考:
https://www.php.net/manual/zh/control-structures.declare.php
strict_types
严格模式,严格类型模式.
https://www.php.net/manual/zh/language.types.declarations.php#language.types.declarations.strict
默认转换为想要的标量.开启严格模式需要完全类型匹配.
调用方应用严格类型,而不是声明文件.
declare("strict_type=1");
function sum(int $a, int $b) {
return $a + $b;
}
sum(1,"2");// TypeError
sum(1,2);
encoding
指定脚本编码方式.
支持的編碼:
https://www.php.net/manual/zh/mbstring.supported-encodings.php
https://www.php.net/manual/zh/function.mb-language.php
用法:
比如代码是文件是GBK文件.
$str="a123王玕";
echo $str;
此时会语法错误,代码运行在GBK下,"玕"转换会出问题.
添加declare(encoding='gbk');
declare(encoding='gbk');
$str="a123王玕";
echo $str;
增加了declare(encoding='gbk');
发生了什么事情呢?
我们使用 mb_detect_encoding
来检查一类型.
默认字符集是CP936,即是GBK.
添加declare(encoding='gbk');
后变成了UTF-8.
发生了什么?为什么转成UTF-B了?不转成其他呢?
declare(encoding='gbk')'
表示当前脚本的编码格式,最后转换成默认字符.
上面代码相当于,不同所有字符编码都遍历转换.
define('Default_Charset','utf-8');
define('Declare_Encode','gbk');
$str="中国人123A";
$str=mb_convert_encoding($str,Default_Charset,Declare_Encode);
默认值由'internal-encoding'的配置决定,internal-encoding 默认值为空,为空时由 'default_charset' 配置决定,default_charset 默认为utf-8;所有默认转成utf-8;
[internal-encoding]
https://www.php.net/manual/zh/ini.core.php#ini.internal-encoding
[default-charset]
https://www.php.net/manual/zh/ini.core.php#ini.default-charset
; PHP internal character encoding is set to empty.
; If empty, default_charset is used.
; http://php.net/internal-encoding
; internal_encoding = ""
; PHP's default character set is set to UTF-8.
; http://php.net/default-charset
;default_charset = ""
declare(encoding)依赖 [zend.multibyte]
和 zend.script_encoding
配置.
zend.multibyte= On 时支持每个文件单独配置那编码.
依赖mbstring. 默认是 Off;
zend.script_encoding 依赖 zend.multibyte 开关,如果设置,文件头部没设置encoding,则使用默认.
; If enabled, scripts may be written in encodings that are incompatible with
; the scanner. CP936, Big5, CP949 and ⇧_JIS are the examples of such
; encodings. To use this feature, mbstring extension must be enabled.
; Default: Off
zend.multibyte = On
; Allows to set the default encoding for the scripts. This value will be used
; unless "declare(encoding=...)" directive appears at the top of the script.
; Only affects if zend.multibyte is set.
; Default: ""
zend.script_encoding = "utf-8"
影响encoding参数有:
echo 'charset:',ini_get('default_charset').PHP_EOL;
echo 'internal:',mb_internal_encoding().PHP_EOL;
echo 'language:',mb_language().PHP_EOL;// 默认: neutral
echo 'multibyte:',var_dump(ini_get('zend.multibyte'));
echo 'script_encoding:',var_dump(ini_get('zend.script_encoding'));
注意:
- 和严格模式不一样,encoding 以代码所在的文件为准.
严格模式以调用方为准. - opcache会缓存编码后的代码,修改配置后需要清空缓存.
ticks
时钟周期.
一般和 register_tick_function()
配合使用.
指每执行一条php语句,调用一次 register_tick_function
.
下面示例,每秒执行ticks=1
条语句.
条件语句不执行.
<?php
$a=1;
// 上面不执行
register_tick_function(function(){
global $n;
$a=2;
// 里面代码不触发
echo 'n:',++$n.PHP_EOL;
sleep(1);
});
declare(ticks=1);// 从这里开始 1
$a=1; // 2
// 注释 不执行
// 函数声明不执行
function f(){
$c=1; // 4,7
echo $c;//5,8
}
$f=f(); // 3
if(true) { // 条件语句不执行
f(); // 6
}// 不执行
exit();// 不执行
常见用途:
限制循环次数或最大执行时间.
例:
<?php
$n=0;
$t=time();
register_tick_function(function()use(&$n,$t){
// 大于10次退出
if(++$n>10){
echo 'maxNum:',$n;
exit;
}
// 大于10秒退出
if(time() -$t >5){
echo 'maxTime:',time()-$t;
exit;
}
});
declare(ticks=2);
while(true){
echo 1;
sleep(1);
}
定时器:
<?php
$n=0;
$t=time();
pcntl_signal(SIGALRM,function()use(&$n,$t){
echo '执行定时器,耗时:',time()-$t,PHP_EOL;
});
declare(ticks=1); // 每执行一条语句,检查一下时钟
pcntl_alarm(1);// 定时1秒后执行
sleep(3);// 虽然过了3秒,但没有代码执行,定时器不触发
定时为1秒
当ticks=1时,1秒后就触发.
当ticks=10时,9秒后才触发.
有个问题就是,就是实际上每执行一条php低语句都要检测一下.
如果代码量很大,虽然是空检测但是性能肯定会影响.
测试100w次性能对比.
虽然注册空函数性能差异,相差6倍多.
使用 "pcntl_signal_dispatch" 代替 tick
<?php
$n=0;
$t=microtime(true);
pcntl_signal(SIGALRM,function()use(&$t,&$n){
$endTime=microtime(true);
$time=round($endTime-$t,4);
echo '执行定时器,耗时:',$time,',n:',$n,PHP_EOL;
exit;
});
pcntl_alarm(2);// 定时N秒后执行
//declare(ticks=1); // 每N条执行,检查时钟
while(true){
pcntl_signal_dispatch();
$n++;
}
// tick: 2.0012,n:22930565
// dispatch: 2.0051,n:39798631
原作者:阿金
本文地址:https://hi-arkin.com/archives/php-declare.html