zoukankan      html  css  js  c++  java
  • php 断言

    原文: https://www.php.cn/php-ask-429607.html

    php7需要在php.ini中配置zend.assertions = 1, 或者运行时通过ini_set()配置。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <?php
     
    function arraySum(array $nums) {
     
        $sum = 0;    foreach ($nums as $n) {
     
            $sum += $n;
     
        }    return $sum;
     
    }
     
     
    assert(arraySum([1, 2, 3]) == 7, 'arraySum() 测试不通过:');
     
    assert(!is_numeric(arraySum([1, 2, 3])), 'arraySum() 测试不通过:');
    assert(1 == 2);

      

    assert 失败时的异常是可以捕捉的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 在断言失败时产生异常
     
    try {   
     
    // 用 AssertionError 异常替代普通字符串
     
        assert(true == false, new AssertionError('True is not false!'));
     
        } catch (Throwable $e) {   
     
        echo $e->getMessage();
     
        }

      

    --------------------------------------------------------------------------------------------------------

    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配置。

    另外,还支持通过 AssertionError 捕获错误。

    使用示例:



    assert_options(ASSERT_EXCEPTION, 1); 

    // 在断言失败时产生异常

    try {    

    // 用 AssertionError 异常替代普通字符串

        assert(true == false, new AssertionError('True is not false!'));

    } catch (Throwable $e) {    

    echo $e->getMessage();

    }

    运行结果:

    1

    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 不再支持字符串

    1

    Deprecated: assert(): Calling assert() with a string argument is deprecated

    八、应用场景

    调试输出:

    先看示例:

    1

    assert('1 == 2', '1 不可能等于 2');

    运行结果:

    1

    Warning: assert(): 1 不可能等于 2: "1 == 2" failed in /Users/shocker/Desktop/demo.php on line 10

    类似于:


    $expression = 1 == 2;

    if (!($expression)) {

        echo "1 不可能等于 2 ";

        var_dump($expression);

        echo __FILE__ . " ";

    }

    但是,我们无法得知 $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(), " ";

    }

    运行结果:


    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)?该如何使用?的详细内容,更多请关注php中文网其它相关文章

  • 相关阅读:
    静态资源放置于独立域名之下
    一个程序学习String类的所有常用方法
    Myeclipse的workspace配置文件浅谈
    使用myeclipse自带的tomcat发布web功能怎么访问
    Java陷阱之assert关键字
    Java集合Map接口与Map.Entry学习
    Java中List和ArrayList的区别
    手动命名名字空间打包以及调用
    命令行java -classpath 的使用
    maven 环境变量设置和Java maven工具配置 on windows 7
  • 原文地址:https://www.cnblogs.com/keketoloveme/p/14498402.html
Copyright © 2011-2022 走看看