【问题标题】:Zend Studio reports warning: Assignment in condition. Is this so bad?Zend Studio 报告警告:分配条件。这有那么糟糕吗?
【发布时间】:2025-11-22 12:30:01
【问题描述】:

我最近开始使用 Zend Studio,它报告了以下类型的代码警告:

$q = query("select * from some_table where some_condition");
while ($f = fetch($q)) {
  // some inner workings
}

要停止警告,代码需要这样编写:

$q = query("select * from some_table where some_condition");
$f = fetch($q);
while ($f) {
  // some inner workings
  $f = fetch($q);
}

为什么这被标记为警告?有这么严重吗?

我了解该警告可能旨在阻止以下错误:

$a = 1;
while ($a = 1) {
  // some inner workings
  $a++;
}

它永远不会终止,因为 1 被分配给 $a,而 $a 又将 1 返回给 while 语句,而不是针对 $a 进行测试并在 $a 不为 1 时返回 false 给 while 语句。

容易犯的错误可能会验证警告,但在第二个示例中忘记在 while 块的末尾添加额外的 $f = fetch($q) 也会导致循环永远不会终止。如果我更改代码以删除警告,然后忘记在 while 块的末尾添加 $f = fetch($q) Zend 将不会警告!

因此,通过删除有关常见错误的警告,我将自己设置为另一个常见错误。

出锅,入火。

【问题讨论】:

    标签: zend-framework warnings while-loop variable-assignment conditional-statements


    【解决方案1】:

    这可能被标记为警告,因为人们经常在意思是“==”时错误地使用“=”。

    例如:

    $a = 1
    while($a = 1) {
       $a++;
    }
    

    这永远不会终止,但如果你认为你写了“==”,它应该会。

    【讨论】:

    • 这当然是由于 PHP 选择 =(等于)作为赋值运算符,而不是说 :=(冒号等于)。
    • PHP 的选择受到了 C 的影响。几乎所有其他语言也是如此。不要因为 C 语言的流行而责怪 PHP。
    • 检测这种错误的一种方法是反转语句:1 == $a。 PHP 会抛出一个错误,因为左边的部分是不可赋值的。
    【解决方案2】:

    它不好的原因是很多人使用“=”来表示“==”

    = 运算符会将赋值返回到左侧,因此如果您使用 if($x=true),则 if 中的代码将运行,如果您使用 if($x=false),则代码将不会运行。这是一个巧妙的技巧,可以节省一两行代码,但它也很危险,因为如果您的意思是 if($x == false) 并输入 if($x = false),这将是一个难以追踪的错误。

    【讨论】:

      【解决方案3】:
      while (($row = $sql->db_Fetch("MYSQL_ASSOC")) != false)
      

      【讨论】:

      • +1 简单,甜美。使表达式意图的意图更加清晰,并抑制来自工作室的警告
      【解决方案4】:

      实际上,我想您的问题已经得到了一定程度的回答。但为了解决您的实际问题,我认为这可能会有所帮助。

      //i dont know what is returned if there are no more records to fetch...
      //but lets assume it is a boolean value
      while (($f = fetch($q))!= false)
      {
          $this->doSomethingVeryImportantThatMakesYourBossHappy($f);
      }
      

      这应该可以解决问题,并且“Assignment in condition”消息应该会消失。

      作为旁注:使用等于运算符的方式与否定事物时的方式相同。您还可以将等号与其他运算符一起使用,例如

      if ($falseness != false){$trueness = true}
      

      而不是

      if ($falseness ! false){$trueness = false}
      

      这有助于我始终记住如何比较值而不是给它们赋值。

      【讨论】:

        【解决方案5】:

        不,我的朋友所有条件中的作业都会生成此警告。我不想完全关闭它,因为 = 而不是 == 是我容易出现的语法错误。 至于为什么有必要的问题,我将使用 PHP 手册中的一个示例。这是来自“MySQL 改进”扩展或 mysqli 的部分:

        $query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 50,5";
        
        if ($result = $mysqli->query($query)) {
        
            /* fetch associative array */
            while ($row = $result->fetch_assoc()) {
                printf ("%s (%s)\n", $row["Name"], $row["CountryCode"]);
            }
        

        不幸的是,我已经使用这种技术开发了我的数据库函数,并尝试在 Zend Studio 中使用它们。这个错误已经出现了足够多的时间来成为一个真正的痛苦。我将在这里重新提出建议,因为我重视明确的代码,但是我也会跳到 PHP 手册并建议他们更改示例以使用更好的样式。也许你们中的一些人可以这样做,我们可以改进文档?!

        【讨论】:

          【解决方案6】:

          因此,您不必在没有正当理由的情况下重写所有代码: 您可以在 Window | 中禁用对这种潜在编程错误的检测。首选项,PHP |语义分析

          【讨论】:

          • 实际上,我决定采用已接受的答案,因为它在功能上更合理。我会避免将空作业作为条件。
          • “Zend Studio 需要重建所有项目,因为这个变化。”一个小时后,我意识到我点击了“应用”,现在担心它是否必须重新重新构建 BS。
          【解决方案7】:

          Zend Studio 正在努力帮助您编写更易于调试的更好代码。禁用语义检查不是一个好主意,它只会将潜在的问题扫到地毯下,而您将错过真正的问题。这是一个正当的理由!不要通过忽略警告消息来避免警告消息,通过实施正确的解决方案来修改您的代码。

          【讨论】:

            【解决方案8】:

            众所周知,Zend Studio 是基于 Eclipse 构建的,Eclipse 是一个 Java IDE。在 Java 语言中,这样做是非法的:

            String s;
            while (s = getName()) {
                ...
            }
            

            那是因为即使 'getName' 返回一个空值,它也会被分配给 's' 并且对象和布尔值(这是条件语句所需的类型)之间的转换与 PHP 一样有点主观,因此它会在编译时抛出异常。

            PHP 中的情况可能有所不同,但出于某种原因,Zend 开发人员决定默认保持此警告处于活动状态,您可以如前所述禁用它,但我认为它会在发生真正的条件分配时为您提供帮助。

            清除警告非常简单,只需分配结果然后像这样进行比较:

            if (($result = $mysqli->query ( $query )) == true) {
            

            代替:

            if ($result = $mysqli->query ( $query )) {
            

            如您所见,您不需要额外的代码。

            反正只是一个警告,你不用太担心他们。

            【讨论】: