如何覆盖设置了参数类型提示的php函数?
我试图用自己的功能扩展一个包。但是包代码在函数调用中有类型提示,这些函数调用指向包中的其他类。 我只是在寻找一种修改代码的方法 更多关于我正在做的事情的细节 我已经尝试将代码更改为使用接口和摘要,但我似乎无法阻止类的声明…必须与“错误”兼容 简而言之,这就是我要做的 软件包具有这种类型的设置如何覆盖设置了参数类型提示的php函数?,php,class,overwrite,hint,Php,Class,Overwrite,Hint,我试图用自己的功能扩展一个包。但是包代码在函数调用中有类型提示,这些函数调用指向包中的其他类。 我只是在寻找一种修改代码的方法 更多关于我正在做的事情的细节 我已经尝试将代码更改为使用接口和摘要,但我似乎无法阻止类的声明…必须与“错误”兼容 简而言之,这就是我要做的 软件包具有这种类型的设置 class ClassA {} class ClassB { public function makeClassA(ClassA $classA) : ClassA {
class ClassA {}
class ClassB {
public function makeClassA(ClassA $classA) : ClassA
{
return $classA;
}
}
这就是我想做的
class ClassANew {}
class ClassC extends ClassB {
public function makeClassA(ClassANew $classA) : ClassANew
{
return $classA;
}
}
我得到以下错误
“PHP致命错误:ClassC::makeClassA(ClassANew$classA)的声明:ClassANew必须与ClassB::makeClassA(classA$classA):classA兼容”
我知道我可以把代码叉出来,把锁着的classA
从ClassB
中去掉,但我不想这样做
如果我要分叉代码,我会看看如何维护原始代码的前提。因此,我尝试将ClassB
中的ClassA
引用更改为ClassAInterface
,但得到了相同的错误
我想做的是可能的吗?不,这是不可能的
请看这里,原因如下:这是一个小把戏,但它的特点是在过去或已经使用和测试的情况下,不会引起安全问题 我知道这不是你真正需要的,但它完全解决了你的问题,同时保持了方法的安全性和强制返回
class ClassA {}
class ClassB {
public function makeClassA_ClassB(ClassA $classA) : ClassA
{
return $classA;
}
function __call($function_name, $argument){
if ($function_name==="makeClassA" && $argument[0] instanceof ClassA ) return $this->makeClassA_ClassB($argument[0]);
}
}
class ClassANew {}
class ClassC extends ClassB {
public function makeClassA_ClassC(ClassANew $classA) : ClassANew
{
return $classA;
}
function __call($function_name, $argument){
if ($function_name==="makeClassA" && $argument[0] instanceof ClassANew ) return $this->makeClassA_ClassC($argument[0]);
}
}
$t=new ClassC();
$t2=new ClassANew();
var_dump($t->makeClassA($t2)); // object(ClassANew)#212 (0) { }
$t=new ClassB();
$t2=new ClassA();
var_dump($t->makeClassA($t2)); // object(ClassA)#212 (0) { }
好的,我终于解决了问题。我必须保持原始引用的返回类型不变。在那之后,它现在可以正常工作了
名称空间原创;
类ClassExtra{}
甲级{
公共函数{u构造($container,ClassB$ClassB){}
}
B类{
公共函数uu构造(ClassExtra$ClassExtra){}
}
C类{
公帑乙类;;
公共集装箱;
公共函数构造(ClassB$ClassB){
$this->classB=$classB;
}
公共函数容器(字符串$container='default'):ClassA
{
$this->containers[$container]=newclassa($container,$this->classB);
返回$this->containers[$container];
}
}
名称空间变化;
类NewClassA扩展\Original\ClassA{}
类NewClassB扩展\Original\ClassB{}
类NewClassC扩展\Original\ClassC{
公共函数容器(字符串$container='default'):\Original\ClassA
{
$this->containers[$container]=NewClassA($container,$this->classB);
返回$this->containers[$container];
}
}
$classC=new\Original\classC(new\Original\ClassB(new\Original\ClassExtra());
变量转储(获取类($classC->container('test'));
/*字符串(15)“原始\ClassA”*/
$classC=newnewclassc(newnewclassb(new\Original\ClassExtra());
变量转储(获取类($classC->container('test'));
/*字符串(17)“更改\NewClassA”*/
为什么不使用类最可能实现的接口创建自己的类实现呢?这样,您仍然可以遵守(假定)接口中定义的契约,并且能够使用任何类使用您试图扩展的内容?我有一个解决方案,如果您可以稍微修改这两个类,这不会产生安全问题您需要它吗?