在Zend框架应用程序中记录设计模式

Son*_*ngo 9 php logging design-patterns zend-framework

我正在使用Zend Framework构建应用程序.该应用程序需要密集记录代码中的每个操作或功能.

所以我的代码大部分时间都是这样的:

function SendMailsAction(){
      $logger->log('Started sending mails.')
...
...
...Some Code...
...
...

foreach ($mails as $mail){
  try{      
       $logger->log('Trying to send')
       $mail->send()
       $logger->log('Mail sent successfully.')
  }catch(Exception $e){
       $logger->log('Failed to send mail.')
      }      
 }

...
...
...Some Code...
...
...
       $logger->log('Finished sending mails.')
}
Run Code Online (Sandbox Code Playgroud)

有时我甚至必须登录2个表,因此大多数日志记录代码加倍,并且函数开始变得复杂和冗长.

我使用Zend框架Zend_Log进行日志记录,所以我的问题不是日志记录类本身,而是如何将日志记录代码与代码功能本身分开并保持关注点的分离.

有些人建议使用面向方面编程(AOP),但遗憾的是AOP for PHP对我的客户来说是不可接受的,所以我正在寻找面向对象的解决方案或最佳实践.

注意:

只是为了弄清楚我的问题不是如何使用Zend_Log,而是如何将日志记录添加到我的应用程序代码中.

Ber*_*rak 5

有时我甚至必须登录2个表,因此大多数日志记录代码加倍,并且函数开始变得复杂和冗长.

它会很长.如果您的代码进行了大量的日志记录,那么它将很长,因为它必须记录,并且它记录的每个行操作都意味着代码中有一行.但是,它不应该是复杂的,因为日志记录是你可以做的最直接的事情之一.令我担心的是,你提到"有时我甚至必须登录2张桌子".在我的书,一,二,五,六十或千表,则是由一个线.每个记录器的代码不会加倍.如果你是复制粘贴一行,并$log改为$log2,你显然做错了(tm).

有些人建议使用面向方面编程(AOP),但遗憾的是AOP for PHP对我的客户来说是不可接受的,所以我正在寻找面向对象的解决方案或最佳实践.

很好,AOP.但它有缺点; 与debug_backtrace方法一样,性能受到重创.这一点,加上代码变得越来越"神奇",因为当你查看代码本身时,它会做一些不明确的事情.这会增加您调试应用程序的时间.

我的0.02美元?首先,不要重复自己:每个操作一个日志条目就足够了.使用可在运行时附加到某些类的灵活记录器.根据"严重性"或"类型" 决定是否在记录器中实际记录消息.总而言之,只需实现Observer模式:

<?php

namespace Foo;

class MailService {
    public function attach( Observes $observer ) {
        $this->observers[] = $observer;
    }

    public function notify( $message, $type = 'notice' ) {
        foreach( $this->observers as $observer ) {
            $observer->notify( $message, $type );
        }
    }

    public function sendMail( ) {
        $this->notify( 'Started sending mails', 'debug' );
        $mails = array( );
        foreach( $mails as $mail ) {
            try {
                $this->notify( 'Trying to send', 'debug' );
                $mail->send( );
                $this->notify( 'Mail sent succesfully', 'debug' );
            }
            catch( Exception $e ) {
                $this->notify( 'Failed to send mail', 'notice' );
            }
        }
        $this->notify( 'Finished sending mail', 'debug' );
    }
}

interface Observes {
    public function notify( $message, $type = 'notice' );
}

abstract class Logger implements Observes {
    protected $types = array(
        'debug' => 0,
        'notice' => 1,
        'warning' => 2,
        'error' => 3
    );

    protected function code( $type ) {
        return isset( $this->types[$type] ) ? $this->types[$type] : 0;
    }
}

class FileLogger extends Logger implements Observes {

    public function __construct( $filename ) {
        $this->filename = $filename;
    }

    /**
     * @todo replace the method body with a call to, say, file_put_contents.
     */
    public function notify( $message, $type = 'notice' ) {
        if( $this->code( $type ) > $this->code( 'notice' ) ) { // only for warning and error.
            echo $message . "\n";
        }
    }


}

class DebugLogger extends Logger implements Observes {
    public function notify( $message, $type = 'notice' ) {
        if( $this->code( $type ) === $this->code( 'debug' ) ) { // only show "debug" notices.
            echo $message . "\n";
        }
    }
}


$service = new MailService( );
$service->attach( new FileLogger( 'yourlog.txt' ) );
$service->attach( new DebugLogger( ) );
$service->sendMail( );
Run Code Online (Sandbox Code Playgroud)