A coworker has added the assert command a few times within our libraries in places where I would have used an if statement and thrown an exception. (I had never even heard o
You coworker is really attempting to apply design by contract (DbC) from the Eiffel language and based on the book: Object Oriented Software Construction, 2nd Edition.
The assertion, as he used it, would be the {P}-part of the Hoare Logic or Hoare Triple: {P} C {Q}, where the {P} is the precondition assert(ion)s and {Q} are the post-condition assert(ion)s.
I would take critical note of advice given about the assert feature in PHP having bugs. You don't want to use buggy code. What you really want are the makers of PHP to fix the bug in the assert. Until they do, you can use the assert, but use it mindful of its present buggy state.
Moreover, if the assert feature is buggy, then I suggest you do not use it in production code. Nevertheless, I do recommend that you use it in development and testing code where appropriate.
Finally—if you do a study of design by contract, you will find that there are consequences to using Boolean assertions in light of object-oriented classical inheritance—that is—you must must never weaken a precondition, nor weaken a post-condition. Doing so could be dangerous to your polymorphic descendant objects interacting with each other. Until you understand what that means—I'd leave it alone!
Moreover—I highly recommend that the makers of PHP do a comprehensive study of design by contract and attempt to put it into PHP ASAP! Then all of us can benefit from having a DbC-aware compiler/interpreter, which would handle the issues noted in the answers (above):
NOTE: Even your use of an if
-statement as a substitute for the assert (precondition) will suffer dire consequences if used to strengthen a precondition or weaken a post-condition. To understand what that means, you will need to study design by contract to know! :-)
Happy studying and learning.
An important note concerning assert in PHP earlier than 7. Unlike other languages with an assert construct, PHP doesn't throw assert statements out entirely - it treats it as a function (do a debug_backtrace() in a function called by an assertion). Turning asserts off seems to just hotwire the function into doing nothing in the engine. Note that PHP 7 can be made to emulate this behavior by setting zend.assertions to 0 instead of the more normal values of 1 (on) or -1 (off).
The problem arises in that assert will take any argument - but if the argument is not a string then assert gets the results of the expression whether assert is on or off. You can verify this with the following code block.
<?php
function foo($a) {
echo $a . "\n";
return TRUE;
}
assert_options(ASSERT_ACTIVE, FALSE);
assert( foo('You will see me.'));
assert('foo(\'You will not see me.\')');
assert_options(ASSERT_ACTIVE, TRUE);
assert( foo('Now you will see'));
assert('foo(\'both of us.\')');
Given the intent of assert this is a bug, and a long standing one since it's been in the language since assert was introduced back in PHP 4.
Strings passed to assert are eval'ed, with all the performance implications and hazards that come with that, but it is the only way to get assert statements to work the way they should in PHP (This behavior deprecated in PHP 7.2).
EDIT: Changed above to note changes in PHP 7 and 7.2