如何在回调函数内部注释$ this

时间:2019-03-17 07:21:04

标签: php laravel

尽管代码示例来自Laravel,但这不是Laravel问题!

所以我有这部分代码

class MacroServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Collection::macro('method_name', function () {
            return $this->map(function ($item) {
                //...do something;
            });
        });
    }
}

问题是$this不属于MacroServiceProvider,而是Collection,并且我的IDE和phpstan当然会向我显示错误。

编辑:问题尚不清楚。 IDE认为$thisMacroServiceProvider,但是在Collection中执行了回调。因此,执行后$this将是Collection。我要实现的是指示代码验证器,回调内部的$ this是Collection实例。

是否可以注释$this并说明它属于Collection实例?

P.S。 PHP版本是7.3,IDE是PHPStorm,但我认为这没关系。

P.P.S。该代码工作正常。仅仅是关于phpstan验证。

2 个答案:

答案 0 :(得分:3)

最简单的解决方案是为$this支持一个文档块-它确实适用于PhpStorm,不确定phpstan:

class MacroServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Collection::macro('method_name', function () {
            /** @var Collection $this */
            return $this->map(function ($item) {
                //...do something;
            });
        });
    }
}

但是请记住,对该猴子修补的Collection方法的任何调用都将导致相同的问题-IDE和分析器都不会知道它的存在。我个人会避免这些策略-我宁愿使用组合将Collection嵌入到其他对象中-无论是您的自定义collection类还是需要您collection的某些容器。但这当然不是Laravel式的工作方式。

更新。找到了一些不错的phpstan包装器-larastan-“支持Laravel的美丽魔力”。可能会有帮助。

答案 1 :(得分:0)

向IDE提供提示的另一种方法是拥有一个方法存根文件。对于在Collection类上创建的宏,它看起来可能与此类似:

<?php


namespace Illuminate\Support{ 

    /**
     * 
     *
     */ 
    class Collection{
        /**
         *
         *
         * @return Collection
         */ 
        public function method_name() {}
    }
}

这是laravel-ide-helper之类的软件包用来向IDE提供有关Laravel中许多动态方法调用和依赖项注入的提示的技术之一。

作为参考,这是它生成的_ide_helper.php文件的完整示例,摘自他们的自述文件:https://gist.github.com/barryvdh/5227822

根据标题,它至少应适用于Netbeans,PhpStorm和Sublime Text 2 CodeIntel。

充满方法存根的文件说明了像PhpStorm这样的IDE可以如何为已编译到PHP运行时中的标准库提供代码提示(IntelliSense)。区别在于这些存根位于IDE的安装目录中而不是项目目录中。