Created
July 22, 2019 09:23
-
-
Save dbalabka/8510ab1d214e5be82c7d7b42296d6b5f to your computer and use it in GitHub Desktop.
iddqd for PHP to ignore notices and warning selectively, while using Symfony ErrorHandler. Helps to upgrade PHP smoothly.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Symfony\Component\Debug\BufferingLogger; | |
use Symfony\Component\Debug\Debug; | |
use Symfony\Component\Debug\ErrorHandler; | |
$loader = require_once __DIR__ . '/vendor/autoload.php'; | |
class ConfigurableErrorHandler extends ErrorHandler | |
{ | |
const ERROR_MSG_COUNT = '/^count\(\): Parameter must be an array or an object that implements Countable$/'; | |
const ERROR_MSG_ARRAY_INDEX = '/^Undefined index: .*$/'; | |
private $rules = [ | |
\E_WARNING => [], | |
\E_NOTICE => [], | |
]; | |
/** | |
* {@inheritDoc} | |
*/ | |
public function __construct(BufferingLogger $bootstrappingLogger = null, array $rules = null) | |
{ | |
$this->rules = $rules; | |
parent::__construct($bootstrappingLogger); | |
} | |
/** | |
* {@inheritDoc} | |
*/ | |
public function handleError($type, $message, $file, $line) | |
{ | |
if ($this->isIgnored($type, $message, $file)) { | |
$setter = $this->getThrownErrorsSetter(); | |
$prevLevel = $setter(E_ALL & ~$type); | |
parent::handleError($type, $message, $file, $line); | |
$setter($prevLevel); | |
return; | |
} | |
parent::handleError($type, $message, $file, $line); | |
} | |
private function isIgnored($type, $message, $file) | |
{ | |
if (!isset($this->rules[$type])) { | |
return false; | |
} | |
$filename = pathinfo($file, PATHINFO_FILENAME); | |
foreach ($this->rules[$type] as $rule) { | |
if ($filename === $rule['file'] && preg_match($rule['message'], $message) === 1) { | |
return true; | |
} | |
} | |
return false; | |
} | |
/** | |
* Can not use throwAt() because it re-register the handler | |
*/ | |
public function getThrownErrorsSetter(): \Closure | |
{ | |
return \Closure::bind(function ($errors) { | |
$prev = $this->thrownErrors; | |
$this->thrownErrors = $errors; | |
return $prev; | |
}, $this, ErrorHandler::class); | |
} | |
} | |
Debug::enable(); | |
$rules = [ | |
\E_WARNING => [ | |
[ | |
'message' => ConfigurableErrorHandler::ERROR_MSG_COUNT, | |
'file' => 'test', | |
] | |
], | |
// uncomment to test notices ignorance | |
// \E_NOTICE => [ | |
// [ | |
// 'message' => ConfigurableErrorHandler::ERROR_MSG_ARRAY_INDEX, | |
// 'file' => 'test', | |
// ] | |
// ], | |
]; | |
$errorHandler = new ConfigurableErrorHandler(null, $rules); | |
ErrorHandler::register($errorHandler, true); | |
var_dump(count(null)); | |
$arr = []; | |
$arr['a']; | |
var_dump(count(null)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment