1<?php 2/* 3 * This file is part of PHPUnit. 4 * 5 * (c) Sebastian Bergmann <sebastian@phpunit.de> 6 * 7 * For the full copyright and license information, please view the LICENSE 8 * file that was distributed with this source code. 9 */ 10 11// Workaround for http://bugs.php.net/bug.php?id=47987, 12// see https://github.com/sebastianbergmann/phpunit/issues#issue/125 for details 13// Use dirname(__DIR__) instead of using /../ because of https://github.com/facebook/hhvm/issues/5215 14require_once dirname(__DIR__) . '/Framework/Error.php'; 15require_once dirname(__DIR__) . '/Framework/Error/Notice.php'; 16require_once dirname(__DIR__) . '/Framework/Error/Warning.php'; 17require_once dirname(__DIR__) . '/Framework/Error/Deprecated.php'; 18 19/** 20 * Error handler that converts PHP errors and warnings to exceptions. 21 */ 22class PHPUnit_Util_ErrorHandler 23{ 24 protected static $errorStack = []; 25 26 /** 27 * Returns the error stack. 28 * 29 * @return array 30 */ 31 public static function getErrorStack() 32 { 33 return self::$errorStack; 34 } 35 36 /** 37 * @param int $errno 38 * @param string $errstr 39 * @param string $errfile 40 * @param int $errline 41 * 42 * @throws PHPUnit_Framework_Error 43 */ 44 public static function handleError($errno, $errstr, $errfile, $errline) 45 { 46 if (!($errno & error_reporting())) { 47 return false; 48 } 49 50 self::$errorStack[] = [$errno, $errstr, $errfile, $errline]; 51 52 $trace = debug_backtrace(false); 53 array_shift($trace); 54 55 foreach ($trace as $frame) { 56 if ($frame['function'] == '__toString') { 57 return false; 58 } 59 } 60 61 if ($errno == E_NOTICE || $errno == E_USER_NOTICE || $errno == E_STRICT) { 62 if (PHPUnit_Framework_Error_Notice::$enabled !== true) { 63 return false; 64 } 65 66 $exception = 'PHPUnit_Framework_Error_Notice'; 67 } elseif ($errno == E_WARNING || $errno == E_USER_WARNING) { 68 if (PHPUnit_Framework_Error_Warning::$enabled !== true) { 69 return false; 70 } 71 72 $exception = 'PHPUnit_Framework_Error_Warning'; 73 } elseif ($errno == E_DEPRECATED || $errno == E_USER_DEPRECATED) { 74 if (PHPUnit_Framework_Error_Deprecated::$enabled !== true) { 75 return false; 76 } 77 78 $exception = 'PHPUnit_Framework_Error_Deprecated'; 79 } else { 80 $exception = 'PHPUnit_Framework_Error'; 81 } 82 83 throw new $exception($errstr, $errno, $errfile, $errline); 84 } 85 86 /** 87 * Registers an error handler and returns a function that will restore 88 * the previous handler when invoked 89 * 90 * @param int $severity PHP predefined error constant 91 * 92 * @throws Exception if event of specified severity is emitted 93 */ 94 public static function handleErrorOnce($severity = E_WARNING) 95 { 96 $terminator = function () { 97 static $expired = false; 98 if (!$expired) { 99 $expired = true; 100 // cleans temporary error handler 101 return restore_error_handler(); 102 } 103 }; 104 105 set_error_handler(function ($errno, $errstr) use ($severity) { 106 if ($errno === $severity) { 107 return; 108 } 109 110 return false; 111 }); 112 113 return $terminator; 114 } 115} 116