尽管代码示例来自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认为$this
是MacroServiceProvider
,但是在Collection
中执行了回调。因此,执行后$this
将是Collection
。我要实现的是指示代码验证器,回调内部的$ this是Collection
实例。
是否可以注释$this
并说明它属于Collection
实例?
P.S。 PHP版本是7.3,IDE是PHPStorm,但我认为这没关系。
P.P.S。该代码工作正常。仅仅是关于phpstan验证。
答案 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的安装目录中而不是项目目录中。