Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/283.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函数?_Php_Class_Overwrite_Hint - Fatal编程技术网

如何覆盖设置了参数类型提示的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”*/

为什么不使用类最可能实现的接口创建自己的类实现呢?这样,您仍然可以遵守(假定)接口中定义的契约,并且能够使用任何类使用您试图扩展的内容?我有一个解决方案,如果您可以稍微修改这两个类,这不会产生安全问题您需要它吗?