I'm studying PHP and, meanwhile, writing toy code to understand what I study.
These are my "error and exception handler" functions.
My intention is:
- to convert any "old style" PHP error in an Exception
- to display the Exception
- to log an error message in the syslog
function display_exception($exception)
{
print_r($exception);
}
function log_error_or_exception($error_type, $error_message, $error_number = null, $file_name = null, $line_number = null)
{
$text = 'Message: ' . $error_message . ' - ErrorType: ' . $error_type;
if ($error_number) {
$text .= ' - Error#: ' . $error_number;
}
if ($file_name) {
$text .= ' -> ' . $file_name;
}
if ($line_number) {
$text .= ':' . $line_number;
}
syslog(LOG_ERR, $text);
}
/**
* This function logs any uncaught exception that has been thrown.
* If in the "dev" environment it also displays the Exception
*
* @var Exception $exception
* @return void
*/
function custom_exception_handler($exception)
{
if (ENV == 'dev') {
display_exception($exception);
}
log_error_or_exception(get_class($exception), $exception->getMessage(), $exception->getCode(), $exception->getFile(), $exception->getLine());
}
/**
* This function converts an "old style" PHP Error in an ErrorException
*
* @var int $errno
* @var string $errstr
* @var string|null $errfile
* @var int|null $errline
* @var array $errcontext
* @return false|void
*/
function custom_error_handler(int $errno, string $errstr, string $errfile = null, int $errline = null, array $errcontext = array())
{
// if error_reporting() is false it means that the error was trigger by a line having
// the error control operator "@" so the error should never be displayed.
// Sometimes thought it's convenient to log it
if (!error_reporting()) {
if (ENV == 'dev') {
log_error_or_exception('Error', $errstr, $errno, $errfile, $errline);
}
return false;
}
throw new ErrorException($errstr, $errno, 1, $errfile, $errline);
echo "this should not be displayed";
}
set_exception_handler('custom_exception_handler');
set_error_handler('custom_error_handler');
Now I have an object
<?php
require_once 'app/src/ErrorExceptionHandlers.php';
class Obj
{
public function method($value){
$result = preg_match('/@/', $value);
}
}
If I run this code everything works as expected:
define('ENV', 'dev');
$object = new Obj;
$object->method(array());
I get:
ErrorException Object
(
[message:protected] => preg_match() expects parameter 2 to be string, array given
[string:Exception:private] =>
...
)
If I try to run this phpunit test
<?php
require_once 'app/src/models/obj.php';
define('ENV', 'dev');
class ObjTest extends \PHPUnit_Framework_TestCase
{
/**
* @ExpectedException ErrorException
*/
public function test_method(){
$object = new Obj();
$object->method(array());
}
}
I get:
There was 1 error:
1) ObjTest::test_method
ErrorException: preg_match() expects parameter 2 to be string, array given
Why does the test fail?
@expectedException