动态参数

时间:2016-08-01 21:13:33

标签: php oop laravel-5.2 type-hinting

我正在使用Laravel 5.2,我想创建一个方法,其中参数必须是Foo,Bar或Baz的实例。如果参数不是任何这些类的对象,则抛出错误。

App\Models\Foo;
App\Models\Bar;
App\Models\Baz;


public function someMethod(// what to type hint here??)
{
   // if 1st argument passed to someMethod() is not an object of either class Foo, Bar, Baz then throw an error
}

怎么做?

3 个答案:

答案 0 :(得分:5)

无法以您想要的方式提供多种类型提示(除非他们根据Dekel的答案扩展/实现彼此)。

您需要手动强制执行该类型,例如:

public function someMethod($object) {
    if (!in_array(get_class($object), array('Foo', 'Bar', 'Baz'))) {
        throw new Exception('ARGGH');
    }
}

您可以通过提供所需类型列表作为phpdoc提示来帮助最终用户:

/**
 * Does some stuff
 * 
 * @param Foo|Bar|Baz $object
 * @throws Exception
 */

答案 1 :(得分:3)

您可以同时使用类名和接口进行类型提示,但仅当所有3个类扩展同一个类或实现相同的接口时,否则您将无法执行此操作:

class C {}
class D extends C {}

function f(C $c) {
    echo get_class($c)."\n";
}

f(new C);
f(new D);

这也适用于接口:

interface I { public function f(); }
class C implements I { public function f() {} }

function f(I $i) {
    echo get_class($i)."\n";
}

f(new C);

答案 2 :(得分:1)

不支持“多个”类型提示。

使用instanceof(或@rjdown解决方案)

检查简单解决方案
public function someMethod($arg) 
{
    if (!$arg instanceof Foo && !$arg instanceof Bar && !$arg instanceof Bar) {
        throw new \Exception("Text here")  
    }
}

或者让所有课程implement成为interface。例如:

class Foo implements SomeInterface;
class Bar implements SomeInterface;
class Baz implements SomeInterface;

// then you can typehint:
public function someMethod(SomeInterface $arg)