类存在多个定义

问题描述 投票:53回答:12

我正在使用Kohana框架,它允许多个类定义(在应用程序和系统子文件夹中)。我使用phpstorm作为IDE,它给我消息multiple definitions exist for class。有没有办法告诉phpStorm哪个类定义是正确的?

phpstorm
12个回答
79
投票

有没有办法告诉PhpStorm哪个类定义是正确的?

不幸的是,你不能。

https://youtrack.jetbrains.com/issue/WI-17646 - 观看此门票(星级/投票/评论)以获得有关任何进展的通知。

ATM你或者只是忽略了挥手......或者你可以配置检查以不报告这种情况(Settings/Preferences | Editor | Inspections | Undefined | Undefined class | Don't report multiple class declaration potential problems)。

即使配置了这种检查,IDE仍会询问您要跳转到哪个类声明(这是正确的行为,因为IDE不知道您是否要查看原始实现或实现自己的实现)。


唯一的另一种方法 - 确保项目中只有一个具有相同名称的类:

  • 将整个文件夹标记为已排除
  • 将单个文件标记为纯文本

两者都可以通过项目视图中的内容菜单获得,并且仅适用于项目文件(例如,如果尝试应用于库范围,将无法使用或无效)。


1
投票

我有类似的问题,这是非常烦人的。我正在使用Yii2框架,结果我最终在项目的根目录(不在应用程序的根目录中)意外创建了额外的“vendor”文件夹和composer.json,所以我最终得到了警告phpStorm很困惑哪个扩展文件夹是正确的。我删除了额外的供应商文件夹,它解决了这个问题。


1
投票

序言

猜猜有几种方法可以解决这个问题。实际上它只是一个警告,它说phpstorm不能为你提供自动完成,所以你必须更努力工作:D

我遇到了和其他许多人一样的问题,并通过忽略不需要的东西来解决它。


脚本

在composer安装之后有一个带有vendor-folder的git项目。此项目中还有一个my-project.phar,其中还包含一些供应商的东西,这引起了我的警告。


File > Preferences|Settings > Directories你必须有可能排除文件和文件夹。在我的情况下,它是.phar所以它是一个“文件”,你可以将它添加到设置窗口的底部。

sample

PHPStorm将不再重复。

这是非常具体的项目,我想moste人必须找到他们自己的解决方案,但指出这是我帮助更容易找到问题。

希望这有助于某人:)


0
投票

在我的情况下,通过删除我的composer.json中包含另一个更通用条目的代码的更具体的条目,我解决了这个问题


25
投票

您应该忽略完整的缓存文件夹。

  • 转到设置>目录
  • 选择var\cache
  • 将其设置为“排除”

来自:https://github.com/Haehnchen/idea-php-symfony2-plugin/issues/301


19
投票

我找到了解决问题的可能方法 - 我可以mark file as plain


11
投票

作为变体,您可以仅针对特定班级关闭检查。将光标放在underwaved类名下,然后Alt+EnterInspection optionsSupress for statement

PHPStorm补充道

/** @noinspection PhpUndefinedClassInspection */

上面的类声明和类名不再是underwaved。


7
投票

我到处都是网络,并没有一个选项对我有用...我已经苦苦挣扎了好几个月,今天我找到了一个解决方案,所以如果以上都不适合你,请尝试重新定义PHP包括路径列表。在“设置”>“语言和框架”>“PHP”下,确保仅配置包含项目或应用程序使用的源路径的文件夹。

我的场景是我做了很多软件包开发,虽然我的软件包都在一个项目中,但在我的作曲家配置中它们也在“vendor”中“符号链接”,因此PHPStorm在供应商文件夹中找到了重复的代码。和我的包文件夹。同样,如果包含路径重复,或者路径配置为查找项目之外的代码(已经是项目的一部分),它也会找到多个定义。因此,排除供应商中的符号链接文件夹,允许PHPStorm仅查找源的一个副本到我的包,如果我的包包含他们自己的供应商文件夹,它们也将显示为重复的定义。删除包含路径列表中可能找到应用程序的任何内容


3
投票

在项目的某个地方,同一个类有多个定义。我发现我的项目中有备份副本导致了这个警告。我从我的项目中删除了备份(无论如何都是一个好主意)并修复了错误。


3
投票

我不知道你是如何创建另一个定义的,但是如果你或任何人因调用class_alias()而出现这个问题,那么你可以快速解决这个问题。

考虑

class_alias(
    'The\AliasClass',
    'My\RealClass',
    true
);

class_alias(
    'The\AliasClass',
    'My\Real'.'Class', // <-- break up the string
    true
);

对于后者,PhpStorm不会拿起My\RealClass,你的“多重定义”警告将停止。顺便说一下,这是一个古老的JavaScript技巧,可以将HTML嵌入到字符串文字中。


2
投票

这个警告让我很长时间都很恼火。我相信这里的答案说有一个重复的文件在某处是正确的。我收到警告的原因是由于自动完成文件给phpStorm提供了如何查找codeIgniter函数的提示。如果你这样做也是一些警告的原因。自动完成文件使phpStorm认为有两种不同的定义。但是,我喜欢自动完成比我不喜欢警告,所以我想我必须和他们住在一起。

这是我指的自动填充:IntelliJ IDEA 12 not finding CodeIgniter classes, throwing errors


2
投票

Alternatives that work after a fashion, but aren't so good

  • 标记文件B您不希望自动完成使用“普通”或排除,使文件A保持活动状态:这将禁用文件C中的通知,但也会使自动完成不再适用于文件B中的任何内容。因此,如果在其他地方你使用了正确在B中的东西,也许你想要从自动完成中排除A,你就不能这样做。
  • 禁用检查:这也将禁用未定义​​的类警告,因此如果我在任何类名中进行任何拼写错误,我将仅在部署之后(或者自动完成停止为该对象工作)发现这一点。
  • “不报告多类声明潜在问题” - 这非常好,但我不喜欢忽视“潜在问题”;如果我创建一个具有在其他地方使用的无意识重复名称的类,该怎么办?承认我会抓住它(或phpunit会),但仍然。

The best I've found so far

现在的方法,至少在PHPStorm可以使用更集中的配置(例如“替代类”)之前,就是将那些通知 - 只有那些 - 标记为可忽略:

/* @noinspection PhpUndefinedClassInspection */
/**
 * Verify an existing contract. Requires agent and supervisor.
 *
 * @param array   $data
 * @param Cliente $cli
 * @param User    $age
 * @param User    $sup
 * @return Contratto
 */
private function contratto(
    array $data,
    /* @noinspection PhpUndefinedClassInspection */
    Cliente $cli,
    /* @noinspection PhpUndefinedClassInspection */
    User $age,
    /* @noinspection PhpUndefinedClassInspection */
    User $sup
) {

请注意,要在PHPDoc注释中禁用通知,我必须在注释之前添加指令;这并没有禁用三个参数的通知。

将来,我希望能够将PHPStorm中的那些指定为

 * @param array                 $data    raw data for the contract
 * @param \local\foobar\Cliente $cli     customer opening the contract

private function contratto(
    array $data,
    /*\local\foobar\*/Cliente $cli,

或者更好的是,明确使用新的PHPdoc标签,例如“@replaces”。所以PHPStorm会知道我的班级是没有被替换的班级。我还必须装饰我的use来指定我将实际使用的类。

并在我的代码中搜索“@noinspection PhpUndefinedClassInspection”。

Another way

上述问题源于这样一个事实,即我有一个“主”客户类,它被foobar客户端的“本地”修改所覆盖,其客户有(比方说)一种特殊方法。

这样做的“正确”方法应该是声明一个仅由foobar代码使用的FoobarCustomer,并且是Customer的子类。当然这只有在子类在我的代码中而不在框架中时才有可能,而且我可能需要父类中的一些方法是protected而不是private,这可能使得这个解决方案不可能或者需要Reflection

/**
 * Verify an existing contract. Requires agent and supervisor.
 *
 * @param array         $data
 * @param FoobarCliente $cli
 * @param FoobarUser    $age
 * @param FoobarUser    $sup
 * @return Contratto
 */
private function contratto(array $data, FoobarCliente $cli, FoobarUser $age...
© www.soinside.com 2019 - 2024. All rights reserved.