Skip to content

Instantly share code, notes, and snippets.

@bastman
Created November 20, 2012 17:28
Show Gist options
  • Save bastman/4119434 to your computer and use it in GitHub Desktop.
Save bastman/4119434 to your computer and use it in GitHub Desktop.
PHP ErrorHandler Example: Extended Symfony2 AND Custom Errors
<?php
/**
* Created by JetBrains PhpStorm.
* User: seb
* Date: 11/20/12
* Time: 5:15 PM
* To change this template use File | Settings | File Templates.
*/
$this = 'asd';
<?php
/**
* Created by JetBrains PhpStorm.
* User: seb
* Date: 11/20/12
* Time: 5:15 PM
* To change this template use File | Settings | File Templates.
*/
$foo = new ReflectionClass('StdClass');
clone $foo;
<?php
/**
* Created by JetBrains PhpStorm.
* User: seb
* Date: 11/20/12
* Time: 5:14 PM
* To change this template use File | Settings | File Templates.
*/
$foo = new StdClass;
$bar = NULL;
$foo->$bar = 123;
<?php
/**
* Created by JetBrains PhpStorm.
* User: seb
* Date: 11/20/12
* Time: 5:04 PM
* To change this template use File | Settings | File Templates.
*/
require 'foo.php';
<?php
/**
* Created by JetBrains PhpStorm.
* User: seb
* Date: 11/20/12
* Time: 5:16 PM
* To change this template use File | Settings | File Templates.
*/
// this crappy code
// will trigger notices ...
var_dump(__FILE__);
$arr =array();
var_dump(@$arr[0]);
var_dump($arr[0]);
@include 'foo.php';
include 'foo.php';
<?php
/**
* Created by JetBrains PhpStorm.
* User: seb
* Date: 11/20/12
* Time: 5:13 PM
* To change this template use File | Settings | File Templates.
*/
foo
<?php
/**
* Created by JetBrains PhpStorm.
* User: seb
* Date: 11/20/12
* Time: 4:05 PM
* To change this template use File | Settings | File Templates.
*/
namespace Symfony\Component\HttpKernel\Debug;
class ErrorHandler
{
private $levels = array(
E_WARNING => 'Warning',
E_NOTICE => 'Notice',
E_USER_ERROR => 'User Error',
E_USER_WARNING => 'User Warning',
E_USER_NOTICE => 'User Notice',
E_STRICT => 'Runtime Notice',
E_RECOVERABLE_ERROR => 'Catchable Fatal Error',
E_DEPRECATED => 'Deprecated',
E_USER_DEPRECATED => 'User Deprecated',
);
private $level;
/**
* Register the error handler.
*
* @param integer $level The level at which the conversion to Exception is done (null to use the error_reporting() value and 0 to disable)
*
* @return The registered error handler
*/
public static function register($level = null)
{
$handler = new static();
$handler->setLevel($level);
set_error_handler(array($handler, 'handle'));
return $handler;
}
public function setLevel($level)
{
$this->level = null === $level ? error_reporting() : $level;
}
/**
* @throws \ErrorException When error_reporting returns error
*/
public function handle($level, $message, $file, $line, $context)
{
if (0 === $this->level) {
return false;
}
if (error_reporting() & $level && $this->level & $level) {
throw new \ErrorException(sprintf('%s: %s in %s line %d', isset($this->levels[$level]) ? $this->levels[$level] : $level, $message, $file, $line), 0, $level, $file, $line);
}
return false;
}
}
<?php
/**
* Created by JetBrains PhpStorm.
* User: seb
* Date: 11/20/12
* Time: 4:10 PM
* To change this template use File | Settings | File Templates.
*/
require dirname(__FILE__) . '/ErrorHandler.php';
use Symfony\Component\HttpKernel\Debug\ErrorHandler;
class ShutdownException extends \Exception
{
/**
* @param array $error
*/
public function importError($error)
{
if (!is_array($error)) {
return;
}
$key = 'type';
if (array_key_exists($key, $error)) {
$this->code = $error[$key];
}
$key = 'message';
if (array_key_exists($key, $error)) {
$this->message = $error[$key];
}
$key = 'file';
if (array_key_exists($key, $error)) {
$this->file = $error[$key];
}
$key = 'line';
if (array_key_exists($key, $error)) {
$this->line = $error[$key];
}
}
}
class Bootstrap
{
/**
* @var Bootstrap
*/
private static $_instance;
/**
* @return Bootstrap
*/
public static function getInstance()
{
if (!self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
*
*/
public function init()
{
ini_set('display_errors', false);
ini_set('html_errors', false);
error_reporting(E_ALL | E_STRICT);
$captureLevel = null; // any capture level
$captureLevel = error_reporting(); // current capture level
//$captureLevel = (E_ALL | E_STRICT) ^ E_NOTICE; // ignore notices. I HATE DOING SO!
ErrorHandler::register($captureLevel);
$bootstrap = $this;
register_shutdown_function(
function () use ($bootstrap) {
var_dump('SHUTDOWN');
$lastError = error_get_last();
$lastErrorType = null;
if (
(is_array($lastError))
&& (array_key_exists('type', $lastError))
) {
$lastErrorType = $lastError['type'];
}
if ($lastErrorType === null) {
return;
}
$shutdownException = new \ShutdownException();
$shutdownException->importError($lastError);
$bootstrap->handleShutdownException($shutdownException);
}
);
}
/**
* @param Exception $exception
*/
public function handleException(\Exception $exception)
{
var_dump(__METHOD__);
var_dump(get_class($exception) . ' : ' . $exception->getMessage());
}
/**
* this is the shutdown process!
* YOU MUST NOT:
* - RETHROW EXCEPTIONS
* - RAISE EXCEPTIONS
* - PRODUCE ERRORS
* @param ShutdownException $exception
*/
public function handleShutdownException(\ShutdownException $exception)
{
var_dump(__METHOD__);
var_dump(
get_class($exception)
. ' : '
. $exception->getMessage()
. ' code =' . $exception->getCode()
. ' file =' . $exception->getFile()
. ' line =' . $exception->getLine()
. ' catched at: ' . get_class(
$this
) . ': ' . __METHOD__ . ':' . __LINE__
);
}
}
\Bootstrap::getInstance()->init();
try {
echo '<pre>';
include __DIR__ . '/e_notice.php';
// include __DIR__.'/e_compile_error.php';
// include __DIR__.'/e_core_error.php';
//include __DIR__.'/e_parse.php';
//include __DIR__.'/file_not_exist.php';
//ini_set('display_errors', true);
//include __DIR__.'/e_fatal.php';
var_dump(__FILE__);
} catch (\Exception $e) {
var_dump('EXCEPTION CATCHED IN ' . __FILE__);
var_dump($e);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment