2011-05-16 80 views
1

我目前正在从我们自己的专有日志记录解决方案迁移到log4php。
我们在项目中只使用静态方法来使用很多类。该文档定义了基本的使用情况,如:在静态环境中使用log4php

class MyClass { 
    private $logger; 

    public function __construct() { 
     $this->logger = Logger::getLogger(__CLASS__); 
     $this->logger->debug('currently in constructor'); 
    } 
} 

但我不能使用,因为我需要在$logger静态上下文是可用的。制作$logger静态也没有帮助,因为我的类的构造函数从不被调用(因为它的所有成员都是静态的)。
该文档告诉我为该成员使用静态初始化器。但是,我必须记得为所有我使用的课程调用它。这似乎太容易出错。

于是我想出了这一点:

class Foo { 
    private static $logger = null; 
    private static function logger() { 
    if(null == self::$logger) self::$logger = Logger::getLogger(__CLASS__); 
    return self::$logger; 
    } 

    public static function bar() { 
    self::logger()->debug("test"); 
    } 
} 

Foo::bar(); 

但是,似乎有太多的开销为好。那么,有什么建议?

回答

0

我想出了一个解决方案,工作得很好,但需要$logger公开。

class Foo { 
    public static $logger = null; 

    public static function bar() { 
    self::$logger->debug("test"); 
    } 
} 

$loggerName = "logger"; 
// Iterate over all declared classes 
$classes = get_declared_classes(); 
foreach($classes as $class) { 
    $reflection = new ReflectionClass($class); 

    // If the class is internally defined by PHP or has no property called "logger", skip it. 
    if($reflection->isInternal() || !$reflection->hasProperty($loggerName)) continue; 

    // Get information regarding the "logger" property of this class. 
    $property = new ReflectionProperty($class, $loggerName); 

    // If the "logger" property is not static or not public, then it is not the one we are interested in. Skip this class. 
    if(!$property->isStatic() || !$property->isPublic()) continue; 

    // Initialize the logger for this class. 
    $reflection->setStaticPropertyValue($loggerName, Logger::getLogger($class)); 
} 

此我只需要定义$logger财产每班一次,运行一次我的初始化代码(我在我的应用程序的入口点的require_once节过后猜测)。

该代码的性能影响可以忽略不计,特别是因为它只运行一次(与我的初始解决方案相比)。这是我一个VirtualBox的虚拟机内测量了英特尔酷Q9450 2.66GHz的@:

10000 iterations for 157 classes completed in 2.6794s. Average per iteration: 0.00026794s 
+0

你的方法有一个很大的缺点:与自动加载,这将无法工作,因为类后,他们的第一只宣布的环境使用。另外,在某处推送记录器是一种不好的编码模式。最好让班级要求并注入。 – Sven 2012-10-12 23:53:05