20

tl;博士

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

动机

如果您想要更大的图景,这就是我提出这个问题的方式。

问题:在我当前的项目中,我们有很多真正应该是单例的类(数据库代理等)。不用说,我们至少有几百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 并不是必需的。

4

2 回答 2

37

好吧,PhpStorm 3.0 将接受

@method static type name() description

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

于 2011-09-14T11:51:11.603 回答
1

一般来说,我认为使用魔法的选择伴随着一个警告,即必须接受失去自动完成之类的有效性的权衡。

但是,在我使用 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()"
于 2011-05-12T21:52:21.760 回答