静的コンテキストでlog4phpを使用してください
質問
現在、私たち自身の独自のロギングソリューションからlog4phpに移動する過程にあります。
私たちのプロジェクトでは静的メソッドだけで多くのクラスを使用します。マニュアルは基本的なユースケースのようなものを定義します。
class MyClass {
private $logger;
public function __construct() {
$this->logger = Logger::getLogger(__CLASS__);
$this->logger->debug('currently in constructor');
}
}
.
しかし、それを使用することはできません、原因は静的なコンテキストでも$logger
も利用できます。$logger
Staticも同様に、Classのコンストラクタは呼び出されないため(すべてのメンバーが静的なので)
ドキュメントは、そのメンバーの静的イニシャライザを使用するように指示します。しかし、私は私が使用するすべてのクラスに対してそれを呼び出すことを忘れないでください。そしてそれはエラーが発生しやすいようです。
だから私はこれを思い付きました:
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();
.
しかし、それはあまりにも多くのオーバーヘッドのように思えます。だから、何か提案?
解決
私はかなりうまく機能するものがあるが、Publicになるために$logger
を必要とする1つの解決策を思い付きました。
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 ) );
}
.
これは、クラスごとに1回$logger
プロパティを定義し、初期化コードを1回実行する必要があります(私のアプリケーションのエントリポイントのrequire_once
セクションの後に推測)。
そのコードのパフォーマンスへの影響は、特に一度だけ実行されるため(最初の解決策と比較して)ごくわずかです。これはIntel Core2 Q9450 @ 2.66GHzのVirtialBox VM内で測定したものです。
10000 iterations for 157 classes completed in 2.6794s. Average per iteration: 0.00026794s
. 所属していません StackOverflow