【问题标题】:PHPDoc and __callStaticPHPDoc 和 __callStatic
【发布时间】:2011-08-24 08:23:19
【问题描述】:

tl;博士

注释(在 PHPDoc 中)通过__callStatic 实现的函数的正确方法是什么?更重要的是:有没有办法让 NetBeans PHPStorm 明白这些是静态方法?

动机

如果您想了解更大的情况,这就是我提出这个问题的方法。

问题:在我当前的项目中,我们有很多真正应该是单例的类(数据库代理等)。不用说,我们至少有几百行 require_once$foo = new FooProxy(); 行。

解决方案:我创建了一个Loader 类来解决这个问题,使用__callStatic 魔术方法所以我们可以说$foo = Loader::FooProxy();。它非常适合我们的目的,但是:

问题:这种方式显然在团队中使用的任何一个 IDE 中都没有类型提示。

解决方案:每个模块都定义了Loader 的子类,添加了只路由到__callStatic 的方法。

问题:为了自动完成而添加实际解释的代码是不可接受的(这可以争论,但让我们暂时接受它)。

解决方案:我们不添加任何真正的方法,只在 PHPDoc 中像这样声明方法:

<?php
/**
 * @method FooProxy FooProxy()
 */
 class BarLoader extends Loader {}
?>

问题FooProxy 不是静态方法。以下都不是静态的:

<?php
/**
 * @static
 * @method FooProxy FooProxy()
 */

///////////////

/**
 * @static @method A A()
 * @method static A A()
 * @method A static A()
 * @method A A() static
 */

使类抽象没有区别。大约一个小时的谷歌搜索没有找到任何解决方案。主要目标是让 IDE 了解这些功能;拥有正确的 PHPDoc 并不是必须的。

【问题讨论】:

    标签: php phpdoc magic-methods


    【解决方案1】:

    嗯,PhpStorm 3.0 会接受

    @method static type name() description
    

    查看相关功能请求http://youtrack.jetbrains.net/issue/WI-4051

    【讨论】:

    • 同样适用于 VS Code。
    【解决方案2】:

    一般来说,我认为选择使用神奇的东西需要接受一个权衡,即失去自动补全之类的东西的有效性。

    但是,在我使用 Eclipse PDT(在 WinXP 上使用 PHP 5.3.2 的 Helios)进行的测试中,我能够从一个显式静态方法和两个神奇的静态方法中获得良好的自动完成功能,这些方法来自我根据您的示例建模的 Loader 类.

    简而言之,在类 docblock 中使用 @method 标记似乎足以让 Eclipse 解决问题。如果 NetBeans 和 PHPStorm 遇到问题,我不确定它是否与“静态”方面有关……可能只是对此类动态代码的解析可能超出了它们的自动完成逻辑的处理能力。

    <?php
    /**
     * @method BarProxy BarProxy() returns an instance of BarProxy
     * @method BazProxy BazProxy() returns an instance of BazProxy
     */
    class Loader
    {
        public static function __callStatic($name, $arguments)
        {
            return new $name($arguments);
        }
    
        /**
         * @return FooProxy
         */
        public static function FooProxy(){
            return new FooProxy();
        }
    }
    
    class FooProxy
    {
        public function sayCheese() {}
    }
    
    class BarProxy
    {
        public function eatFries() {}
    }
    
    class BazProxy
    {
        public function sleep() {}
    }
    
    $foo = Loader::FooProxy();
    $foo->sayCheese(); // did this simply to verify explicit autocompletion succeeded
    
    $bar = Loader::BarProxy();
    $bar->eatFries();  // autocompletion of just "$bar->" brought up "eatFries()"
    
    $baz = Loader::BazProxy();
    $baz->sleep();     // autocompletion of just "$baz->" brought up "sleep()"
    

    【讨论】:

    • 不幸的是,@method 被两个 IDE 解析和使用得很好,但他们假设这些方法是动态的。 PHPStorm 甚至会发出警告说我正在静态调用非静态方法。
    • 看来我不得不接受这个“不,那不可能”的回答
    猜你喜欢
    • 2011-08-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-07
    • 2016-04-07
    • 1970-01-01
    • 2013-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多