/** * Registers a message handler to catch deprecation errors * * This method is based on \Symfony\Bridge\PhpUnit\DeprecationErrorHandler::register() * * @return void * * @since 3.5 */ public static function registerDeprecationHandler() { if (self::$isDeprecationHandlerRegistered) { return; } $deprecations = array('phpCount' => 0, 'userCount' => 0, 'php' => array(), 'user' => array()); $deprecationHandler = function ($type, $msg, $file, $line, $context) use(&$deprecations) { // Check if the type is E_DEPRECATED or E_USER_DEPRECATED if (!in_array($type, array(E_DEPRECATED, E_USER_DEPRECATED))) { return PHPUnit_Util_ErrorHandler::handleError($type, $msg, $file, $line, $context); } $trace = debug_backtrace(PHP_VERSION_ID >= 50400 ? DEBUG_BACKTRACE_IGNORE_ARGS | DEBUG_BACKTRACE_PROVIDE_OBJECT : true); $i = count($trace); while (isset($trace[--$i]['class']) && ('ReflectionMethod' === $trace[$i]['class'] || 0 === strpos($trace[$i]['class'], 'PHPUnit_'))) { // Nothing to do } $group = $type === E_USER_DEPRECATED ? 'user' : 'php'; if (isset($trace[$i]['object']) || isset($trace[$i]['class'])) { $class = isset($trace[$i]['object']) ? get_class($trace[$i]['object']) : $trace[$i]['class']; $method = $trace[$i]['function']; $ref =& $deprecations[$group][$msg]['count']; $ref++; $ref =& $deprecations[$group][$msg][$class . '::' . $method]; $ref++; } else { $ref =& $deprecations[$group][$msg]['count']; $ref++; } $deprecations[$group . 'Count']++; }; $oldErrorHandler = set_error_handler($deprecationHandler); if (null !== $oldErrorHandler) { restore_error_handler(); if (array('PHPUnit_Util_ErrorHandler', 'handleError') === $oldErrorHandler) { restore_error_handler(); self::register(); } } else { self::$isDeprecationHandlerRegistered = true; if (self::hasColorSupport()) { $colorize = function ($str, $red) { $color = $red ? '41;37' : '43;30'; return "[{$color}m{$str}[0m"; }; } else { $colorize = function ($str) { return $str; }; } register_shutdown_function(function () use(&$deprecations, $deprecationHandler, $colorize) { $currErrorHandler = set_error_handler('var_dump'); restore_error_handler(); if ($currErrorHandler !== $deprecationHandler) { echo "\n", $colorize('THE ERROR HANDLER HAS CHANGED!', true), "\n"; } $cmp = function ($a, $b) { return $b['count'] - $a['count']; }; foreach (array('php', 'user') as $group) { if ($deprecations[$group . 'Count']) { echo "\n", $colorize(sprintf('%s deprecation notices (%d)', ucfirst($group), $deprecations[$group . 'Count']), true), "\n"; uasort($deprecations[$group], $cmp); foreach ($deprecations[$group] as $msg => $notices) { echo "\n", rtrim($msg, '.'), ': ', $notices['count'], "x\n"; arsort($notices); foreach ($notices as $method => $count) { if ('count' !== $method) { echo ' ', $count, 'x in ', preg_replace('/(.*)\\\\(.*?::.*?)$/', '$2 from $1', $method), "\n"; } } } } } if (!empty($notices)) { echo "\n"; } }); } }