【问题标题】:how to tell eclipse php linter that a variable exists?如何告诉eclipse php linter变量存在?
【发布时间】:2019-09-03 09:18:40
【问题描述】:

编辑:我从 Eclipse 版本 4.12.0 和 PDT 版本 6.2.0.201812112302 更新到 Eclipse 版本 4.13.0M3(预发布)和 PDT 版本 6.3.0.201908130957(预发布),我无法再复制预发布版本中的问题,现在正在执行/** @var variableType $variableName */ 使错误静音 - 在实际版本发布之前我不会肯定地说,但我很确定这只是一个错误。 (已在 dev 中修复但尚未发布)

我有这个非常简单的代码:

<?php
declare(strict_types = 1);
namespace vaporfs;

/** @var array $config */
$config["db"]["dsn"] = "mysql:host=127.0.0.1;port=3306;dbname=vaporfs;charset=utf8mb4";
$config["db"]["username"] = "vaporfs";
$config["db"]["password"] = "ffaXIgcDAmXkB5iJXG";

仅此而已。并且 eclipse linter 在尝试使用它之前抱怨 $config 不存在:

我如何告诉 eclipse linter 变量 $config 确实存在?

(我真的认为答案是 /** @var array $config */,但显然不是。或者我做得正确,但它可能是 linter 中的错误?)

【问题讨论】:

  • 你导入变量了吗?还是你在这个代码sn-p here中创建它?
  • @LLJ97 现在我正在那里创建变量,但将来我可能会在其他地方创建它,因此我不想在这里用$config=[]; 声明/清除它,所以我希望 eclipse 假设变量已经存在在这里。 isset() 守卫似乎可以工作,但我希望有更好的方法:if(!isset($config)){ $config=[]; }
  • 但这不是一个错误,因为 PHP 允许使用未定义的变量(显然),但由于变量未初始化,eclipse 仍然是正确的。这并不漂亮,但日食是对的,IMO。如果您在其他地方创建并导入它,eclipse 会将其标记为未定义,因为 linter 忽略 require/include 语句。
  • @LLJ97 只是为了证明一点:现在我创建了一个内容为 &lt;?php namespace vaporfs;$config=["foo"=&gt;"bar"];require_once('config.php');var_dump($config); 的新文件 - eclipse 仍然抱怨 $config 未定义,现在 eclipse linter 错误,$config 确实存在。我如何告诉 linter $config 已经存在?
  • @LLJ97 顺便说一句,我在 2016 年遇到了同样的问题,eclipse linter 没有意识到存在一些变量。 2016 年的解决方案是明确告诉 linter 该变量与 /** @var variableType $variableName */ 存在,但似乎不适用于现代版本的 eclipse?那么现代的做法是什么? - 仅作记录,我现在使用的是 eclipse 版本 2019-06 (4.12.0),PDT 版本为6.2.0.201812112302,但我不记得我在 2016 年使用的是什么版本

标签: php eclipse static-analysis eclipse-pdt


【解决方案1】:
/** @var array $config */

完全正确。即将推出的 PDT 6.3 已经支持此功能。

【讨论】:

    【解决方案2】:

    您将未定义的变量视为数组。 linter 给你一个警告,它是绝对正确的。这并不意味着代码不起作用。它只是警告你它可能有问题。注释在这里没有帮助。变量在你分配给它的那一刻就是数组,就好像它是一个数组一样,所以注释没有告诉任何新的东西。 是否将此文件包含在另一个文件中,该文件在包含 config.php 的范围内定义了变量,这无关紧要,因为 linter 会孤立地处理该文件。您也可以从未定义变量的上下文中包含文件,但这超出了 linter 的范围。因此,linter 更愿意警告您,因为它认为将文件包含在未定义变量的范围内是可能的。这一切都归结为您在全局范围内编写代码,因此它具有副作用。当您包含更多此类文件时,全局范围将混合在一起,并且混合方式将取决于包含的顺序。

    您的选择是:

    1) 确保它在 config.php 中定义

    $config = [];
    //the rest of your code here
    

    if (!isset($config)) {
      $config = [];
    }
    // rest of your code here
    

    但您可能还想检查它是否为数组,否则抛出异常。

    2) 从具有副作用的全局范围中删除代码,将其移至函数中:

    function createConfig(array $config = []) {
      // your code comes here
      return $config;
    }
    

    3) 接受这样一个事实,即您确定以正确的方式包含它,并且 linter 会警告您可能发生的事情,但您确定它没有发生。

    IMO 最好的办法是选项 2 - 避免全局范围的副作用。

    【讨论】:

    • 1:如果没有办法在不更改代码的情况下消除您知道不正确的 linter 错误,那么这就是一个糟糕的 linter。 2:这可能只是一个错误,因为我从 eclipse 版本 4.12.0 和 PDT 版本 6.2.0.201812112302 更新到 eclipse 版本 4.13.0M3(预发布)和 PDT 版本 6.3.0.201908130957(预发布),并且我无法再在预发布版本中重现该问题,现在正在执行 /** @var variableType $variableName */ 使错误静音 - 在实际版本发布之前我不会肯定地说,但我很确定这只是一个错误
    • 我不会抱怨 linter。在全球范围内这样做首先是一种糟糕的方法......而且这又不是一个 linter 错误,而是一个警告。代码无论如何都可以工作。 @hanshenrik
    猜你喜欢
    • 2012-01-19
    • 2021-10-27
    • 2015-08-16
    • 1970-01-01
    • 1970-01-01
    • 2014-01-05
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    相关资源
    最近更新 更多