PHP中断言函数的使用详解

原来一直以为断言相关的函数是 PHPUnit 这些单元测试组件提供的,在阅读手册后才发现,这个 assert() 断言函数是 PHP 本身就自带的一个函数。也就是说,我们在代码中进行简单的测试的时候是不需要完全引入整个单元测试组件的。

assert() 断言函数

assert(1==1);

assert(1==2);
// assert.exception = 0 时,Warning: assert(): assert(1 == 2)
// assert.exception = 1 时,Fatal error: Uncaught AssertionError: 验证不通过

很明显,第二段代码无法通过断言验证。这时,PHP 就会返回一个警告或者异常错误。为什么有可能是两种错误形式呢?当我们设置 php.ini 中的 assert.exception 为 off 或者 0 时,也就是关闭这个参数的能力时,程序就会以 PHP5 的形式依然返回一个警告,就像上面代码中的注释一样。同时,通过 try...catch 也无法进行异常的捕获了。这个参数其实就是控制是否以正宗的异常对象进行抛出。如果保持这个参数为默认情况也就是设置为 on 或者 1 的话,就会直接抛出异常,程序中止。

从上述代码可以看出,断言的第一个参数是一个表达式,而且是需要一个返回 bool 类型对象的表达式。如果我们传递的是一个字符串或者一个数字呢?

// 设置 assert.exception = 0 进行多条测试

assert(" ");
// Deprecated: assert(): Calling assert() with a string argument is deprecated
// Warning: assert(): Assertion " " failed

assert("1");
// Deprecated: assert(): Calling assert() with a string argument is deprecated

assert(0);
// Warning: assert(): assert(0) failed

assert(1);

assert("1==2");
// Deprecated: assert(): Calling assert() with a string argument is deprecated
// Warning: assert(): Assertion "1==2" failed

很明显第一个参数的表达式会进行类型强制转换,但是字符串类型会多出一个过时提醒,表明给 assert() 函数传递字符串类型的表达式类型已经过时了。当前的测试版本是 7.3 ,在将来可能就会直接报中止运行的错误或异常了。主要问题在于,如果传递的字符串本身也是一个表达式的话,会以这个表达式的内容为基础进行判断,这样很容易产生歧义,就像最后一段代码一样。当然,已经过时的使用方式还是不推荐的,这里仅是做一个了解即可。

接下来我们看一下 assert() 函数的其他参数,它的第二个参数是两种类型,要么给一个字符串用来定义错误的信息,要么给一个 异常类 用于抛出异常。

assert(1==1, "验证不通过");

assert(1==2, "验证不通过");
// Warning: assert(): 验证不通过 failed

如果直接给的一个字符串,那么在警告的提示信息中,显示的就是我们定义的这个错误信息的内容。这个非常好理解。

// 注意 assert.exception 设置不同的区别

assert(1==1,  new Exception("验证不通过"));

assert(1==2,  new Exception("验证不通过"));
// assert.exception = 1 时,Fatal error: Uncaught Exception: 验证不通过
// assert.exception = 0 时,Warning: assert(): Exception: 验证不通过

当然,我们也可以给一个 异常类 让断言抛出一个异常。在默认情况下,这个异常的抛出将中止程序的运行。也就是一个正常的异常抛出流程,我们可以使用 try...catch 进行异常的捕获。

try{
    assert(1==2,  new Exception("验证不通过"));
}catch(Exception $e){
    echo "验证失败!:", $e->getMessage(), PHP_EOL;
}
// 验证失败!:验证不通过

另外还有一个参数会对断言的整体运行产生影响,那就是 php.ini 中的 zend.assertions 参数。它包含三个值:

  • 1,生成并执行代码,一般在测试环境使用
  • 0,生成代码但是在运行时会路过
  • -1,不生成代码,一般在正式环境使用

这个参数大家可以自行配置测试,默认的 php.ini 中它的默认值是 1 ,也就是正常的执行 assert() 函数。

assert_options() 及相对应的 php.ini 中的参数配置

PHP 中的断言功能还为我们提供了一个 assert_options() 函数,用于方便地设置和获取一些和断言能力有关的参数配置。它能够设置的断言标志包括:

标志 | INI设置 | 默认值 | 描述

  • | :-: | :-: | -:

ASSERT_ACTIVE | assert.active | 1 | 启用 assert() 断言 ASSERT_WARNING | assert.warning | 1 | 为每个失败的断言产生一个 PHP 警告(warning) ASSERT_BAIL | assert.bail | 0 | 在断言失败时中止执行 ASSERT_QUIET_EVAL | assert.quiet_eval | 0 | 在断言表达式求值时禁用 error_reporting ASSERT_CALLBACK | assert.callback | (NULL) | 断言失败时调用回调函数

这些参数的含义都非常好理解,大家可以自己测试一下。我们就来看一下最后一个 ASSERT_CALLBACK 的作用。其实它的说明也非常清楚,就是断言失败的情况下就进入到这个选项定义的回调函数中。

assert_options(ASSERT_ACTIVE, 1);
assert_options(ASSERT_WARNING, 1);
assert_options(ASSERT_BAIL, 1);

assert_options(ASSERT_CALLBACK, function($params){
    echo "====faild====", PHP_EOL;
    var_dump($params);
    echo "====faild====", PHP_EOL;
});

assert(1!=1);
// ====faild====
// string(105) ".../source/一起学习PHP中断言函数的使用.php"
// ====faild====

当断言失败的时候,我们就进入了回调函数中,在回调函数直接简单的打印了传给回调函数的参数内容。可以看出,这个回调函数里面传递过来的是无法通过断言的文件信息。

总结

学习掌握一下断言函数的使用及配置,可以为我们将来学习 PHPUnit 单元测试打下基础,当然,本身这个能力的东西就不是很多,大家记住就好啦!

测试代码:

github.com/zhangyue050…

以上就是PHP中断言函数的使用详解的详细内容,更多关于PHP中断言函数的使用的资料请关注我们其它相关文章!

(0)

相关推荐

  • PHP危险函数禁用深入详解

    error_log() 功能描述:将错误信息发送到指定位置(文件).  安全备注:在某些版本的 PHP 中,可使用 error_log() 绕过 PHP safe mode, 执行任意命令.  危险等级:低 phpinfo() 功能描述:输出 PHP 环境信息以及相关的模块.WEB 环境等信息.  危险等级:中 scandir()  功能描述:列出指定路径中的文件和目录.  禁用建议:不建议禁用,因为thinkphp框架需要调用. 危险等级:中 syslog()  功能描述:可调用 UNIX 系

  • php中使用array_filter()函数过滤数组实例讲解

    在数组中元素的过滤上,有一种方法比较特殊,结合了回调函数的使用,通过键值来与函数进行对应.相信说到这里很多人对于这种函数方法已经很好奇了,它就是array_filter() 函数的使用.接下来我们对该函数的定义.语法.参数.返回值.实例进行全面的介绍,具体过滤方法展现如下. 1.定义 array_filter用回调函数处理数组中的各个元素. 重点在于过滤(而不是新增)某个元素,当你处理到一个元素时,如果返回了false,那么这个元素将会被过滤掉.PS:保持了原来的索引. 2.语法 array a

  • 详解各种PHP函数漏洞

    1.MD5 compare漏洞 PHP在处理哈希字符串时,会利用"!="或"=="来对哈希值进行比较,它把每一个以"0E"开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以"0E"开头的,那么PHP将会认为他们相同,都是0. 常见的payload有 0x01 md5(str) QNKCDZO 240610708 s878926199a s155964671a s214587387a s214587387

  • 正则表达式之零宽断言实例详解【基于PHP】

    本文实例讲述了正则表达式之零宽断言.分享给大家供大家参考,具体如下: 前言 之前我曾写了一篇关于正则表达式的文章(http://www.jb51.net/article/111359.htm) 在该文章中详细介绍了正则,但是关于零宽断言介绍却是很少提及到.现在将该内容补充一下.在本文中,主要解决如下问题: ① 什么是零宽断言,为什么要使用零宽断言 ② 怎样使用零宽断言 概念 零宽断言,大多地方这样定义它,用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像 \b ^ $ \<

  • PHP执行系统命令函数实例讲解

    命令注入 命令注入(Command Injection),对一些函数的参数没有做过滤或过滤不严导致的,可以执行系统或者应用指令(CMD命令或者 bash 命令)的一种注入攻击手段. 常见的执行系统命令的函数有 system() passthru() exec() shell_exec() popen() proc_open() pcntl_exec() system()函数 string system ( string $command [, int &$return_var ] ) $comm

  • php bcdiv和bcmul 函数的怪异现象

    一.简介 我要实现这样一个表达式 z=总奖金 n=总名数 i=自己的排民 ((n-i+1)/(1+2+3+-n))*z 这是一个分配奖金的式子.我试着用php的bc函数进行操作发现以下两种写法得出不一样的结果 表达式1: a r r [ arr[ arr[i]=bcmul(bcdiv((51- i ) , i), i),num,2), r e w a r d [ ′ L e a d e r b o a r d ′ ] , 0 ) ; 表 达 式 2 : reward['Leaderboard']

  • PHP超级全局变量、魔术变量和魔术函数汇总整理

    PHP在设计的时候已经预定义了9个超级全局变量.8个魔术变量和13魔术函数,这些变量和函数可以在脚本的任何地方不用声明就可以使用. 在PHP开发会频繁的使用这些变量和函数,这些变量和函数可以方便的帮我们解决很多问题.下面详细的讲解下PHP中的超级全局变量.魔术变量和魔术函数. PHP超级全局变量(9个) $GLOBALS:储存全局作用域中的变量 $_SERVER:获取服务器相关信息 $_REQUEST:获取POST和GET请求的参数 $_POST:获取表单的POST请求参数 $_GET:获取表单

  • php array_map()函数实例用法

    有时候我们想要对数组里的元素进行改变,不过在函数的选择上犯了难题.本篇带来的是array_map函数,对于数组中元素的值进行调整,然后再返回新的数组,处理数组的数量上也不止一个.下面我们就array_map()函数的说明.语法.参数.返回值.实例带来详解. 1.说明 array_map用回调函数处理数组中的各个元素. 在函数中你可以改变各个元素的值,重点在你需要什么样的值就返回什么样的值,保持索引. 可以一次性处理多个数组.但是数组的数量应该与回调函数的参数保持一致 2.语法 array_map

  • python如何调用php文件中的函数详解

    前言 python调用php代码实现思路:php文件可通过在terminal中使用php命令行进行调用,因此可使用python开启子进程执行命令行代码.函数所需的参数可通过命令行传递. 测试环境 1.操作系统:macos10.13.2 2.php版本:PHP 7.1.7(mac自带) 3.python版本:python3.6.0 4.python库:subprocess 调用php函数 php命令行调用php文件中的函数 php文件:test_hello.php <?php function h

  • PHP中断言函数的使用详解

    原来一直以为断言相关的函数是 PHPUnit 这些单元测试组件提供的,在阅读手册后才发现,这个 assert() 断言函数是 PHP 本身就自带的一个函数.也就是说,我们在代码中进行简单的测试的时候是不需要完全引入整个单元测试组件的. assert() 断言函数 assert(1==1); assert(1==2); // assert.exception = 0 时,Warning: assert(): assert(1 == 2) // assert.exception = 1 时,Fata

  • Java 中synchronize函数的实例详解

    Java 中synchronize函数的实例详解 java中的一个类的成员函数若用synchronized来修饰,则对应同一个对象,多个线程像调用这个对象的这个同步函数时必须等到上一个线程调用完才能由下一个线程调用. 那么如果一个类同时有两个成员函数是由synchronized修饰如代码所示,对与同一个对象,是否可以在两个线程运行时,一个调用funcA,同时另一个调用funcB? Mysyn是这样一个类,如果我有两个线程,一个在run方法中先运行funcA再运行funcB,另一个线程在run方法

  • 对pandas中apply函数的用法详解

    最近在使用apply函数,总结一下用法. apply函数可以对DataFrame对象进行操作,既可以作用于一行或者一列的元素,也可以作用于单个元素. 例:列元素 行元素 列 行 以上这篇对pandas中apply函数的用法详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们. 您可能感兴趣的文章: 浅谈Pandas中map, applymap and apply的区别

  • mysql中find_in_set()函数的使用详解

    首先举个例子来说: 有个文章表里面有个type字段,它存储的是文章类型,有 1头条.2推荐.3热点.4图文等等 . 现在有篇文章他既是头条,又是热点,还是图文,type中以 1,3,4 的格式存储.那我们如何用sql查找所有type中有4的图文类型的文章呢?? 这就要我们的 find_in_set 出马的时候到了.以下为引用的内容: select * from article where FIND_IN_SET('4',type) --------------------------------

  • PyTorch中topk函数的用法详解

    听名字就知道这个函数是用来求tensor中某个dim的前k大或者前k小的值以及对应的index. 用法 torch.topk(input, k, dim=None, largest=True, sorted=True, out=None) -> (Tensor, LongTensor) input:一个tensor数据 k:指明是得到前k个数据以及其index dim: 指定在哪个维度上排序, 默认是最后一个维度 largest:如果为True,按照大到小排序: 如果为False,按照小到大排序

  • 对tensorflow 中tile函数的使用详解

    tensorflow中tile是用来复制tensor的指定维度,具体看下面的代码: import tensorflow as tf a = tf.constant([[1, 2], [3, 4], [5, 6]], dtype=tf.float32) a1 = tf.tile(a, [2, 2]) with tf.Session() as sess: print(sess.run(a1)) 结果就是: [[ 1. 2. 1. 2.] [ 3. 4. 3. 4.] [ 5. 6. 5. 6.] [

  • Python-re中search()函数的用法详解(查找ip)

    1.首先来看一下search()和find()的区别 import re s1 = "2221155" #search 字符串第一次出现的位置 print(re.search("1",s1)) print(s1.find("1")) 它们的输出分别是: search(): 函数返回的是查找的字符在字符串中的位置 find(): 函数返回的也是在字符串中的位置 目前来看两者并没有什么区别,但是**search()**函数的高级操作还在后边哦! 2.

  • Python3.2中Print函数用法实例详解

    本文实例讲述了Python3.2中Print函数用法.分享给大家供大家参考.具体分析如下: 1. 输出字符串 >>> strHello = 'Hello World' >>> print (strHello) Hello World 2. 格式化输出整数 支持参数格式化,与C语言的printf类似 >>> strHello = "the length of (%s) is %d" %('Hello World',len('Hello

  • PHP中spl_autoload_register()函数用法实例详解

    本文实例分析了PHP中spl_autoload_register()函数用法.分享给大家供大家参考,具体如下: 在了解这个函数之前先来看另一个函数:__autoload. 一.__autoload 这是一个自动加载函数,在PHP5中,当我们实例化一个未定义的类时,就会触发此函数.看下面例子: printit.class.php: <?php class PRINTIT { function doPrint() { echo 'hello world'; } } ?> index.php <

  • Python中 map()函数的用法详解

    map( )函数在算法题目里面经常出现,map( )会根据提供的函数对指定序列做映射,在写返回值等需要转换的时候比较常用. 关于映射map,可以把[ ]转成字符串的话,就不需要用循环打印字符串输出结果这种比较旧的方式. 在Python 3中的例子如下: 也可以用匿名函数来计算幂计算: map(lambda x:x**2,[1,2,3,4,5]) 也可以用来规范输出: name_list={'tony','cHarLIE','rachAEl'} def format_name(s): ss=s[0

随机推荐