派生类返回值的 PhpStorm 类型提示
Posted
技术标签:
【中文标题】派生类返回值的 PhpStorm 类型提示【英文标题】:PhpStorm type hinting for derived class return value 【发布时间】:2014-08-29 01:00:32 【问题描述】:是否可以提示 phpStorm 在下面的代码中 item()
方法的返回值具有 DOMElement
类型(不修改实际的 PHP 语句,即通过 PhpStorm 的一些外部设置或插件或使用某种 PHPDoc 注释等)?
再次,请不要建议我修改代码中的语句,尤其是 $list->item(0)->getAttribute('test')
部分。
另外,我发现了一个有点相似的问题 PhpStorm type-hinting for factories?,但它处理用户定义函数的类型提示,在我的例子中,函数 item()
是一个预定义的库函数。
$doc = new DOMDocument();
$doc->loadXML('<x test="123"/>');
$list = $doc->getElementsByTagName('x');
if($list->length > 0)
var_dump($list->item(0)->getAttribute('test'));
【问题讨论】:
只是为了做到这一点:您不能更改上面列出的任何代码?还是不能更改 item(0) 调用的实现? @nivekastoreth 只能更改空格 - 这包括添加作为空格子情况的 cmets。 已在 strubs 中修复。 github.com/JetBrains/phpstorm-stubs 外部库 -> PHP 运行时 -> 高级设置 -> 默认 srubs 路径:C:\User\Name\ 【参考方案1】:根据official docs $list->item(0)
返回没有getAttribute()
方法的DOMNode
类的元素。 PhpStorm 在此处遵循官方文档。
但是如果你在你的代码中添加额外的行并在调试器中分析它(例如$z = $list->item(0);
),你会看到$z
是DOMElement
的实例,有这样的方法。
A. 您不能即时将文档添加到预定义的方法(尤其是在链中)。没办法。
B. 正如你所看到的——这里的“问题”在文档中:他们说item()
返回一个类的实例,而在你的特定情况下它返回不同类的实例.
几个选项:
1. 修改您的代码以引入可以提供正确类型提示的中间变量。 据我了解,您不想使用它。
2. 忽略这些警告:您可以完全禁用它或仅针对该文件禁用它;您可以降低严重性(例如“信息”而不是“警告”)等
3. 更改文档(但不确定这是否是个好主意)。
这可以通过修改实际存根文件在全局级别完成(PhpStorm 发行版的一部分...所以它会影响所有项目,您必须在再次升级到新版本后重做)。
或者您可以在本地级别执行此操作(仅针对此项目):
从原始存根文件中提取DOMNodeList
类的存根
将其放在项目中任何位置的单独文件中
更改item()
方法的@return
标记- 将其设置为@return DOMElement
任何你需要的东西。
这将使 IDE “合并”来自两个来源的文档:类似于 @return DOMNode|DOMElement
。
再一次——这将涵盖你的特殊情况——这将如何影响你的其他情况,我不知道。
【讨论】:
提取我没有想到的存根文件,这非常聪明——尽管我认为如果有人将其发送给我,我会拒绝该代码审查,因为如果 PHP 版本可能会导致误导性文档改变了。 嗯 .. 这仅适用于 IDE——这样的文件不需要包含在项目的实际代码库中(这也意味着:不要将此类文件放在实际项目中,只需链接它:通过附加内容根目录或包含路径)。【参考方案2】:我不确定您无法编辑 PHP 语句但同时能够编辑 PHPDoc cmets 究竟是什么意思,但您可以通过执行以下操作来完成您的要求:
<?php
$doc = new DOMDocument();
$doc->loadXML('
<x test="123"/>');
$list = $doc->getElementsByTagName('x');
if($list->length > 0)
/** @var DomElement $element */
$element = $list->item(0);
var_dump($element->getAttribute('test'));
但这在技术上并不安全,因为 getElementsByTagName 返回一个 DomNodeList,它指定它包含 DomNodes(尽管我不够熟悉,不知道是否出于所有实际目的该列表将只包含 DomElements)
无论哪种方式,当我查看此示例代码时,所使用的方法已经正确记录,您的问题是您正在尝试指定,如上所述,在 DOM 代码中未(特别)强制执行的特殊约束/cmets。
【讨论】:
这正是我不想做的——将$list->item(0)->getAttribute('test')
分成几个部分并引入新变量。
想你可能会这么说。你只是说 list() 是预定义的,并不是说调用 $list->item() 的代码也是不可修改的。以上是关于派生类返回值的 PhpStorm 类型提示的主要内容,如果未能解决你的问题,请参考以下文章