【问题标题】:How to document magic (_call and _callStatic) methods for IDEs如何记录 IDE 的魔法(__call 和 __callStatic)方法
【发布时间】:2013-03-16 01:38:35
【问题描述】:

在使用 notepad++ 和 sublime 编码多年后,有人建议我试一试 PHP IDE。我正在尝试 phpStorm,它看起来不错。代码完成和文档是一个很棒的功能,但在使用魔术方法时对我来说不起作用。 有没有办法让 phpStorm 了解魔术方法中发生了什么?

我们的情况是这样的:

abstract class a {
    public static function __callStatic($method,$args)
    {
        if(strpos($method,"get_by_") === 0)
        {
            //do stuff
        } elseif(strpos($method,"get_first_by_") === 0) {
            //do stuff
        } elseif($method == "get_all") {
            //do stuff
        }
    }
}

class b extends a {
    // some more stuff
}

b::get_by_user_id(27);
b::get_first_by_id(156);
b::get_all();

神奇的 callStatic 方法允许我们通过构成函数调用的 1 个或多个参数来获取对象集合。

我看到在这些情况下有一个@method 语句可以使用,但是 phpStorm 只选择了这些语句中的第一个。此外,我只能将返回类型设置为混合,因为我希望能够将其设置为调用它的任何类(在我的示例中为 b)。

任何想法或建议都将非常感激,谢谢。

【问题讨论】:

  • 为什么会有任何人认为覆盖_call是个好主意?!!
  • 得说,+1'd Brian 的评论,以防任何理智的人都会找到这个问题。魔术方法适用于所有意图和目的:无法记录(尝试将 a(n) [参数|前置条件|后置条件|异常] 记录为魔术方法),不适合 IDE(尝试逐步调试魔术方法),对重构具有弹性(请不要考虑尝试在终身软件中重构魔法方法)和 LAZY(好吧,最后一个可能被解释为意见)。
  • -1 对@LukeA.Leber 评论中的意见表示缺乏远见。虽然魔术方法不是一种编写更少代码的方法(如果您使用它们是懒惰的),但魔术方法使架构成为可能,否则简单是不可能的,或者会非常复杂以至于不值得编写。在使用 PHPDoc 时,它们完全是 IDE 友好的。请注意,大多数时候您不需要魔术方法,但是当您需要它们时,没有替代品(在 PHP 中)。当它们以非常结构化的方式使用时,使用它们是一个完整的有效解决方案。
  • 不要认为覆盖 __call 是一个坏主意。这一切都与实施有关。上面问题中显示的实现肯定不是最好的方法,但是对于可链接的 API,它提供了很大的灵活性。

标签: php documentation phpstorm magic-methods docblocks


【解决方案1】:

使用类级别的 PHPDoc 注释——特别是 @method 标签——在 PhpStorm 中可以正常工作:

/**
 * @method static someClass get_by_user_id(int $id) Bla-bla
 * @method static someClass get_first_by_id(int $id) 
 */
abstract class a {
...

在上面:

  • @method -- PHPDoc 标签
  • static -- 表示这是静态方法
  • someClass$this -- 返回类型
  • get_by_user_id -- 方法名
  • (int $id) -- 方法签名:([[type] [parameter]<, ...>])
  • Bla-bla -- 一些可选描述

更多关于@method

附言 虽然@method static 在 PhpStorm 中运行良好(告诉 IDE 该方法是静态的),但实际的 phpDocumentor 工具可能(还没有?)支持它(抱歉,暂时没有使用它)。


或者:(当然是在 PhpStorm 中)Settings | Inspections | PHP | Undefined | Undefined method --> Downgrade severity if __magic methods are present in class -- 它不会以任何方式帮助此类方法的代码完成,但不会将这些魔术方法标记为“未定义方法”错误。


phpDocumentor's ticket 关于为 @property/@method 标记使用 RegEx/部分名称(它对文档有多大用处,以及在处理代码时它对实际 IDE 的帮助有多大)完成):

【讨论】:

  • 谢谢,这看起来是一个合理的建议,它在 phpStorm 中确实有效,但我有点讨厌在每个类的顶部写出可能有数百行 @method 的行。您会看到 get_by_* 方法可以由任何对象参数前置,以通过指定参数获取该类型的对象。即使排除 get_by__and_ 的可能性,我最终会在 140 个不同的班级中获得大约 1500 个 @methods。难道没有更通用的方式来提供文档吗?
  • 没有。所有魔术方法都必须明确声明(这是以这种方式记录的要点) - PHPDoc 不理解部分名称(例如get_by_*(int $id))。对于 IDE(代码检查,而不是完成!),您有 alt 解决方案(禁用警告)。对于 phpDocumentor(或替代工具) - 我不知道任何解决方案(也许它在那里,但我不知道)。你有 github 的链接——提交新票并要求添加这样的“部分名称”匹配功能——看看他们会说什么(很可能会被拒绝)。如果它会实现,那么 IDE 可能稍后也会有它。
  • github.com/phpDocumentor/phpDocumentor2/issues -- 但请在发布您的之前检查是否不存在类似的票。
  • 感谢所有这些。目前有一张关于这方面的公开票,但一切似乎都变得平静了。我已经在其中发表了评论,我们会看看它的结果。
  • 仅供参考,phpDocumentor 的票证(以便其他用户知道您在说什么票证;也将其添加到答案本身):github.com/phpDocumentor/phpDocumentor2/issues/689
【解决方案2】:

与原始问题有些相关:

您也可以在 phpstorm 元文件中定义它。这是工厂方法(v2016.3)的示例:

// Define in .phpstorm.meta.php
namespace PHPSTORM_META {
    $STATIC_METHOD_TYPES = [
        \Factory::create('') => [],
    ];
}

// Then use in code
$factory = new \Factory();
$user = $factory->create(\User::class);
// Here you get autocomplete.
$user->subscribe();

这样,当魔法发生时,您不必在文档中阻止所有可能性。

有一些docs了解详情。

【讨论】:

  • 这不适用于 __call。它也没有记录和无效的PHP。 PHPStorm 仅支持静态定义的方法,这些方法根据输入返回混合类型。
猜你喜欢
  • 1970-01-01
  • 2019-01-30
  • 1970-01-01
  • 2011-09-30
  • 2013-12-17
  • 1970-01-01
  • 1970-01-01
  • 2019-12-04
  • 1970-01-01
相关资源
最近更新 更多