3v4l.org

run code in 300+ PHP versions simultaneously
<?php class ErrorHandler { /** * Error number constant used when an error is silenced by use of the error * control operator '@'. * * @var int */ const E_SILENCED_ERROR = 0; /** * Chain before * @var string */ const CHAIN_BEFORE = 'before'; /** * Chain after * @var string */ const CHAIN_AFTER = 'after'; /** * Don't chain * @var bool */ const CHAIN_NONE = false; /** * @var string|bool */ private $_chainPreviousHandler = self::CHAIN_AFTER; /** * Gets if the previous handler will be called. Values are: before, after, false * @return string|bool */ public function getChainPreviousHandler() { return $this->_chainPreviousHandler; } /** * Sets if the previous handler will be called. Values are: before, after, false * @param string|bool $chainPreviousHandler */ public function setChainPreviousHandler($chainPreviousHandler) { $this->_chainPreviousHandler = $chainPreviousHandler; } /** * @var bool */ private $_usePhpDefaultBehaviour = true; /** * Gets if the default PHP behaviour for errors will be allowed at the end * of the error handling. * @return bool */ public function isUsePhpDefaultBehaviour() { return $this->_usePhpDefaultBehaviour; } /** * Sets if the default PHP behaviour for errors will be allowed at the end * of the error handling. * @param bool $usePhpDefaultBehaviour */ public function setUsePhpDefaultBehaviour($usePhpDefaultBehaviour) { $this->_usePhpDefaultBehaviour = $usePhpDefaultBehaviour; } /** * @var bool */ private $_convertErrorsToExceptions = true; /** * Gets if this handler will convert recoverable errors to exceptions * @return bool */ public function isConvertErrorsToExceptions() { return $this->_convertErrorsToExceptions; } /** * Sets if this handler will convert recoverable errors to exceptions * @param bool $convertErrorsToExceptions */ protected function setConvertErrorsToExceptions($convertErrorsToExceptions) { $this->_convertErrorsToExceptions = $convertErrorsToExceptions; } /** * Array of default errors converted to exceptions. * @var array */ private $_errorsToExceptions = array( self::E_SILENCED_ERROR, // Silenced errors E_USER_ERROR, E_RECOVERABLE_ERROR); /** * Gets an array with all the error numbers to be converted to exceptions * @return array */ public function getErrorsToExceptions() { return $this->_errorsToExceptions; } /** * Sets an array with all the error numbers to be converted to exceptions * @param array $errorsToExceptions */ public function setErrorsToExceptions(array $errorsToExceptions) { $this->_errorsToExceptions = $errorsToExceptions; } /** * Adds errors to the array of errors that will throw an exception * @param array $errorsToExceptions */ public function addErrorsToExceptions(array $errorsToExceptions) { foreach($errorsToExceptions as $pos => $errorNumber) { if (!in_array($errorNumber, $this->_errorsToExceptions)) { $this->_errorsToExceptions[] = $errorNumber; } } } /** * @var bool */ private $_registered = false; /** * Gets if this class was registered to be the default error handler for * php errors. * @return bool */ public function isRegistered() { return $this->_registered; } /** * Sets if this class was registered to be the default error handler for * php errors. * @param bool $registered */ protected function setRegistered($registered) { $this->_registered = $registered; } /** * @var mixed */ private $_previousHandler = null; /** * Gets the previously set global error handler * @return mixed */ public function getPreviousErrorHandler() { return $this->_previousHandler; } /** * Sets the previously set global error handler * @param mixed $previousHandler */ protected function setPreviousErrorHandler($previousHandler) { $this->_previousHandler = $previousHandler; } /** * @var array */ private $_errorHandlers = array(); /** * Gets stack of error handlers * @return array */ public function getErrorHandlers() { return $this->_errorHandlers; } /** * Adds a handler to the stack of error handlers * @param callable $errorHandler */ public function addErrorHandler(callable $errorHandler) { // Avoid duplicated error handlers $this->removeErrorHandler($errorHandler); $this->_errorHandlers[]= $errorHandler; } /** * Remove the error handler comparing the one provided with the ones stored. * It does not affect the previous error handler. * @param callable $errorHandler * @return boolean True if an error handler was found and removed or false * if not. */ public function removeErrorHandler($errorHandler) { $type = gettype($errorHandler); $found = false; foreach($this->_errorHandlers as $pos => $existingErrorHandler) { if ($type != gettype($existingErrorHandler)) { continue; } $remove = false; if ($type == 'string' && $errorHandler == $existingErrorHandler) { $found = true; } else if ($type == 'array' && $errorHandler[0] == $existingErrorHandler[0] && $errorHandler[1] == $existingErrorHandler[1]) { $found = true; } else if (is_object($errorHandler) && $errorHandler == $existingErrorHandler) { $found = true; } if ($remove) { unset($this->_errorHandlers[$pos]); $found = true; break; } } return $found; } /** * Finds the name of an error constant. * * @param int $error * @return string | false */ public function getErrorName($error) { $constants = get_defined_constants(); $name = array_search($error, $constants, true); return $name; } /** * Calls every error handler passing in the arguments. * * If an error handler throws an exception the rest of error handlers will * not be called. * * If this class is set as the default error handler the previous handler * will be called after all handlers have been called. * * Error handlers must conform to standard error handler signature for * set_error_handler function but with an additional optional parameter * whose value will be this same instance. * * This method follows the following order: * 1- Execute previous error handler (only uf previous error handler is * chained before) * 2- Execute error handlers * 3- Execute previous error handler (only uf previous error handler is * chained after) * 4- Throw exceptions for errors (optional) * 5- Call PHP's default error handler if configured to do so. * * Error handlers should not raise more errors but they can throw exceptions * as they will not be handled in this method so they can be handled * upstream. * * @param int $errorNumber * @param string $errorMessage * @param string $file * @param int $line * @param array $context * @throws \ErrorException When error to exception conversion is enabled * @throws \Exception When any error handler throws it * @return bool */ public function handleError($errorNumber, $errorMessage, $file, $line, $context) { $errorParams = array( $errorNumber, $errorMessage, $file, $line, $context, $this ); if ($this->_previousHandler && $this->_chainPreviousHandler == self::CHAIN_BEFORE) { call_user_func_array($this->_previousHandler, $errorParams); } foreach($this->_errorHandlers as $errorHandler) { call_user_func_array($errorHandler, $errorParams); } if ($this->_previousHandler && $this->_chainPreviousHandler == self::CHAIN_AFTER) { call_user_func_array($this->_previousHandler, $errorParams); } // The last thing we do is throwing ourselves an exception in the // error handler as this will halt execution and we need to call // all error handlers first. if ($this->_convertErrorsToExceptions) { $this->throwErrorException($errorNumber, $errorMessage, $file, $line, $context); } if ($this->_usePhpDefaultBehaviour) { return false; } else { return true; } } /** * Throws an ErrorException with the given information. * * This method does not honors error_reporting setting and will throw an * exception for every configured error number as it makes no sense to * convert a certain error to an exception and then allow it to be * "silenced". * * @param int $errorNumber * @param string $errorMessage * @param string $file * @param int $line * @param array $context * @throws \ErrorException Always */ protected function throwErrorException($errorNumber, $errorMessage, $file, $line, array $context) { if (in_array($errorNumber, $this->_errorsToExceptions)) { throw new \ErrorException( $errorMessage, $errorNumber, 0, $file, $line); } } /** * Registers this instance to handle PHP's errors (recoverable ones only) * @throws \Exception If the error handler is registered twice for some * reason. * @return boolean True if this handler was not registered, false if it * was. */ public function registerErrorHandler() { if ($this->_registered) { return false; } $previousHandler = set_error_handler(array($this, 'handleError')); if (is_array($previousHandler) && !empty($previousHandler) && $previousHandler[0] === $this) { throw new \Exception("Error handler registered twice!"); } $this->_previousHandler = $previousHandler; $this->_registered = true; return true; } /** * Unregisters this instance if it was set to handle PHP's errors * @return boolean True if this handler was registered, false if it doesn't. */ public function unregisterErrorHandler() { if (!$this->_registered) { return false; } // If one or more error handlers were set after we registered our own // this will pop the last one set and leave our own one in the stack // :( restore_error_handler(); $this->_registered = false; $this->_previousHandler = null; return true; } }

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
8.3.60.0090.00918.30
8.3.50.0110.00717.93
8.3.40.0070.00718.75
8.3.30.0100.00718.93
8.3.20.0050.00320.34
8.3.10.0050.00321.76
8.3.00.0070.00719.20
8.2.180.0090.00918.16
8.2.170.0120.00322.96
8.2.160.0100.01022.08
8.2.150.0100.00624.18
8.2.140.0090.00924.66
8.2.130.0100.01026.16
8.2.120.0070.00319.12
8.2.110.0120.00620.52
8.2.100.0000.01117.97
8.2.90.0080.00018.95
8.2.80.0030.00617.97
8.2.70.0030.00617.50
8.2.60.0040.00417.80
8.2.50.0030.00618.07
8.2.40.0090.00018.16
8.2.30.0050.00318.04
8.2.20.0090.00017.49
8.2.10.0000.00817.89
8.2.00.0000.01017.48
8.1.280.0040.01125.92
8.1.270.0030.00618.82
8.1.260.0070.00026.35
8.1.250.0000.00728.09
8.1.240.0030.00624.00
8.1.230.0060.00619.48
8.1.220.0080.00017.74
8.1.210.0060.00318.77
8.1.200.0060.00317.35
8.1.190.0030.00617.23
8.1.180.0040.00418.10
8.1.170.0040.00418.64
8.1.160.0000.00822.05
8.1.150.0040.00418.84
8.1.140.0030.00519.17
8.1.130.0030.00517.70
8.1.120.0000.00817.29
8.1.110.0000.00917.42
8.1.100.0000.00717.34
8.1.90.0050.00217.44
8.1.80.0020.00517.29
8.1.70.0000.00717.38
8.1.60.0000.00917.50
8.1.50.0060.00617.47
8.1.40.0040.00417.45
8.1.30.0080.00017.58
8.1.20.0050.00317.59
8.1.10.0080.00017.40
8.1.00.0040.00417.23
8.0.300.0080.00018.77
8.0.290.0000.00916.63
8.0.280.0040.00418.43
8.0.270.0040.00417.06
8.0.260.0030.00317.10
8.0.250.0030.00316.94
8.0.240.0070.00016.76
8.0.230.0000.00816.89
8.0.220.0000.00716.91
8.0.210.0000.00716.89
8.0.200.0030.00716.85
8.0.190.0040.00416.75
8.0.180.0040.00416.90
8.0.170.0040.00416.88
8.0.160.0000.00716.75
8.0.150.0030.00516.68
8.0.140.0040.00316.76
8.0.130.0050.00313.21
8.0.120.0040.00416.82
8.0.110.0030.00516.80
8.0.100.0030.00616.71
8.0.90.0000.00716.89
8.0.80.0180.00616.82
8.0.70.0050.00316.84
8.0.60.0060.00316.77
8.0.50.0000.00716.62
8.0.30.0130.01016.99
8.0.20.0150.00517.40
8.0.10.0060.00316.84
8.0.00.0080.01116.74
7.4.330.0020.00215.03
7.4.320.0000.00616.39
7.4.300.0070.00016.44
7.4.290.0040.00416.43
7.4.280.0000.00816.32
7.4.270.0030.00316.54
7.4.260.0000.01016.47
7.4.250.0090.00016.30
7.4.240.0020.00516.45
7.4.230.0000.00816.63
7.4.220.0060.01316.59
7.4.210.0120.00316.33
7.4.200.0030.00316.33
7.4.160.0060.01016.22
7.4.150.0090.00917.40
7.4.140.0150.01017.86
7.4.130.0100.00716.49
7.4.120.0070.01016.52
7.4.110.0150.00416.59
7.4.100.0080.01216.54
7.4.90.0100.00716.32
7.4.80.0060.01119.39
7.4.70.0130.00316.32
7.4.60.0150.00016.53
7.4.50.0080.00016.33
7.4.40.0030.01316.38
7.4.30.0160.00616.33
7.4.00.0030.00714.69
7.3.330.0050.00013.31
7.3.320.0030.00313.30
7.3.310.0030.00316.16
7.3.300.0040.00216.06
7.3.290.0090.00716.28
7.3.280.0060.01116.22
7.3.270.0000.02017.40
7.3.260.0110.00716.10
7.3.250.0070.01316.31
7.3.240.0070.01116.31
7.3.230.0060.01216.39
7.3.210.0070.01016.28
7.3.200.0030.01319.39
7.3.190.0120.00616.23
7.3.180.0130.00316.25
7.3.170.0070.01316.29
7.3.160.0170.00016.40
7.3.10.0030.00916.50
7.3.00.0030.01016.51
7.2.330.0100.00716.26
7.2.320.0110.00516.55
7.2.310.0150.00616.36
7.2.300.0060.01216.53
7.2.290.0130.01116.48
7.2.130.0070.00716.62
7.2.120.0070.00316.52
7.2.110.0000.01316.64
7.2.100.0030.00616.33
7.2.90.0030.00716.60
7.2.80.0070.01116.81
7.2.70.0060.01016.70
7.2.60.0090.00316.27
7.2.50.0000.01216.68
7.2.40.0030.01016.30
7.2.30.0030.00916.39
7.2.20.0060.00916.36
7.2.10.0070.00316.39
7.2.00.0090.00417.81
7.1.250.0040.00415.49
7.1.100.0000.01117.86
7.1.70.0030.00716.68
7.1.60.0070.01719.46
7.1.50.0000.02316.85
7.1.00.0030.07722.46
7.0.200.0040.00816.44
7.0.140.0030.06322.05
7.0.100.0270.06720.03
7.0.90.0000.04320.01
7.0.80.0130.06720.23
7.0.70.0100.06020.03
7.0.60.0030.08320.02
7.0.50.0070.03720.39
7.0.40.0200.07020.00
7.0.30.0100.08020.14
7.0.20.0200.07320.08
7.0.10.0100.08320.06
7.0.00.0030.08720.03
5.6.280.0030.07321.12
5.6.250.0100.06320.77
5.6.240.0200.06320.67
5.6.230.0070.06020.65
5.6.220.0030.05320.58
5.6.210.0100.07320.82
5.6.200.0070.05321.02
5.6.190.0030.07321.03
5.6.180.0100.03321.07
5.6.170.0070.08721.11
5.6.160.0070.06720.98
5.6.150.0170.07321.10
5.6.140.0100.06021.18
5.6.130.0100.07721.10
5.6.120.0030.04321.11
5.6.110.0030.08021.10
5.6.100.0130.07021.12
5.6.90.0130.07320.97
5.6.80.0030.05020.40
5.6.70.0100.06320.45
5.6.60.0070.03720.38
5.6.50.0030.07720.55
5.6.40.0030.08320.34
5.6.30.0100.07320.46
5.6.20.0100.07720.42
5.6.10.0070.07720.48
5.6.00.0030.08320.34
5.5.380.0100.06720.50
5.5.370.0030.04320.47
5.5.360.0070.04020.53
5.5.350.0030.04020.52
5.5.340.0030.07320.86
5.5.330.0070.04020.95
5.5.320.0070.07020.81
5.5.310.0170.08720.96
5.5.300.0070.08320.95
5.5.290.0000.08320.92
5.5.280.0100.04020.85
5.5.270.0070.04720.95
5.5.260.0030.04720.78
5.5.250.0170.05320.70
5.5.240.0070.06320.22
5.5.230.0000.04320.33
5.5.220.0070.07020.34
5.5.210.0070.07020.29
5.5.200.0030.08320.21
5.5.190.0070.07320.32
5.5.180.0100.07320.28
5.5.160.0100.07020.20
5.5.150.0170.07020.18
5.5.140.0200.05720.24
5.5.130.0070.07720.28
5.5.120.0030.04720.27
5.5.110.0030.04020.30
5.5.100.0070.05020.07
5.5.90.0030.04320.13
5.5.80.0100.06720.13
5.5.70.0000.05020.11
5.5.60.0000.06320.20
5.5.50.0070.03320.25
5.5.40.0030.06020.15
5.5.30.0170.03720.20
5.5.20.0030.09020.07
5.5.10.0130.05020.02
5.5.00.0070.05320.13
5.4.450.0030.08319.36
5.4.440.0030.08719.47
5.4.430.0000.04319.37
5.4.420.0070.07719.45
5.4.410.0000.06019.36
5.4.400.0000.08719.05
5.4.390.0000.04718.87
5.4.380.0070.07319.12
5.4.370.0170.07319.09
5.4.360.0100.07319.13
5.4.350.0070.07719.18
5.4.340.0000.07019.23
5.4.320.0000.08019.14
5.4.310.0000.07019.10
5.4.300.0030.06718.84
5.4.290.0000.04319.12
5.4.280.0100.07318.88
5.4.270.0130.06719.03
5.4.260.0030.06018.87
5.4.250.0070.07318.90
5.4.240.0070.03719.16
5.4.230.0070.08019.13
5.4.220.0070.07319.04
5.4.210.0030.06719.16
5.4.200.0100.07318.84
5.4.190.0030.08319.20
5.4.180.0170.06719.13
5.4.170.0100.05318.94
5.4.160.0070.06319.16
5.4.150.0000.07718.88
5.4.140.0000.07316.45
5.4.130.0100.06716.38
5.4.120.0100.05016.30
5.4.110.0070.04316.57
5.4.100.0130.06316.54
5.4.90.0100.05016.47
5.4.80.0100.03316.51
5.4.70.0000.05016.38
5.4.60.0070.07016.46
5.4.50.0070.06716.45
5.4.40.0030.06316.49
5.4.30.0070.06316.49
5.4.20.0130.06716.35
5.4.10.0000.06716.51
5.4.00.0070.03315.83

preferences:
49.48 ms | 400 KiB | 5 Q