gpt4 book ai didi

PHP 命名空间和继承

转载 作者:行者123 更新时间:2023-12-04 17:03:39 25 4
gpt4 key购买 nike

我正在将我开发的一系列类转换为使用命名空间。
其中一个类具有依赖项:

文件A

namespace VENDOR
class A{
static public function(){
B::getInfo();
}
}

文件B
namespace VENDOR;
class B{
static public function getInfo(){
//some work
}
}

然后,这属于我将包含到项目中的个人库。类(class) B易于扩展:
namespace APPNAMESPACE
class SuperB extends \VENDOR\B{
static public function getInfo(){
//Some different work
}
}

我的意图是 VENDOR\A 调用 APPNAMESPACE\SuperB,但在这里我看到我没有很好地设计我的系统,因为显然它会继续调用 VENDOR\B。

在此之前,我可以实现这种行为,因为我根本没有使用命名空间,而是使用经典的类命名约定 DIR_CLASS.php,它允许我的自动加载器(现在使用 composer)首先在高优先级 APP 文件夹中查找,如果在其他文件夹中找不到优先级较低(类似于 kohana、Codeigniter 等)。

那么我该如何解决这个问题(显然没有将 APPNAMESPACE\SuperB 硬编码到 VENDOR\A 中)

最佳答案

没有状态,这确实很快变得棘手。有没有理由这必须是静态调用?如果可能的话,我更喜欢(可配置的、可测试的、可交换的、可测试的)实例。

这样的事情会容易得多:

namespace VENDOR
class A{
protected $b;
public function __construct(B $b){
$this->b = $b;
}
public function something(){
$this->b->getInfo();
}
}

......所以你可以添加你喜欢的东西。可能,构造函数中的 B 类型提示应该是接口(interface)而不是类定义,并且您可能几乎无法控制外部供应商为您提供的内容。

如果我们假设您无法触及 VENDOR 的代码,我认为没有合理的工作方法。如果它需要是静态的(并且仔细思考为什么会这样),并且您可以触摸代码,这样的事情可能会起作用,但我不喜欢它,因为它更难检查、调试和强制执行一致性在类名中(OTOH,未经测试):
namespace VENDOR
class A{
protected static $b = 'B';
static public function something(){
call_user_func(array(self::$b,'getInfo'));
}
static function useB($classname){
if(!in_array('\VENDOR\B',class_implements($classname))){
trigger_error("$classname does not implement \VENDOR\B", E_USER_ERROR);
}
self::$b =
}
}

同样,选择一个接口(interface)而不是一个实现来检查。尽管如果您想进一步扩展\VENDOR\A ,我们可能会再次遇到 static::/self::问题。这是“有点”的功能,例如您看到@ $PDO->setAttribute(PDO::ATTR_STATEMENT_CLASS, 'A class that extends PDOStatement'); ,但是您立即已经看到它在实例中被调用(并且它需要扩展而不是实现 PDOStatement 的事实与该类的 C 级实现/功能有更多关系)。

关于PHP 命名空间和继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25339394/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com