Php 如何将实例放入基类中

Php 如何将实例放入基类中,php,oop,model-view-controller,service-locator,service-provider,Php,Oop,Model View Controller,Service Locator,Service Provider,我正在用PHP构建一个简单的MVC框架,我被困在必须创建BaseController类的地方 每个“页面”控制器都需要从此BaseController扩展。因为这个BaseController类将具有一些属性,这些属性将允许用户访问模板引擎和记录器类(以及其他一些东西) 我的问题是,我不确定如何在BaseController类中实例化这些东西。显然,我可以在\uu constructo()中对其进行硬编码,如下所示: class BaseController { protected $v

我正在用PHP构建一个简单的MVC框架,我被困在必须创建
BaseController
类的地方

每个“页面”控制器都需要从此
BaseController
扩展。因为这个BaseController类将具有一些属性,这些属性将允许用户访问
模板
引擎和
记录器
类(以及其他一些东西)

我的问题是,我不确定如何在BaseController类中实例化这些东西。显然,我可以在
\uu constructo()
中对其进行硬编码,如下所示:

class BaseController
{
    protected $view;
    protected $log;

    public function __construct()
    {
        $this->view = new \namespace\view('param1', 'param2');
        $this->log = new Logger('name');
        $this->log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));
    }
}
class BaseController
{
    protected $view;
    protected $log;

    public function __construct($view, $log)
    {
        $this->view = $view;
        $this->log = $log;
    }
}

但这并不能使它非常模块化。例如,这使得更改Logger类变得很困难。或者,如果用户希望将模板引擎更改为Smarty(例如)

我也不能真正使用依赖性注射。因为从
BaseController
扩展的每个控制器都必须将这些实例传递给
BaseController

看起来是这样的:

class BaseController
{
    protected $view;
    protected $log;

    public function __construct()
    {
        $this->view = new \namespace\view('param1', 'param2');
        $this->log = new Logger('name');
        $this->log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));
    }
}
class BaseController
{
    protected $view;
    protected $log;

    public function __construct($view, $log)
    {
        $this->view = $view;
        $this->log = $log;
    }
}
家庭控制器

class HomeController extends BaseController
{
    public function __construct($view, $log)
    {
        parent::__construct($view, $log);

        // Do my own stuff
    }
}
对我来说,当用户只想在
\uu构造函数中做一件简单的事情时,这并不是真正的用户友好。即使使用了
IoC

因此,我现在唯一能想到的就是使用
BaseController
中的
\uu construct
方法中的
服务提供者。但我不确定这是不是一条路?也许有更好的选择

那么,解决这个问题的好办法是什么呢


另外,如果我确实需要一个
服务定位器
,是否有好的示例?我发现的那些作品是由那些似乎不知道自己在说什么的人写的。他们基本上是在复制彼此的博客帖子。

您首先需要思考控制器的职责是什么,为什么需要访问日志功能,或者为什么要设置模板引擎或切换模板

控制器的工作只是从请求中提取数据(主要是表单数据/用户输入)并通过服务将其发送到模型层,不应该选择模板,这是视图工作

显然,您希望将基本控制器的依赖项保持在最小值,以便在实例化子控制器时,不会有大量依赖项要注入

我的基本控制器有两个依赖项,请求对象和视图,这两个依赖项都被注入。控制器是简单和轻,没有逻辑或任何幻想应该发生在他们。有一次,我不得不在我的一个控制器中使用记录器,但那只是因为PayPal使用IPN系统向它发送请求,我需要将请求中的所有数据记录到一个文件中,以查看发生了什么,除了这样的特殊情况外,我不明白为什么控制器需要记录器。在这种情况下,只有处理PayPal请求的控制器持有记录器实例,而不是父基控制器

您应该始终注入依赖项。不要在构造函数中实例化对象,这会使类与这些对象紧密耦合

如果您最终使用了服务定位器,这可能是您的类违反了OOP的单一责任原则的标志


控制器应该很简单,不要通过添加您认为它们将来可能需要的依赖项使其过于复杂,特别是不要添加到基本控制器,否则您可能需要进行大量重构。

在控制器中记录哪些内容?请求中的数据?@David这实际上更像是一个例子,我不需要一个日志类。底线是,我需要BaseController类中的一些类实例。我需要一种方法让他们以模块化的方式进入那里。