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');
}