douwenpin0428 2013-03-03 01:30
浏览 46
已采纳

PHP Composer,用于包含带命名空间的建议模块的良好设计模式

I am writing some code (a database abstraction layer, to be used in other of my code modules) that I would like to release as a standalone module that may be included in a project with composer. I would like to include in the composer defintion some suggested modules that would improve the performance of my module, but that are't required.

The problem I have is how to do this in a way that is note completely horrific.

So in this particular example the module is declared in namespace Intahwebz\DB; and then the optional module Intahwebz\Log\Log is tried to be included, which in turn tries to use the optional module Monolog.

What I have so far is the module code ConnectionWrapper.php

namespace Intahwebz\DB;

use Intahwebz\Log\Log;


if(trait_exists("Intahwebz\Log\Log") == false){
    require_once("Log.php");
}


class ConnectionWrapper{

    use Log;

    function __construct(){
        $this->initLog();

        // Rest of constructor code.

        $this->log->trace("ConnectionWrapper has been constructed.");
    }   

    // Lots of other functions here.
}


?>  

Then in Log.php I check to see if Monolog is available and if so include it, otherwise define a really lightweight logger.

<?php

namespace Intahwebz\Log;

if (class_exists('Monolog\Logger') &&
    class_exists('Monolog\Handler\StreamHandler')) {

require_once "MonologWrapper.php";

}
else{

    class Logger{
        public function debug($message, array $context = array()){
            echo $message."
";
        }
        public function log($level, $message, array $context = array()){
            echo $message."
";
        }
        public function info($message, array $context = array()){
            echo $message."
";
        }
        public function notice($message, array $context = array()){
            echo $message."
";
        }
        public function warning($message, array $context = array()){
            echo $message."
";
        }
        public function error($message, array $context = array()){
            echo $message."
";
        }
        public function critical($message, array $context = array()){
            echo $message."
";
        }
        public function alert($message, array $context = array()){
            echo $message."
";
        }
        public function emergency($message, array $context = array()){
            echo $message."
";
        }
    }

    trait Log{

        var $log;
        function initLog(){
            $this->log = new Logger(__CLASS__);
        }
    }
}

If Monolog is available, we use it by including MonologWrapper.php

<?php

namespace Intahwebz\Log;

use Monolog\Logger;
use Monolog\Handler\StreamHandler;

trait Log{

    var $log;

    function    initLog(){
        $this->log = new Logger(__CLASS__);
        //Todo - get log handler from config file automagically.
        $this->log->pushHandler(new StreamHandler(PATH_TO_ROOT.'var/log/Admin.log', Logger::WARNING));
    }
}


?>

The problems with this are:

1) It's incredibly ugly, and requires an extra files per suggested module.

2) It doesn't allow people to switch in a different logger other than monolog without re-writing code.

3) It has duplicate class/trait definitions separated only by if statements, which completely confuses my IDE.

I know that the way Symfony et al solve this problem is by having a service layer. However I can't see how to use that design pattern without forcing the dependency inclusions to be a lot more complicated than they ought to be for just bringing in an optional module.

Can anyone describe a decent design pattern for including optional modules, or replacing them with other compatible modules? Or is this the type of thing that can only be defined nicely within an actual framework?

  • 写回答

1条回答

      报告相同问题?

      相关推荐 更多相似问题

      悬赏问题

      • ¥15 使用DWY100k数据集对UEA进行测试,出现报错:IndexError: index 125000 is out of bounds for axis 0 with size 95500
      • ¥15 前端vue实现根据图片url生成pdf文件
      • ¥15 RfidReader资源Q个
      • ¥20 user-agent是否是唯一的,有没有可能相同
      • ¥15 关于#开会#的问题,如何解决?(语言-c++)
      • ¥15 关于#二十四点问题#的问题
      • ¥15 运行kitex的demon出错(求大家解决)
      • ¥15 开发一个类似 typora 这样的软件需要多少钱?
      • ¥15 clearcase7.0安装包
      • ¥15 断点回归模型月度核密度检验不连续