Making assertions

int assert ( mixed assertion)

mixed assert_options ( int what [, mixed value])

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.

Here is the list of options you can use for the first parameter of assert_options() :

Parameter

Default

Description

ASSERT_ACTIVE

On

Enables evaluation of assert() calls

ASSERT_WARNING

On

Makes PHP output a warning for each failed assertion

ASSERT_BAIL

Off

Force PHP to end script execution on a failed assertion

ASSERT_QUIET_EVAL

Off

Ignore errors in assert() calls

ASSERT_CALLBACK

Off

Name of user function to call on a failed assertion

So, to disable assert() calls, we can use this line of code:

assert_options(ASSERT_ACTIVE, 0);

And to make PHP end script execution rather than just issue a warning, we can use this line of code:

assert_options(ASSERT_BAIL, 1);

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');
?>

Here we've got our callback function defined taking $file, $line, and $expr for the three variables passed in, and it will dutifully output them nicely formatted whenever an assertion fails. To make that result actually happen, assert_options() is called to let PHP know that assert_failed() is the correct function to use as a callback - note that there are no brackets after the string being passed into assert_options().

ASSERT_WARNING is also disabled, which stops PHP from outputting a warning as well as running the callback function. Finally, two variables are set, and are used as part of a call to assert() - as you can see, $foo is quite clearly not greater than $bar, which means the assertion will fail and call our callback. As such, the output from the script is:

Assertion failed in /home/paul/tmp/blerg.php on line 9: $foo > $bar

You can assert() any statement you like, as long as it will return either true or false. This makes the assert() function incredibly powerful - even more so when you think that you can just turn off assertion execution to make the code run at full speed.

As such, assert() is an excellent debugging aid, and one that you should use regularly - sprinkle asserts in wherever you need to be sure of a value before it is used. It is the best, and easiest way, to make sure your program is in a sane state.

 

Want to learn PHP 7?

Hacking with PHP has been fully updated for PHP 7, and is now available as a downloadable PDF. Get over 1200 pages of hands-on PHP learning today!

If this was helpful, please take a moment to tell others about Hacking with PHP by tweeting about it!

Next chapter: Triggering your own errors >>

Previous chapter: The most basic debugging technique

Jump to:

 

Home: Table of Contents

Copyright ©2015 Paul Hudson. Follow me: @twostraws.