From 98f3ea1b47dda8006a12bdeb96b5f3d511802eef Mon Sep 17 00:00:00 2001 From: JustInVTime Date: Tue, 4 Mar 2014 00:10:23 +0100 Subject: [PATCH 1/3] Added registerFatalErrorShutdownFunction and test --- library/Zend/Log/Logger.php | 46 +++++++++++++++++++++++++++++++ tests/ZendTest/Log/LoggerTest.php | 25 +++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/library/Zend/Log/Logger.php b/library/Zend/Log/Logger.php index 5476edd74e9..c94387716a4 100644 --- a/library/Zend/Log/Logger.php +++ b/library/Zend/Log/Logger.php @@ -60,6 +60,13 @@ class Logger implements LoggerInterface */ protected static $registeredErrorHandler = false; + /** + * Registered shutdown error handler + * + * @var bool + */ + protected static $registeredFatalErrorShutdownFunction = false; + /** * Registered exception handler * @@ -154,6 +161,10 @@ public function __construct($options = null) static::registerErrorHandler($this); } + if (isset($options['fatal_error_shutdownfunction']) && $options['fatal_error_shutdownfunction'] === true) { + static::registerFatalErrorShutdownFunction($this); + } + } elseif ($options) { throw new Exception\InvalidArgumentException('Options must be an array or an object implementing \Traversable '); } @@ -554,6 +565,41 @@ public static function unregisterErrorHandler() static::$registeredErrorHandler = false; } + + /** + * Register a shutdown handler to log fatal errors + * + * @link http://www.php.net/manual/function.register-shutdown-function.php + * @param Logger $logger + * @return bool + */ + public static function registerFatalErrorShutdownFunction(Logger $logger) + { + // Only register once per instance + if (static::$registeredFatalErrorShutdownFunction) { + return false; + } + + $errorPriorityMap = static::$errorPriorityMap; + + register_shutdown_function(function () use ($logger, $errorPriorityMap) { + $error = error_get_last(); + if (null !== $error && $error['type'] === E_ERROR) { + $logger->log($errorPriorityMap[E_ERROR], + $error['message'], + array( + 'file' => $error['file'], + 'line' => $error['line'] + ) + ); + } + }); + + static::$registeredFatalErrorShutdownFunction = true; + return true; + } + + /** * Register logging system as an exception handler to log PHP exceptions * diff --git a/tests/ZendTest/Log/LoggerTest.php b/tests/ZendTest/Log/LoggerTest.php index a2c98b498a0..112f08b2162 100644 --- a/tests/ZendTest/Log/LoggerTest.php +++ b/tests/ZendTest/Log/LoggerTest.php @@ -410,4 +410,29 @@ public function testErrorHandlerWithStreamWriter() $this->assertContains('test', $contents); $this->assertContains('second', $contents); } + + /** + * @runInSeparateProcess + */ + public function testRegisterFatalShutdownFunction() + { + $writer = new MockWriter; + $this->logger->addWriter($writer); + + $result = Logger::registerFatalErrorShutdownFunction($this->logger); + $this->assertTrue($result); + + // check for single error handler instance + $this->assertFalse(Logger::registerFatalErrorShutdownFunction($this->logger)); + + $self = $this; + register_shutdown_function(function () use ($writer, $self) { + ini_set('display_errors', true); + $self->assertEquals($writer->events[0]['message'], 'Call to undefined method ZendTest\Log\LoggerTest::callToNonExistingMethod()'); + }); + + // Temporary hide errors, because we don't want the fatal error to fail the test + ini_set('display_errors', false); + $this->callToNonExistingMethod(); + } } From d487eee1e60ad406c78c564e3948e3bada3f6dd4 Mon Sep 17 00:00:00 2001 From: JustInVTime Date: Tue, 4 Mar 2014 00:31:04 +0100 Subject: [PATCH 2/3] Suppress error --- tests/ZendTest/Log/LoggerTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/ZendTest/Log/LoggerTest.php b/tests/ZendTest/Log/LoggerTest.php index 112f08b2162..86070a9b391 100644 --- a/tests/ZendTest/Log/LoggerTest.php +++ b/tests/ZendTest/Log/LoggerTest.php @@ -432,7 +432,6 @@ public function testRegisterFatalShutdownFunction() }); // Temporary hide errors, because we don't want the fatal error to fail the test - ini_set('display_errors', false); - $this->callToNonExistingMethod(); + @$this->callToNonExistingMethod(); } } From af3a04aec36647b865423311989228cd583fe301 Mon Sep 17 00:00:00 2001 From: JustInVTime Date: Tue, 4 Mar 2014 00:43:12 +0100 Subject: [PATCH 3/3] Removed ini_set call in shutdown function --- tests/ZendTest/Log/LoggerTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/ZendTest/Log/LoggerTest.php b/tests/ZendTest/Log/LoggerTest.php index 86070a9b391..219a43edc4f 100644 --- a/tests/ZendTest/Log/LoggerTest.php +++ b/tests/ZendTest/Log/LoggerTest.php @@ -427,7 +427,6 @@ public function testRegisterFatalShutdownFunction() $self = $this; register_shutdown_function(function () use ($writer, $self) { - ini_set('display_errors', true); $self->assertEquals($writer->events[0]['message'], 'Call to undefined method ZendTest\Log\LoggerTest::callToNonExistingMethod()'); });