PHP中的变量函数和类型暗示

PHP中的变量函数和类型暗示,php,types,variadic-functions,type-hinting,Php,Types,Variadic Functions,Type Hinting,快一点: 有没有办法在PHP中强制变量函数的类型?我想不会,不过也许我错过了什么 到目前为止,我只是强制使用所需类型的一个必需参数,并迭代检查其余参数 public function myFunction(MyClass $object){ foreach(func_get_args() as $object){ if(!($object instanceof MyClass)){ // throw exception or something

快一点:

有没有办法在PHP中强制变量函数的类型?我想不会,不过也许我错过了什么

到目前为止,我只是强制使用所需类型的一个必需参数,并迭代检查其余参数

public function myFunction(MyClass $object){
    foreach(func_get_args() as $object){
        if(!($object instanceof MyClass)){
            // throw exception or something
        }
        $this->_objects[] = $object;
    }
}
有更好的解决办法吗


目的:

作为子对象的迭代列表的容器对象,具有一些实用函数。使用可变构造函数调用它可能是这样的:

// returned directly from include
return new MyParent(
    new MyChild($params),
    new MyChild($params),
    new MyChild($params)
);
另一个选项可以是
addChild
方法链:

$parent = new MyParent;
return $parent
    ->addChild(new MyChild($params))
    ->addChild(new MyChild($params))
    ->addChild(new MyChild($params));

孩子们也将几个参数带到他们的构造函数中,所以我试图在易读性和处理费用之间取得平衡。

好吧,我想说这取决于参数的数量:)没有什么比列表更像(所有参数1-n都是MyClass[在PHP5.6之前,对于PHP5.6+请参见]),您更需要编写每个参数(如您的问题所示)允许发送更多,但只检查定义的

但是,您可以定义更多,并将其设置为可选。因此,我为什么要编写它取决于参数的数量:

public function myFunction(MyClass $object, MyClass $object2=null, MyClass $object3=null, MyClass $object4=null, ...){
    foreach(func_get_args() as $object){
        if(null === $object){
            // throw exception or something
        }
        $this->_objects[] = $object;
    }
}
在这样的例子中,当参数不为NULL且不为MyClass时,PHP可能已经抛出了异常(如果作为默认值提供,则传递NULL,也传递)。可选参数不应该是
func\u get\u args()
的返回值的一部分。我的意思是,如果不传递第三个参数(此处名为
$object3
)它不会出现在返回的数组中

不知道这是否比问题中的代码更适用于您

如果您在代码中遇到更多这样的情况,您可以创建某种帮助程序来验证函数调用的输入,并委托该帮助程序抛出异常以及来自该帮助程序的漂亮错误消息。这将防止重复代码,并在开发中提供更大的舒适度,因为您可以在为多线程编写异常通知时使异常通知更漂亮例


根据您的新反馈,如果您希望首先让解释器执行检查工作,则只需进行一点迭代,并使用addMember函数即可:

class MyParent {
    private $children = array();
    public function __construct() {
        foreach(func_get_args() as $object) $this->addChild($object);
    }
    public function addChild(MyChild $object) {
        $this->children[] = $object;
    }
}
在任何列表中使用错误类型的对象实例化对象将阻止实例化集合

然后,您可以执行以下操作:

// returned directly from include
return new MyParent(
    new MyChild($params),
    new MyChild($params),
    new MyChild($params)
);
现在,使用…运算符(在某些语言中也称为splat运算符)可以实现:

例如:

function addDateIntervalsToDateTime( DateTime $dt, DateInterval ...$intervals )
{
    foreach ( $intervals as $interval ) {
        $dt->add( $interval );
    }
    return $dt;
}

感谢hakre;我的预期用途是传递给定类的非有限数量的对象,并且该数量始终是任意的。它们被传递到的对象构造函数用于容器对象,但所有子对象都必须是适当的类。我正在考虑的另一个选项是方法链接
addObject
方法;I虽然调用了(可能的)一个大量的
addObject
方法可能会很昂贵,这就是我最初选择可变构造函数的原因。示例添加到question.TomcatExodus中,我添加了一些示例代码,可以避免您抛出异常,因为PHP会为您这样做。但在任何情况下,如果您想要执行chec,都需要某种迭代ks.尽管我认为SPL中可能有某种类型的列表可以处理这个问题。再次感谢hakre;我现在关心的是调用
addChild()的相关成本
对于构造函数的每个参数,或者作为可链接的方法。我知道微观优化;但是,在某些情况下,这种方法可能不太理想。我将在有机会时进行基准测试;如果链接方法的性能明显下降,我将使用构造函数方法,将可链式方法保留为实例化后添加。大多数子对象都设置为实例化,并从包含返回,如我的示例中所示。我不能说这是否为MO,这取决于您的操作。但是我不知道您有多少个对象,但迭代速度很快。如果您不需要检查chi的类型ldren,只需将它们分配给数组。如果您仍然知道自己在做什么,您可以稍后添加迭代器:)我考虑过这一点,对访问执行检查,而不是对初始化执行检查。事实上,如果添加了错误的对象,这对应用程序来说是一个致命的异常;因此,在初始化时为每个子级执行检查可能是次优的。父容器实现了
Iterator
,为了快速访问,我可以将检查放入
current()
。许多值得考虑的问题。再次感谢hakre,我将让这个问题暂时搁置一下,看看是否还有其他人有洞察。在PHP7中,也可以使用标量类型键入hint。