我目前正在从我们自己的专有日志记录解决方案转向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 :(得分: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
部分之后)。
该代码对性能的影响可以忽略不计,特别是因为它只运行一次(与我的初始解决方案相比)。这是我在Intel Core2 Q9450 @ 2.66GHz上的VirtualBox VM中测量的内容:
10000 iterations for 157 classes completed in 2.6794s. Average per iteration: 0.00026794s