Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 需要父项的最优雅方式::\u construct()_Php_Oop - Fatal编程技术网

Php 需要父项的最优雅方式::\u construct()

Php 需要父项的最优雅方式::\u construct(),php,oop,Php,Oop,假设我有以下控制器结构: class Controller { public function __construct(){ $this->accessControl(); } } class Account extends Controller { public function __construct(User $user){ parent::__construct(); $this->user = $user;

假设我有以下控制器结构:

class Controller {

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

class Account extends Controller {

   public function __construct(User $user){

      parent::__construct();
      $this->user = $user;
   }
}
如何要求其他开发人员在其子控制器中显式调用
parent::\u construct()
?它包含访问控制等关键内容

到目前为止,我决定将父构造函数中的所有函数包装到
init()
方法中,该方法将
initialized
属性设置为TRUE,然后在路由器中检查该属性。如果不是真的-抛出异常

public $initialized = false;

class Controller {

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

protected function init(){
   $this->accessControl();
   $this->initialized = true;
}

class Router {
    public function process($path){
       $controller = new User();
       if(!$controller instanceof Controller || !$controller->initialized){
          throw new Exception('Error');
       }
    }
}
它闻起来难闻吗?

是的,它闻起来难闻

如何要求其他开发人员在 他们的子控制器

首先,你应该信任你的开发者。另一个问题是如何确保所有控制器都具有访问控制。为了确保这一点,您必须对所有控制器进行测试。因此,每个控制器都应该进行测试,以检查未经授权的用户是否可以访问它

到目前为止,我决定将父构造函数中的所有函数包装到
init()
方法,该方法将
initialized
属性设置为TRUE,然后检查此项 路由器中的属性

实际上,您的
init
函数没有任何价值,因为您只是将代码从
\uuuu构造中移动过来(最后,您必须确保开发人员调用
init
函数——请参见,只更改了名称;)。您还可以在
\u构造
本身中设置
初始化

因此,您将强制您的开发人员检查控制器是否已初始化,在每个地方,它都将在中使用

我想你不能使代码万无一失。您必须相信开发人员会做正确的事情,并教育新的团队成员。当然,您应该用测试覆盖所有代码,因为在实践中,这是确保开发人员做正确事情的唯一方法

有一个很好的播客,这对您的问题来说是切实可行的:。

同样需要在Command中使用,其中构造函数必须添加命令名和定义

在添加命令的单个位置。所以你们在路由器中检查控制器的方法是相同的我已经准备好了,而不是把责任交给抽象的控制者或一些反思


另一方面,它看起来应该在安全层级别检查
accessControl()
,而不是在路由器中检查

您使用什么框架?


您可以使用EventSubscriber和framework事件将其与路由器分离吗?

父项::\uu construct()
看起来很优雅。由于子类依赖于它,不调用它将意味着它们无法访问父类的
\u construct()
函数中创建的变量。不久前,我完全停止使用类继承。“你也应该这么做。”迈克,所以我假设你没有使用任何主要的框架。否则,这真的很难做到,因为框架要求您使用继承。@迈克,老实说,我同意您的看法,最好使用组合而不是继承,并在默认情况下声明类为final。但由于我们不是生活在仙境中,实现它可能相当困难。虽然困难,但它是值得的。类更易于维护和测试。顺便说一下,我用的是Symfony。它不会强迫我做任何事情。它不是一个框架,而是我自己写的:)。“您能使用EventSubscriber和framework事件将其与路由器解耦吗?”它已经解耦了。两个不同的类用于不同的目的。路由器只需查看预定义路由列表(regexp模式)并调用适当的控制器方法“应在安全层级别检查accessControl()”,这是什么意思?控制器负责访问控制,不是吗?但这种方法在与非标准方法相结合时可能存在缺陷:参见本周发布的Symfony命令:
if(!$controller instanceof Controller || !$controller->initialized){
    throw new Exception('Error');
}