Why do we use assert() and assert_options() in PHP?
Assert()
is a clever function that works along the same lines as our print statements, but they only have any effect if a certain condition is not matched. Essentially, assert()
is used to say "This statement must be true - if it isn't, please tell me". Consider this following example:
<?php
print "Stage 1\n";
assert(1 == 1);
print "Stage 2\n";
assert(1 == 2);
print "Stage 3\n";
?>
Here we have two assert()
s, with the first call asserting that one must be equal to one, and the second call asserting that one must be equal to two. As it is impossible to redefine constants like 1 and 2, the first assert()
will always evaluate to true, and the second will always evaluate to false. Here is the output from the script:
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
Note that the first assert()
is not seen in the output at all because it evaluated to true
, whereas the second assert()
evaluated to false
, so we get a warning
about an assertion failure
. Also note that we see "Stage 3"
after the assertion failure warning
, because the script carries on executing after the failure. As long as assertions evaluate to true, they have no effect on the running of the script, which means you can insert them for debugging purposes and not have to worry about taking them out once you are finished debugging.
If you are worried about your assertions slowing execution down, which, although the speed hit will be minimal, is still a valid concern, you can disable execution of assert()
by using the assert_options()
function or by setting assert.active
to Off in your php.ini file. If you want to use assert_options()
, it takes two parameters - the option to set and the value you wish to set it to - and there are a variety of ways it can make assert() more powerful.
Note that all of these options can be set in your php.ini
file so that they are always in effect - the key options to change are assert.active, assert.warning, assert.bail, assert.quiet_eval, and assert_callback
.
ASSERT_CALLBACK
is a very useful options as it allows you to write an error handler for when your code fails an assertion. It takes the string name of a function to execute when assertions fail, and the function you define must take three parameters - one to hold the file where the assertion occurred, one to hold the line, and one to hold the expression. Using all three together in your callback function allows you to generate meaningful error messages that you can debug easily. Consider this code snippet:
<?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');
?>
Ref: http://www.hackingwithphp.com/19/8/3/making-assertions
Example from official documentation
assert_options
— Set/get the various assert flags
Example #1 assert_options() example
<?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';
?>
As per PHP documentation assert()
- If the assertion is given as a string it will be evaluated as PHP code by
assert()
. - If you pass a boolean condition as assertion, this condition will not show up as parameter to the assertion function which you may have defined with
assert_options()
.The condition is converted to a string before calling that handler function, and the boolean FALSE is converted as the empty string. Assertions
should be used as adebugging
feature only. You may use them for sanity-checks that test for conditions that should always be TRUE and that indicate some programming errors if not or to check for the presence of certain features like extension functions or certain system limits and features.Assertions
should not be used for normal runtime operations likeinput parameter
checks. As a rule of thumb your code should always be able to work correctly if assertion checking is not activated.- The behavior of
assert()
may be configured byassert_options()
or by.ini-settings
described in that functions manual page.Theassert_options()
function and/orASSERT_CALLBACK
configuration directive allow a callback function to be set to handle failed assertions. 6.assert()
callbacks are particularly useful for building automated test suites because they allow you to easily capture the code passed to the assertion, along with information on where the assertion was made. While this information can be captured via other methods, using assertions makes it much faster and easier!
The assert()
function is a good way to ensure certain conditions are true throughout the life of your code. To quote this article by Paul Hudson:
Essentially, assert() is used to say "This statement must be true - if it isn't, please tell me".
To enable assertion handling, use assert_options(ASSERT_ACTIVE)
, and also use 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 section for the list of all options and their outcomes.
Try out some of the options in this playground example.
Read that article for more information about both of those functions.