php assert or,什么是PHP断言(assert)?该如何使用?
PHP 中的断言常用于调试,检查一个表达式或语句是否为 FALSE。本文带你重新认识 PHP assert() 函数的神通广大。
本文基于 PHP Version 7.1.28
一、什么是断言
编写程序时,常会做出一定的假设,那断言就是用来捕获假设的异常,我们也可以认为断言是异常的一种特殊形式。
断言一般用于程序执行结构的判断,不可让断言处理业务流程。用的最多的场景就是单元测试,一般的单元测试框架都采用了断言。assert(1 == 2);
// 运行结果:
// Warning: assert(): assert(1 == 2) failed in /Users/shocker/Desktop/demo.php on line 25
二、PHP中的断言
在 PHP 中,采用 assert()函数对表达式进行断言。// PHP 5assert ( mixed $assertion [, string $description ] ) : bool
// PHP 7assert ( mixed $assertion [, Throwable $exception ] ) : bool
四、传统的断言方式
参数 assertion 既支持表达式,也支持表达式字符串(某些特定的场景会用到,比如判断某个字符串表达式是否合法)
如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。assertion 是字符串的优势是当禁用断言时它的开销会更小,并且在断言失败时消息会包含 assertion 表达式。
断言这个功能应该只被用来调试。你应该用于完整性检查时测试条件是否始终应该为 TRUE,来指示某些程序错误,或者检查具体功能的存在(类似扩展函数或特定的系统限制和功能)。
断言不应该用于普通运行时操作,类似输入参数的检查。作为一个经验法则,在断言禁用时你的代码也应该能够正确地运行。
实例:function my_assert_handler($file, $line, $code, $desc){ echo "Assertion Failed:
File '{$file}'
Line '{$line}'
Code '{$code}'
Desc '{$desc}'
";
}
// 设置回调函数
assert_options(ASSERT_CALLBACK, 'my_assert_handler');
// 让一则断言失败
assert('1 == 2', '1 不可能等于 2');
运行结果:Assertion Failed:
File '/Users/shocker/Desktop/demo.php'
Line '29'
Code '1 == 2'
Desc '1 不可能等于 2'
五、支持异常的断言
在 PHP 7 中,assert() 是一个语言结构,允许在不同环境中生效不同的措施,具体可见zend.assertions配置。
使用示例:assert_options(ASSERT_EXCEPTION, 1);
// 在断言失败时产生异常
try {
// 用 AssertionError 异常替代普通字符串
assert(true == false, new AssertionError('True is not false!'));
} catch (Throwable $e) {
echo $e->getMessage();
}
运行结果:True is not false!
六、对断言行为进行控制
PHP 支持 assert_options() 函数对断言进行配置,也可用 ini 进行设置
以下配置中,常量标志用于 assert_options() 函数进行配置,ini 设置用于 ini_set() 函数设置,效果一样
zend.assertions 是个特殊的配置(PHP >= 7.0.0 支持),控制不同运行环境下断言的行为,仅可用 ini_set() 进行设置。并且,设置了1就不能再设置为-1,反之亦然,其他不受限。
1: 编译代码,并执行(开发模式)
0: 编辑代码,但运行时跳过
-1: 不编译代码(生产模式)
七、版本的不兼容
PHP >= 5.4.8,description 可作为第四个参数提供给 ASSERT_CALLBACK 模式里的回调函数
在 PHP 5 中,参数 assertion 必须是可执行的字符串,或者运行结果为布尔值的表达式
在 PHP 7 中,参数 assertion 可以是任意表达式,并用其运算结果作为断言的依据
在 PHP 7 中,参数 exception 可以是个 Throwable 对象,用于捕获表达式运行错误或断言结果为失败。(当然 assert.exception 需开启)
PHP >= 7.0.0,支持 zend.assertions、assert.exception 相关配置及其特性
PHP >= 7.2 版本开始,参数 assertion 不再支持字符串Deprecated: assert(): Calling assert() with a string argument is deprecated
八、应用场景
调试输出:
先看示例:assert('1 == 2', '1 不可能等于 2');
运行结果:Warning: assert(): 1 不可能等于 2: "1 == 2" failed in /Users/shocker/Desktop/demo.php on line 10
类似于:$expression = 1 == 2;
if (!($expression)) {
echo "1 不可能等于 2\n";
var_dump($expression);
echo __FILE__ . "\n";
}
但是,我们无法得知 $expression 的具体表达式,也无法得知具体的执行行数。
九、单元测试function arraySum(array $nums) {
$sum = 0; foreach ($nums as $n) {
$sum += $n;
} return $sum;
}
assert(arraySum([1, 2, 3]) == 6, 'arraySum() 测试不通过:');
assert(is_numeric(arraySum([1, 2, 3])), 'arraySum() 测试不通过:');
十、验证表达式
Tip:
PHP 7 开始,新增了 Error 类用于捕获 PHP 内置错误,包括语法错误。Error 与之前的 Exception 均继承自 Throwable,所以从 7.0.0 开始,Throwable 可以捕获一切错误和异常。
下例演示了如何验证某个字符串表达式是否为合法的 PHP 表达式:try {
assert('a +== 1');
} catch (Throwable $e) {
echo $e->getMessage(), "\n";
}
运行结果:Failure evaluating code:
a +== 1
十一、安全问题
假如是下列代码会有什么结果呢?function demo(){
file_put_contents('data.log', 'shockerli.net');
return true;
}
$func = $_GET["func"];
assert("$func()");
所以,对于 assert 函数,正常情况下是不建议用于生产环境的。
与 eval 一样会执行任何 PHP 代码,危害极大。这也是 PHP 从 7.2 开始废弃支持字符串表达式的原因
感谢您的阅读,如有错误请指出。
相了解更多相关问题请访问PHP中文网:PHP视频教程
php assert or,什么是PHP断言(assert)?该如何使用?相关推荐
- java断言assert初步使用:断言开启、断言使用
1 说明 java断言assert是jdk1.4引入的. jvm断言默认是关闭的. 断言可以局部开启的,如:父类禁止断言,而子类开启断言,所以一般说"断言不具有继承性". 断言只适 ...
- C语言断言assert()函数
文章目录 断言(assert)的用法 用法总结与注意事项 1)在函数开始处检验传入参数的合法性 2)每个assert只检验一个条件,因为同时检验多个条件时,如果断言失败,无法直观的判断是哪个条件失败 ...
- 断言(assert)详解
目录 一.assert定义 二.用法总结与注意事项 四.以下是使用断言的几个原则: 一.assert定义 我一直以为 assert 仅仅是个报错函数,事实上,它居然是个宏,并且作用并非"报错 ...
- python断言assert实例_Python断言assert的用法代码解析
在开发一个程序时候,与其让它运行时崩溃,不如在它出现错误条件时就崩溃(返回错误).这时候断言assert 就显得非常有用. python assert断言是声明布尔值必须为真的判定,如果发生异常就说明 ...
- Linux C 中断言assert()使用简介
assert()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行.如果表达式不为0,则继续执行后面的语句,它的作用是终止程序 ...
- python(11)-if语句,断言assert
分支语句if 1.if基本语法 2 if语句的嵌套 3 比较运算符号 4 逻辑运算符: 5 整数随机数初应用 6 tip 7.断言assert 1.if基本语法 if语句开发中的应用场景:如果条件成立 ...
- python断言assert实例_Python 拓展之断言(assert)
写在之前 大家好,这是首发在我公众号「Python空间」的第 60 篇文章,欢迎关注,期待和你的交流. 在昨天的文章中(零基础学习 Python 之处理异常)中学习了处理异常的正确姿势,今天我们继续来 ...
- 断言(Assert)与异常(Exception)
断言(Assert)与异常(Exception) 参考文章: (1)断言(Assert)与异常(Exception) (2)https://www.cnblogs.com/lionden/p/Asse ...
- java 断言 assert 初步使用:断言开启、断言使用
主要总结一下在eclipse中如何使用断言. (一)首先明确: java断言Assert是jdk1.4引入的. jvm 断言默认是关闭的. 断言只适用于复杂的调试过程. 断言一般用于程序执行结果的判断 ...
最新文章
- 死锁产生条件-互斥条件
- c++派生类的访问控制
- stm32 web 参数_老司机们都是怎么学习STM32的?
- oracle notes,Oracle Notes
- c语言中函数调用的原理
- recv原理、高阶版黏包解决方案、基于UDP的socket通信
- php生成 sku_高并发下,php与redis实现的抢购、秒杀功能
- zabbix计算型监控项函数last_zabbix 自定义key类型之计算(Calculated items)-阿里云开发者社区...
- 编码规范-html.md
- c语言数组电脑显示不出来,C语言有关结构数组的一个程序为什么运行什么结果都不显示?求助~...
- Google是如何赚钱的 -- 四年工作离别小结
- CentOS6.5 firefox安装flash插件
- 学有小成-php基础语法-06
- 2021年12月四六级考试成绩批量查询Java
- B 站顶流何同学对话苹果 CEO 库克
- pytorch训练时报input size错误问题
- 机器学习理论 之 经验风险最小化(Empirical Risk Minimization)
- ajax技术的实质是什么意思,什么是Ajax?Ajax的原理是什么?Ajax的核心技术是什么?Ajax的优缺点是什么?...
- “21 天好习惯”第一期-7
- 《Windows 8 权威指南》——2.4 Aero与Metro的触摸对比
热门文章
- android handler2--消息队列源码解析
- android常见布局整理
- 基于JAVA+SpringMVC+Mybatis+MYSQL的课堂考勤系统
- 基于JAVA+SpringMVC+Mybatis+MYSQL的学习资源交互系统
- 基于JAVA+SpringMVC+Mybatis+MYSQL的值班管理系统
- c语言二叉树的构造输出,C语言数据结构树状输出二叉树,谁能给详细的解释一下...
- post发送请求参数注意的问题
- string和wstring相互转换
- Android 面试题总结
- Linux的nat端口转换实例