I've discovered the "Design by contract" pattern and how to implement in in PHP. I can't find a real world example of how to do this in PHP. First question is am i'm doing it in the right way? Second one is why the assert callback is not honored?
A static class Asserts
for reusable assertions:
class Asserts
{
public static function absentOrNotNumeric($value)
{
return !isset($value) ? true : is_numeric($value);
}
}
Usage:
assert_options(ASSERT_ACTIVE, true);
assert_options(ASSERT_BAIL, true);
assert_options(ASSERT_WARNING, true);
assert_options(ASSERT_CALLBACK, array('UseAsserts', 'onAssertFailure'));
class UseAsserts
{
private $value;
public function __construct($value)
{
// Single quotes are needed otherwise you'll get a
// Parse error: syntax error, unexpected T_STRING
assert('Asserts::absentOrNotNumeric($value)');
$this->value = $value;
}
public static function onAssertFailure($file, $line, $message)
{
throw new Exception($message);
}
}
// This will trigger a warning and stops execution, but Exception is not thrown
$fail = new UseAsserts('Should fail.');
Only the (right) warning is triggered:
Warning: assert() [function.assert]: Assertion "Asserts::absetOrNotNumeric($value)" failed.
Your exception is being thrown, altering it to:
public static function onAssertFailure($file, $line, $message)
{
echo "<hr>Assertion Failed:
File '$file'<br />
Line '$line'<br />
Code '$code'<br /><hr />";
}
results in a display of the text, some testing discovers that if you alter this option
assert_options(ASSERT_BAIL, false);
The exception will be thrown, so it seems that it bails on the execution prior to throwing the exception.
Hope that helps