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

Dan*_*ugg 5 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
        }
        $this->_objects[] = $object;
    }
}
Run Code Online (Sandbox Code Playgroud)

更好的解决方案?


目的:

一个容器对象,充当子对象的迭代列表,具有一些实用程序功能.使用可变参数构造函数调用它将是这样的:

// returned directly from include
return new MyParent(
    new MyChild($params),
    new MyChild($params),
    new MyChild($params)
);
Run Code Online (Sandbox Code Playgroud)

另一种选择可能是addChild方法链:

$parent = new MyParent;
return $parent
    ->addChild(new MyChild($params))
    ->addChild(new MyChild($params))
    ->addChild(new MyChild($params));
Run Code Online (Sandbox Code Playgroud)

孩子们也会对他们的构造函数提出几个论点,所以我试图在易读性和处理费用之间取得平衡.

JCM*_*JCM 18

现在可以使用PHP 5.6.x,使用...运算符(在某些语言中也称为splat运算符):

例:

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


hak*_*kre 2

好吧,我想说这取决于参数的数量:)没有什么比列表更好的了(所有参数 1-n 作为 MyClass [在 PHP 5.6 之前,对于 PHP 5.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;
    }
}
Run Code Online (Sandbox Code Playgroud)

对于这样的示例,当参数不为 NULL 且不为 MyClass 时,PHP 就会抛出异常(如果作为默认值给出,则也可以传递 NULL)。可选参数不应成为 的返回值的一部分func_get_args()。我的意思是,如果您不传递第三个参数(此处名为$object3),它就不会出现在 . 返回的数组中func_get_args()

不知道这对您来说是否比问题中的代码更实用。

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


根据您的新反馈,如果您希望解释器首先进行检查工作,则进行一点迭代,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;
    }
}
Run Code Online (Sandbox Code Playgroud)

在任何列表中使用错误类型的对象实例化对象将阻止集合实例化。

然后你就可以这样做:

// returned directly from include
return new MyParent(
    new MyChild($params),
    new MyChild($params),
    new MyChild($params)
);
Run Code Online (Sandbox Code Playgroud)