From cab3ff71ffc802af272928ff71341cfc51e8ee98 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 26 Nov 2015 23:48:42 +0000 Subject: [PATCH] Add regression test for #691 and optimize implementation using a single pass loop over the handlers, refs #692 --- src/Monolog/Logger.php | 19 +++++++++--------- tests/Monolog/LoggerTest.php | 39 ++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/Monolog/Logger.php b/src/Monolog/Logger.php index de79b2f9..82f34133 100644 --- a/src/Monolog/Logger.php +++ b/src/Monolog/Logger.php @@ -280,11 +280,14 @@ class Logger implements LoggerInterface // check if any handler will handle this message so we can return early and save cycles $handlerKey = null; - foreach ($this->handlers as $key => $handler) { + reset($this->handlers); + while ($handler = current($this->handlers)) { if ($handler->isHandling(array('level' => $level))) { - $handlerKey = $key; + $handlerKey = key($this->handlers); break; } + + next($this->handlers); } if (null === $handlerKey) { @@ -315,17 +318,13 @@ class Logger implements LoggerInterface foreach ($this->processors as $processor) { $record = call_user_func($processor, $record); } - $foundStartingKey = false; - foreach ($this->handlers as $key => $handler) { - if ($key === $handlerKey) { - $foundStartingKey = true; - } - if ($foundStartingKey === false) { - continue; - } + + while ($handler = current($this->handlers)) { if (true === $handler->handle($record)) { break; } + + next($this->handlers); } return true; diff --git a/tests/Monolog/LoggerTest.php b/tests/Monolog/LoggerTest.php index 3194838e..fee98040 100644 --- a/tests/Monolog/LoggerTest.php +++ b/tests/Monolog/LoggerTest.php @@ -303,6 +303,45 @@ class LoggerTest extends \PHPUnit_Framework_TestCase $logger->debug('test'); } + /** + * @covers Monolog\Logger::addRecord + */ + public function testHandlersNotCalledBeforeFirstHandlingWithAssocArray() + { + $handler1 = $this->getMock('Monolog\Handler\HandlerInterface'); + $handler1->expects($this->never()) + ->method('isHandling') + ->will($this->returnValue(false)) + ; + $handler1->expects($this->once()) + ->method('handle') + ->will($this->returnValue(false)) + ; + + $handler2 = $this->getMock('Monolog\Handler\HandlerInterface'); + $handler2->expects($this->once()) + ->method('isHandling') + ->will($this->returnValue(true)) + ; + $handler2->expects($this->once()) + ->method('handle') + ->will($this->returnValue(false)) + ; + + $handler3 = $this->getMock('Monolog\Handler\HandlerInterface'); + $handler3->expects($this->once()) + ->method('isHandling') + ->will($this->returnValue(false)) + ; + $handler3->expects($this->never()) + ->method('handle') + ; + + $logger = new Logger(__METHOD__, array('last' => $handler3, 'second' => $handler2, 'first' => $handler1)); + + $logger->debug('test'); + } + /** * @covers Monolog\Logger::addRecord */