【问题标题】:Dynamic arguments动态参数
【发布时间】:2016-12-07 02:05:40
【问题描述】:

我正在使用 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
}

如何做到这一点?

【问题讨论】:

    标签: php oop laravel-5.2 type-hinting


    【解决方案1】:

    无法以您想要的方式提供多种类型提示(除非它们根据 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
     */
    

    【讨论】:

    • 同样,所有有用的东西
    【解决方案2】:

    您可以同时使用类名和接口进行类型提示,但前提是所有 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);
    

    【讨论】:

    • 考虑到您可以实现多个接口,我认为最佳实践是实现像 Dekel 演示的接口。
    • @Nitin 根据单一方法的输入要求来构建类远非最佳实践。当然,这种方法适用的情况很多。
    • 优秀的界面使用,我喜欢。
    • @rjdown 好点。在这种情况下,如果该方法仅限于一次使用,那么您的解决方案是正确的选择。否则就有可能复制控制结构。也为您的答案+1,我也会使用它。
    【解决方案3】:

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

    简单的解决方案是检查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) 
    

    【讨论】:

      猜你喜欢
      • 2017-06-15
      • 2016-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-25
      • 2013-10-24
      • 2013-03-20
      相关资源
      最近更新 更多