©
本文档使用
php.cn手册 发布
(PHP 4, PHP 5, PHP 7)
assert_options — 设置/获取断言的各种标志
$what
[, mixed $value
] )设置 assert() 的各种控制选项,或者是仅仅查询当前的设置。
what
标志 | 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 ) | 断言失败时调用回调函数 |
value
标志的新值。
返回任意标志的原始设置,出错时返回 FALSE
。
Example #1 assert_options() 例子
<?php
// 处理断言失败时的函数
function assert_failure ()
{
echo 'Assert failed' ;
}
// 我们的测试函数
function test_assert ( $parameter )
{
assert ( is_bool ( $parameter ));
}
// 设置断言标志
assert_options ( ASSERT_ACTIVE , true );
assert_options ( ASSERT_BAIL , true );
assert_options ( ASSERT_WARNING , false );
assert_options ( ASSERT_CALLBACK , 'assert_failure' );
// 让一个断言会失败
test_assert ( 1 );
// 由于 ASSERT_BAIL 是 true,这里永远也到不了
echo 'Never reached' ;
?>
[#1] Fr?d?ric Bouchery [2003-07-20 16:25:41]
Here is an exemple how to use the assertion callback function :
<?php
assert_options( ASSERT_CALLBACK, 'assert_callback');
function assert_callback( $script, $line, $message ) {
echo 'You have a design error in your script <b>', $script,'</b> : line <b>', $line,'</b> :<br />';
echo '<b>', ereg_replace( '^.*//\*', '', $message ), '</b><br /><br />';
echo 'Open the source file and check it, because it\'s not a normal behaviour !';
exit;
}
$x = 3;
assert('is_integer( $x ) && ($x >= 0) && ($x <= 10); /
public function setAssertionDebug($assertion, $callback, array $options, $description = null)
{
if (is_array($options)) {
foreach ($options AS $option => $value) {
assert_options($option, $value);
}
}
if ($callback) {
assert_options(ASSERT_CALLBACK, $callback);
}
return assert($assertion, $description);
}
?>
How to use:
<?php
use Ikac\Component\SystemBehaviour\OptionsInfo;
$system = new OptionsInfo();
$option = array(ASSERT_ACTIVE => 1,ASSERT_WARNING => 0,ASSERT_QUIET_EVAL => 1);
$system->setAssertionDebug('2<1', function(){
echo "Assertion failed";
}, $option);
?>
[#3] devoto13 at gmail dot com [2013-07-03 10:29:34]
"If you would like to compare with === or !== you need to add '(string)' before string numbers. Or wrap them with quotes."
Do not use this aproach, because it would not work, look at http://php.net/manual/en/function.var-export.php .
[#4] uramihsayibok, gmail, com [2010-06-20 13:48:22]
There's a nice advantage to giving assert() some code to execute, as a string, rather than a simple true/false value: commenting.
<?php
assert('is_int($int) ');
// and my personal favorite
assert('false ');
?>
The comment will show up in the output (or in your assertion handler) and doesn't require someone debugging to go through your code trying to figure out why the assertion happened. That's no excuse to not comment your code, of course.
You need to use a block comment () because a line comment (//...) creates an "unexpected $end" parse error in the evaluated code. Bug? Could be.
(You can get around it with "false // not yet implemented\n" but that screws up the message)
[#5] hodgman at ali dot com dot au [2008-07-28 21:19:43]
As noted on Wikipedia - "assertions are primarily a development tool, they are often disabled when a program is released to the public." and "Assertions should be used to document logically impossible situations and discover programming errors?? if the 'impossible' occurs, then something fundamental is clearly wrong. This is distinct from error handling: most error conditions are possible, although some may be extremely unlikely to occur in practice. Using assertions as a general-purpose error handling mechanism is usually unwise: assertions do not allow for graceful recovery from errors, and an assertion failure will often halt the program's execution abruptly. Assertions also do not display a user-friendly error message."
This means that the advice given by "gk at proliberty dot com" to force assertions to be enabled, even when they have been disabled manually, goes against best practices of only using them as a development tool.
[#6] Krzysztof 'ChanibaL' Bociurko [2007-10-01 18:13:06]
Note that func_get_args() should be used carefully and never in a string! For example:
<?php
function asserted_normal($a, $b) {
assert(var_dump(func_get_args()));
}
function asserted_string($a, $b) {
assert('var_dump(func_get_args())');
}
?>
<?php asserted_normal(1,2) ?>
prints
array(2) {
[0]=>
int(1)
[1]=>
int(2)
}
but
<?php asserted_string(3,4) ?>
prints
array(1) {
[0]=>
string(25) "var_dump(func_get_args())"
}
This is because of that the string passed to assert() is being evaled inside assert, and not your function. Also, note that this works correctly, because of the eval scope:
<?php
function asserted_evaled_string($a, $b) {
assert(eval('var_dump(func_get_args())'));
}
asserted_evaled_string(5,6);
?>
array(2) {
[0]=>
int(5)
[1]=>
int(6)
}
(oh, and for simplicity's sake the evaled code doesn't return true, so don't worry that it fails assertion...)
[#7] mail<at>aaron-mueller.de [2006-09-13 10:51:05]
Here is a simple demonstration of Design By Contract with PHP
<?php
assert_options(ASSERT_ACTIVE, 1);
assert_options(ASSERT_WARNING, 0);
assert_options(ASSERT_BAIL, 1);
assert_options(ASSERT_CALLBACK, 'dcb_callback');
function dcb_callback($script, $line, $message) {
echo "<h1>Condition failed!</h1><br />
Script: <strong>$script</strong><br />
Line: <strong>$line</strong><br />
Condition: <br /><pre>$message</pre>";
}
// Parameters
$a = 5;
$b = 'Simple DCB with PHP';
// Pre-Condition
assert('
is_integer($a) &&
($a > 0) &&
($a < 20) &&
is_string($b) &&
(strlen($b) > 5);
');
// Function
function combine($a, $b) {
return "Kombined: " . $b . $a;
}
$result = combine($a, $b);
// Post-Condition
assert('
is_string($result) &&
(strlen($result) > 0);
');
// All right, the Function works fine
var_dump($result);
?>
[#8] gk at proliberty dot com [2005-08-26 19:35:54]
If you expect your code to be able to work well with other code, then you should not make any assumptions about the current state of assert_options() flags, prior to calling assert(): other code may disable ASSERT_ACTIVE, without you knowing it - this would render assert() useless!
To avoid this, ALWAYS set assert_options() IMMEDIATELY before calling assert(), per the C++ paradigm for assertion usage:
In one C++ source file, you can define and undefine NDEBUG multiple times, each time followed by #include <cassert>, to enable or disable the assert macro multiple times in the same source file.
Here is how I workaround this issue in my PHP code:
<?php
//////////////////////////////////////////////////////////////////////
/// phpxAssertHandler_f
//////////////////////////////////////////////////////////////////////
function phpxAssertHandler_f($file_or_custom_options=null, $line_or_assert_options=null, $code=null){
static $custom_options;
$debug = false;
if (is_null($code)){
// set default assert_options
$assert_options[]=1;//ASSERT_ACTIVE
$assert_options[]=0;//ASSERT_WARNING -
$assert_options[]=0;//ASSERT_QUIET_EVAL
$assert_options[]=__FUNCTION__;//ASSERT_CALLBACK
// set default custom_options
$custom_options[]=E_USER_ERROR;// error level
if (!is_null($line_or_assert_options)){
// assert_options are passed in
if (!is_array($line_or_assert_options)){
$line_or_assert_options=array($line_or_assert_options);
}
foreach ($line_or_assert_options as $i=>$assert_option){
if ($assert_option===true) $assert_option=1;
if ($assert_option===false) $assert_option=0;
$assert_options[$i]=$assert_option;
if($debug) echo ("assert_options[$i]=$assert_option\n");
}
}
if (!is_null($file_or_custom_options)){
// custom_options are passed in
if (!is_array($file_or_custom_options)){
$file_or_custom_options=array($file_or_custom_options);
}
foreach ($file_or_custom_options as $i=>$custom_option){
if ($custom_option===true) $custom_option=1;
if ($custom_option===false) $custom_option=0;
$custom_options[$i]=$custom_option;
if($debug) echo ("custom_options[$i]=$custom_option\n");
}
}
// set assert options
@assert_options (ASSERT_ACTIVE, $assert_options[0]);
@assert_options (ASSERT_WARNING, $assert_options[1]);
@assert_options (ASSERT_QUIET_EVAL, $assert_options[2]);
@assert_options (ASSERT_CALLBACK, $assert_options[3]);
} else {
// we are acting as a callback function
$file = $file_or_custom_options;
$line = $line_or_assert_options;
$msg="ASSERTION FAILED: $code";
phpxErrorHandler_f ($custom_options[0],$msg,$file,$line);
}
}//phpxAssertHandler_f()
?>