PHP assert() 到底如何工作?

发布于 2024-11-26 15:57:27 字数 7490 浏览 0 评论 0原文

我试图做一个简单的 PHP 断言来验证字符串不为空,但得到了令人困惑的结果。

我不知道断言()中的字符串评估功能,但检查了文档并理解了该部分。

我将代码包含在所有测试用例中,然后是输出,然后是问题。当某个案例因语法错误而失败时,我只需将其注释掉并重复测试,以便可以执行以下案例,并显示每次执行的输出。

该代码是关于使用 XMLReader 定位 XML 元素,但这恰好是我的代码。所以这里首先是代码:

<?php

$xml = <<< XML
<depts  xmlns:apl="urn:my:ns" >
    <apl:dept>Dept One</apl:dept>
    <apl:dept>Dept Tow</apl:dept>
</depts>
XML;


$elmLocal = 'dept';
$elmUrn = "urn:my:ns";

$xr = new XMLReader;
$xr->XML($xml);

// move to the first desired element node
$found = false;
while ($xr->read()) {
    if ($xr->localName === $elmLocal && $xr->namespaceURI === $elmUrn) {
        $found = true;
        break;
    }
}
if (!$found) {
    exit("---Error--- No element found with given Name/NS.\n");
}



$var = $xr->name;

echo "---------------- Test Results ---------------->\n";

echo "----- var    =={$var}==\n";
echo "----- xr name=={$xr->name}==\n\n";


echo "------ assertion 00 ------>\n";
assert ($xr->name);

echo "------ assertion 01 ------>\n";
assert ($var);

echo "------ assertion 02 ------>\n";
assert ('$xr->name!==""');   

echo "------ assertion 03 ------>\n";
assert ('$var!==""');   

echo "------ assertion 04 ------>\n";
assert ("{$xr->name}!==''");   

echo "------ assertion 05 ------>\n";
assert ("{$var}!==''");   

echo "------ assertion 06 ------>\n";
assert(!empty($xr->name));

echo "------ assertion 07 ------>\n";
assert(!empty($var));

echo "------ assertion 08 ------>\n";
assert('!empty($xr->name)');

echo "------ assertion 09 ------>\n";
assert('!empty($var)');

echo "------ assertion 10 ------>\n";
assert("!empty({$xr->name})");

echo "------ assertion 11 ------>\n";
assert("!empty({$var})");



// do some processing
$domNode = $xr->expand(); // DOMNode XMLReader::expand ([ DOMNode $basenode ] )


?>

这里是执行输出 - 再次注意,有关于致命语法失败和重复执行的注释,您可以假设每个断言都是单独测试的:

#tests#php -v
PHP 5.3.3-7+squeeze3 with Suhosin-Patch (cli) (built: Jun 28 2011 13:13:26)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
    with Xdebug v2.1.0, Copyright (c) 2002-2010, by Derick Rethans
    with Suhosin v0.9.32.1, Copyright (c) 2007-2010, by SektionEins GmbH


#tests#php -q vars.php
---------------- Test Results ---------------->
----- var    ==apl:dept==
----- xr name==apl:dept==

------ assertion 00 ------>
PHP Parse error:  syntax error, unexpected ':' in /shared/tests/vars.php(40) : assert code on line 1
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:40
PHP Catchable fatal error:  assert(): Failure evaluating code:
apl:dept in /shared/tests/vars.php on line 40
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:40

#tests#php -q vars.php
---------------- Test Results ---------------->
----- var    ==apl:dept==
----- xr name==apl:dept==

------ assertion 01 ------>
PHP Parse error:  syntax error, unexpected ':' in /shared/tests/vars.php(43) : assert code on line 1
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:43
PHP Catchable fatal error:  assert(): Failure evaluating code:
apl:dept in /shared/tests/vars.php on line 43
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:43

#tests#php -q vars.php
---------------- Test Results ---------------->
----- var    ==apl:dept==
----- xr name==apl:dept==

------ assertion 02 ------>
------ assertion 03 ------>
------ assertion 04 ------>
PHP Parse error:  syntax error, unexpected ':' in /shared/tests/vars.php(52) : assert code on line 1
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:52
PHP Catchable fatal error:  assert(): Failure evaluating code:
apl:dept!=='' in /shared/tests/vars.php on line 52
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:52

#tests#php -q vars.php
---------------- Test Results ---------------->
----- var    ==apl:dept==
----- xr name==apl:dept==

------ assertion 02 ------>
------ assertion 03 ------>
------ assertion 05 ------>
PHP Parse error:  syntax error, unexpected ':' in /shared/tests/vars.php(55) : assert code on line 1
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:55
PHP Catchable fatal error:  assert(): Failure evaluating code:
apl:dept!=='' in /shared/tests/vars.php on line 55
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:55

#tests#php -q vars.php
---------------- Test Results ---------------->
----- var    ==apl:dept==
----- xr name==apl:dept==

------ assertion 02 ------>
------ assertion 03 ------>
------ assertion 06 ------>
PHP Warning:  assert(): Assertion failed in /shared/tests/vars.php on line 58
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:58
------ assertion 07 ------>
------ assertion 08 ------>
PHP Warning:  assert(): Assertion "!empty($xr->name)" failed in /shared/tests/vars.php on line 64
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:64
------ assertion 09 ------>
------ assertion 10 ------>
PHP Parse error:  syntax error, unexpected ':', expecting T_PAAMAYIM_NEKUDOTAYIM in /shared/tests/vars.php(70) : assert code on line 1
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:70
PHP Catchable fatal error:  assert(): Failure evaluating code:
!empty(apl:dept) in /shared/tests/vars.php on line 70
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:70

#tests#php -q vars.php
---------------- Test Results ---------------->
----- var    ==apl:dept==
----- xr name==apl:dept==

------ assertion 02 ------>
------ assertion 03 ------>
------ assertion 06 ------>
PHP Warning:  assert(): Assertion failed in /shared/tests/vars.php on line 58
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:58
------ assertion 07 ------>
------ assertion 08 ------>
PHP Warning:  assert(): Assertion "!empty($xr->name)" failed in /shared/tests/vars.php on line 64
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:64
------ assertion 09 ------>
------ assertion 11 ------>
PHP Parse error:  syntax error, unexpected ':', expecting T_PAAMAYIM_NEKUDOTAYIM in /shared/tests/vars.php(73) : assert code on line 1
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:73
PHP Catchable fatal error:  assert(): Failure evaluating code:
!empty(apl:dept) in /shared/tests/vars.php on line 73
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:73

现在一些注释:

情况 1,2 是可以理解的- 即字符串评估“feature”。

所有断言表达式用双引号括起来的情况 - 也弄清楚了:首先完成变量解析,这会导致执行中的语法错误。因此,为了使案例 4 发挥作用,我们可以这样做:

echo "------ assertion 04 ------>\n";
assert ("'{$xr->name}'!==''");   

现在真正的问题是案例 6,7。为什么6失败而7成功。与案例 8,9 - 8 失败而 9 成功相同。

问候。

I was trying to do a simple PHP assertion to verify that a string is not empty, but got confusing results.

I wasn't aware of the string evaluation feature in assert(), but checked the docs and understood that part.

I included the code with the all the test cases, followed by the output, then followed by the questions. When a case fails with syntax error, I just comment it out and repeat the test so the following cases can get executed, and I show the output for each execution.

The code is about locating an XML element using XMLReader, but that just happened to be my code. So here goes the code first:

<?php

$xml = <<< XML
<depts  xmlns:apl="urn:my:ns" >
    <apl:dept>Dept One</apl:dept>
    <apl:dept>Dept Tow</apl:dept>
</depts>
XML;


$elmLocal = 'dept';
$elmUrn = "urn:my:ns";

$xr = new XMLReader;
$xr->XML($xml);

// move to the first desired element node
$found = false;
while ($xr->read()) {
    if ($xr->localName === $elmLocal && $xr->namespaceURI === $elmUrn) {
        $found = true;
        break;
    }
}
if (!$found) {
    exit("---Error--- No element found with given Name/NS.\n");
}



$var = $xr->name;

echo "---------------- Test Results ---------------->\n";

echo "----- var    =={$var}==\n";
echo "----- xr name=={$xr->name}==\n\n";


echo "------ assertion 00 ------>\n";
assert ($xr->name);

echo "------ assertion 01 ------>\n";
assert ($var);

echo "------ assertion 02 ------>\n";
assert ('$xr->name!==""');   

echo "------ assertion 03 ------>\n";
assert ('$var!==""');   

echo "------ assertion 04 ------>\n";
assert ("{$xr->name}!==''");   

echo "------ assertion 05 ------>\n";
assert ("{$var}!==''");   

echo "------ assertion 06 ------>\n";
assert(!empty($xr->name));

echo "------ assertion 07 ------>\n";
assert(!empty($var));

echo "------ assertion 08 ------>\n";
assert('!empty($xr->name)');

echo "------ assertion 09 ------>\n";
assert('!empty($var)');

echo "------ assertion 10 ------>\n";
assert("!empty({$xr->name})");

echo "------ assertion 11 ------>\n";
assert("!empty({$var})");



// do some processing
$domNode = $xr->expand(); // DOMNode XMLReader::expand ([ DOMNode $basenode ] )


?>

And here goes the execution outputs - notice again that there are commenting out on fatal syntax failure and repeat execution, you can just assume that each assertion was tested separately:

#tests#php -v
PHP 5.3.3-7+squeeze3 with Suhosin-Patch (cli) (built: Jun 28 2011 13:13:26)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
    with Xdebug v2.1.0, Copyright (c) 2002-2010, by Derick Rethans
    with Suhosin v0.9.32.1, Copyright (c) 2007-2010, by SektionEins GmbH


#tests#php -q vars.php
---------------- Test Results ---------------->
----- var    ==apl:dept==
----- xr name==apl:dept==

------ assertion 00 ------>
PHP Parse error:  syntax error, unexpected ':' in /shared/tests/vars.php(40) : assert code on line 1
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:40
PHP Catchable fatal error:  assert(): Failure evaluating code:
apl:dept in /shared/tests/vars.php on line 40
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:40

#tests#php -q vars.php
---------------- Test Results ---------------->
----- var    ==apl:dept==
----- xr name==apl:dept==

------ assertion 01 ------>
PHP Parse error:  syntax error, unexpected ':' in /shared/tests/vars.php(43) : assert code on line 1
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:43
PHP Catchable fatal error:  assert(): Failure evaluating code:
apl:dept in /shared/tests/vars.php on line 43
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:43

#tests#php -q vars.php
---------------- Test Results ---------------->
----- var    ==apl:dept==
----- xr name==apl:dept==

------ assertion 02 ------>
------ assertion 03 ------>
------ assertion 04 ------>
PHP Parse error:  syntax error, unexpected ':' in /shared/tests/vars.php(52) : assert code on line 1
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:52
PHP Catchable fatal error:  assert(): Failure evaluating code:
apl:dept!=='' in /shared/tests/vars.php on line 52
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:52

#tests#php -q vars.php
---------------- Test Results ---------------->
----- var    ==apl:dept==
----- xr name==apl:dept==

------ assertion 02 ------>
------ assertion 03 ------>
------ assertion 05 ------>
PHP Parse error:  syntax error, unexpected ':' in /shared/tests/vars.php(55) : assert code on line 1
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:55
PHP Catchable fatal error:  assert(): Failure evaluating code:
apl:dept!=='' in /shared/tests/vars.php on line 55
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:55

#tests#php -q vars.php
---------------- Test Results ---------------->
----- var    ==apl:dept==
----- xr name==apl:dept==

------ assertion 02 ------>
------ assertion 03 ------>
------ assertion 06 ------>
PHP Warning:  assert(): Assertion failed in /shared/tests/vars.php on line 58
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:58
------ assertion 07 ------>
------ assertion 08 ------>
PHP Warning:  assert(): Assertion "!empty($xr->name)" failed in /shared/tests/vars.php on line 64
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:64
------ assertion 09 ------>
------ assertion 10 ------>
PHP Parse error:  syntax error, unexpected ':', expecting T_PAAMAYIM_NEKUDOTAYIM in /shared/tests/vars.php(70) : assert code on line 1
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:70
PHP Catchable fatal error:  assert(): Failure evaluating code:
!empty(apl:dept) in /shared/tests/vars.php on line 70
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:70

#tests#php -q vars.php
---------------- Test Results ---------------->
----- var    ==apl:dept==
----- xr name==apl:dept==

------ assertion 02 ------>
------ assertion 03 ------>
------ assertion 06 ------>
PHP Warning:  assert(): Assertion failed in /shared/tests/vars.php on line 58
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:58
------ assertion 07 ------>
------ assertion 08 ------>
PHP Warning:  assert(): Assertion "!empty($xr->name)" failed in /shared/tests/vars.php on line 64
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:64
------ assertion 09 ------>
------ assertion 11 ------>
PHP Parse error:  syntax error, unexpected ':', expecting T_PAAMAYIM_NEKUDOTAYIM in /shared/tests/vars.php(73) : assert code on line 1
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:73
PHP Catchable fatal error:  assert(): Failure evaluating code:
!empty(apl:dept) in /shared/tests/vars.php on line 73
PHP Stack trace:
PHP   1. {main}() /shared/tests/vars.php:0
PHP   2. assert() /shared/tests/vars.php:73

Now some comments:

Cases 1,2 are understandable - ie the string evaluation "feature".

All cases with the assertion expression surrounded by double quotes - figured them out too: variable parsing is done first which results in the syntax error in the execution. So to make case 4 for example work, we can do:

echo "------ assertion 04 ------>\n";
assert ("'{$xr->name}'!==''");   

Now the real issue is with cases 6,7. Why is 6 failing while 7 is succeeding. The same with cases 8,9 - 8 failing while 9 succeeding.

Regards.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梨涡 2024-12-03 15:57:27

这不是关于assert()如何工作,而是关于empty()如何工作。
当与 $object->inaccessibleProp 一起使用时,empty 首先尝试与 isset() 相同的操作,如果此“测试”返回 false,empty() 甚至不会尝试访问该元素,而是返回 true。
XMLReader 类显然没有实现 __isset() 按照您需要的方式进行方法。

<?php
$xml = <<< XML
<depts  xmlns:apl="urn:my:ns" >
    <apl:dept>Dept One</apl:dept>
    <apl:dept>Dept Tow</apl:dept>
</depts>
XML;

$elmLocal = 'dept';
$elmUrn = "urn:my:ns";

$xr = new XMLReader;
$xr->XML($xml);

// move to the first desired element node
$found = false;
while ($xr->read()) {
    if ($xr->localName === $elmLocal && $xr->namespaceURI === $elmUrn) {
        $found = true;
        break;
    }
}
if (!$found) {
    exit("---Error--- No element found with given Name/NS.\n");
}

$var = $xr->name;
var_dump(isset($xr->name));
var_dump(empty($xr->name));
echo $xr->name;

印刷

bool(false)
bool(true)
apl:dept

It's not about how assert() works but how empty() works.
When used with $object->inaccessibleProp empty first tries the same thing as isset() and if this "test" returns false empty() doesn't even try to access the element but returns true.
And the XMLReader class obviously doesn't implement the __isset() method the way you'd need it.

<?php
$xml = <<< XML
<depts  xmlns:apl="urn:my:ns" >
    <apl:dept>Dept One</apl:dept>
    <apl:dept>Dept Tow</apl:dept>
</depts>
XML;

$elmLocal = 'dept';
$elmUrn = "urn:my:ns";

$xr = new XMLReader;
$xr->XML($xml);

// move to the first desired element node
$found = false;
while ($xr->read()) {
    if ($xr->localName === $elmLocal && $xr->namespaceURI === $elmUrn) {
        $found = true;
        break;
    }
}
if (!$found) {
    exit("---Error--- No element found with given Name/NS.\n");
}

$var = $xr->name;
var_dump(isset($xr->name));
var_dump(empty($xr->name));
echo $xr->name;

prints

bool(false)
bool(true)
apl:dept
独自←快乐 2024-12-03 15:57:27

现在真正的问题是案例 6,7。为什么6失败而7成功。与情况 8,9 - 8 失败而 9 成功相同。

因为它不是标量类型。

Now the real issue is with cases 6,7. Why is 6 failing while 7 is succeeding. The same with cases 8,9 - 8 failing while 9 succeeding.

Because it was not a scalar type.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文