为什么我们在 PHP 中使用 assert() 和 assert_options()?

Why do we use assert() and assert_options() in PHP?

我是 PHP 的新手,我正在通过阅读 php.net 上的文档来学习它 - 目前 assert() 的页面知道那些 assert()assert_options() 函数,但它没有解释 why 我们使用它们以及这些函数用简单的词来做什么。这些功能是什么,我们为什么要在 PHP 中使用它们?

Assert() 是一个聪明的函数,它的工作原理与我们的 print 语句相同,但它们只有在特定条件不匹配时才会起作用。本质上,assert() 用来表示 "This statement must be true - if it isn't, please tell me"。考虑以下示例:

<?php
    print "Stage 1\n";
    assert(1 == 1);
    print "Stage 2\n";
    assert(1 == 2);
    print "Stage 3\n";
?>

这里我们有两个 assert(),第一个调用断言一必须等于一,第二个调用断言一必须等于二。由于无法重新定义像 1 和 2 这样的常量,因此第一个 assert() 将始终计算为真,而第二个将始终计算为假。这是脚本的输出:

Stage 1 Stage 2 Warning: assert()

[http://www.php.net/function.assert]: Assertion failed in /home/paul/sandbox/php/assert.php on line 5

Stage 3

请注意,第一个 assert() 在输出中根本看不到,因为它的计算结果为 true,而第二个 assert() 的计算结果为 false,因此我们得到一个 warning 关于一个 assertion failure。另请注意,我们在断言 failure warning 之后看到 "Stage 3",因为脚本在失败后继续执行。只要断言的计算结果为真,它们就不会影响脚本的 运行,这意味着您可以将它们插入以进行调试,而不必担心在完成调试后将它们取出。


如果您担心您的断言会减慢执行速度,虽然速度影响很小,但仍然是一个有效的问题,您可以使用 assert_options() 禁用 assert() 的执行功能或通过在 php.ini 文件中将 assert.active 设置为关闭。如果你想使用 assert_options(),它需要两个参数——要设置的选项和你希望设置的值——并且有多种方法可以使 assert() 更强大。

请注意,所有这些选项都可以在您的 php.ini 文件中设置,以便它们始终有效 - 要更改的关键选项是 assert.active, assert.warning, assert.bail, assert.quiet_eval, and assert_callback

ASSERT_CALLBACK 是一个非常有用的选项,因为它允许您为代码断言失败时编写错误处理程序。它采用断言失败时要执行的函数的字符串名称,您定义的函数必须采用三个参数 - 一个用于保存发生断言的文件,一个用于保存行,一个用于保存表达式。在您的回调函数中同时使用这三者可以让您生成有意义的错误消息,您可以轻松地进行调试。考虑这个代码片段:

<?php
    function assert_failed($file, $line, $expr) {
        print "Assertion failed in $file on line $line: $expr\n";
    }

    assert_options (ASSERT_CALLBACK, 'assert_failed');
    assert_options (ASSERT_WARNING, 0);

    $foo = 10;
    $bar = 11;
    assert('$foo > $bar');
?>

参考: http://www.hackingwithphp.com/19/8/3/making-assertions


来自官方文档的例子

assert_options — Set/get 各种断言标志

示例 #1 assert_options() 示例

<?php
// This is our function to handle 
// assert failures
function assert_failure()
{
    echo 'Assert failed';
}

// This is our test function
function test_assert($parameter)
{
    assert(is_bool($parameter));
}

// Set our assert options
assert_options(ASSERT_ACTIVE,   true);
assert_options(ASSERT_BAIL,     true);
assert_options(ASSERT_WARNING,  false);
assert_options(ASSERT_CALLBACK, 'assert_failure');

// Make an assert that would fail
test_assert(1);

// This is never reached due to ASSERT_BAIL 
// being true
echo 'Never reached';
?>

根据 PHP 文档 assert()

  1. 如果断言作为字符串给出,它将被 assert() 评估为 PHP 代码。
  2. 如果您将布尔条件作为断言传递,此条件将不会显示为您可能已使用 assert_options() 定义的断言函数的参数。在调用该处理函数之前,该条件将转换为字符串, 并且布尔值 FALSE 被转换为空字符串。
  3. Assertions 应仅用作 debugging 功能。您可以将它们用于健全性检查,以测试应始终为 TRUE 的条件,如果不是,则指示一些编程错误,或者检查是否存在某些功能,如扩展功能或某些系统限制和功能。
  4. Assertions 不应该用于像 input parameter 检查这样的正常运行时操作。根据经验,如果未激活断言检查,您的代码应该始终能够正常工作。
  5. assert() 的行为可以通过 assert_options() 或函数手册 page.The assert_options() 函数 and/or 中描述的 .ini-settings 配置ASSERT_CALLBACK 配置指令允许设置回调函数来处理失败的断言。 6.assert() 回调对于构建自动化测试套件特别有用,因为它们使您可以轻松捕获传递给断言的代码,以及有关断言位置的信息。虽然可以通过其他方法捕获此信息,但使用断言可以使它更快更容易!

Paul Hudson 的 assert() function is a good way to ensure certain conditions are true throughout the life of your code. To quote this article

Essentially, assert() is used to say "This statement must be true - if it isn't, please tell me".

要启用断言处理,请使用 assert_options(ASSERT_ACTIVE),并使用 assert_options() with other arguments to control what happens when assertions fail (e.g. ending the PHP script execution when an assertion fails, calling a handler function- which could be used to send emails, log data in files and/or database tables, etc.). Refer to the parameters 部分列出所有选项及其结果。

尝试this playground example中的一些选项。

阅读 that article 了解有关这两个函数的更多信息。