PHP 易错点
PHP 内置回调事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# 程序结束(包含正常结束和异常结束)时,触发此回调
register_shutdown_function(function () {
// 获取上一个错误,如果是正常结束返回的是 NULL
$error = error_get_last();
});
# 注册 \Exception 抛出时的回调处理
set_exception_handler(function (\Exception $exception) {
});
# 注册 \Error 抛出时的回调处理
set_error_handler(function ($iErrNo, $sErrStr, $sErrFile, $iErrLine) {
});
# 注册类加载
spl_autoload_register(function ($sClassName) {
});
|
注册完,支持运行时移除的回调
restore_error_handler
1
2
3
4
5
6
7
8
|
function a() {}
function b() {}
// 注册错误处理函数 a
set_error_handler('a');
// 修改错误处理函数为 b
set_error_handler('b');
// 恢复为原来错误处理函数 a
restore_error_handler();
|
restore_exception_handler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<?php
function exception_handler_1(Exception $e)
{
echo '[' . __FUNCTION__ . '] ' . $e->getMessage();
}
function exception_handler_2(Exception $e)
{
echo '[' . __FUNCTION__ . '] ' . $e->getMessage();
}
set_exception_handler('exception_handler_1');
set_exception_handler('exception_handler_2');
restore_exception_handler();
throw new Exception('This triggers the first exception handler...');
// 输出结果:[exception_handler_1] This triggers the first exception handler...
?>
|
高手擅长回避的问题
非 0 即真
1
2
3
4
|
self::assertSame(7, 7 ?: 1);
self::assertSame(1, 0 ?: 1);
// 你是不是以为下面的结果是 1 啊
self::assertSame(-2, -2 ?: 1);
|
总结:
1
|
$var3 = (非 0 即真) ? $va1 : $val2;
|
知道了非 0 即真,那么下面的答案就简单了。
1
2
3
4
5
|
if (-1) {
var_dump(1);
} else {
var_dump(0);
}
|
输出:int(1)
PHP 8.0 终于对了
OPcache 和 OPcode 的关系
最近你是不是也被这个问题困惑,那我们一起来翻阅 PHP 手册来需求解答。
在 PHP 手册的 函数参考 > 影响 PHP 行为的扩展 > OPcache
有专业的解答。
OPcache 通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能, 存储预编译字节码的好处就是 省去了每次加载和解析 PHP 脚本的开销。
那么 OPcode 是什么?你还没解释。
什么,不是说了吗? OPcode 就是字节码,相当于 Java 开发中的 xxx.class,PHP 的 Zend VM 解析引擎就类似 Java 的 VM
说白了就是,用 OPcache 这个扩展来缓存 OPcode 到内存,从而来提高 PHP 的解析速度。
更多使用技巧请参考: 使用 OpCache 提升 PHP 性能
内存中的堆栈区别
很多是否还是会碰到堆栈,那堆栈是什么,区别又是什么,是时候花时间弄明白了。
栈 |
堆 |
大小 |
不大,最大也就10M |
手动释放内存 |
不需要,临时空间 函数退出后系统释放 |
存放数据 |
方法调用,所有局部变量和函数的参数 |
const 与 define 有何区别
我们知道 const 和 define 都可以定义全局常量,那么他们有和区别呢?
1
2
3
4
5
|
<?php
const VERSION = '3.2.3';
defined('ADDON_PATH') or define('ADDON_PATH', APP_PATH . 'Addon');
|
总结一下,就是,如果定义的常量没有其他常量条件限制,就使用const
常量定义语法,如果有条件限制,则使用宏定义define
来定义常量。
var_export 高级用法
高级应用,代码压缩。
字符串方法使用
strpos 字符串匹配
1
2
3
4
5
6
7
|
<?php
if (!strpos('hello', 'h')) {
exit('不存在 h');
} else {
exit('存在 h');
}
|
结果:不存在 h
原因:strpos('hello', 'h')
返回的索引是 0,由于弱类型,被当作 false 处理了。
1
2
3
4
5
6
7
|
<?php
if (false === strpos('hello', 'h')) {
exit('不存在 h');
} else {
exit('存在 h');
}
|
结果:存在 h