【问题标题】:PHP - If/else, for, foreach, while - without curly braces?PHP - If/else, for, foreach, while - 没有花括号?
【发布时间】:2023-07-20 11:04:01
【问题描述】:

真正想知道但从未发现的东西是 PHP 中的快捷方式。

我目前正在编写一个带有foreach 循环的函数,其中只有一个语句。我试图省略花括号,就像在 if/else 控制结构中可以做的那样,它可以工作。没有错误。

foreach($var as $value)
    $arr[] = $value;

现在我尝试以相同的方式使用它,但在其中放置了一个 if/else 块。再次,正常工作,没有错误。

foreach($var as $value)
    if(1 + 1 == 2) {
        $arr[] = $value;
    };

然后,我想“为什么会这样?”并省略了结束分号。还在工作。因此,我尝试在 foreach 循环中使用不带花括号的 if/else 语句,并且再次使用,仍然有效且没有错误。但是 foreach 循环现在真的关闭/结束了吗?

foreach($var as $value)
    if(1 + 1 == 2)
        $arr[] = $value;

至少我再次省略了结束分号,并且(如预期的那样)发生了解析错误。

所以我的大问题是:我什么时候可以省略花括号以及在哪个结构/循环/函数中?我知道我绝对可以在ifelse 中这样做。但是whileforforeach 呢?

是的,我知道它不安全、不聪明,无论在没有花括号的情况下进行编码,还有像 $condition ? true : false;if: doSomething(); endif;endfor;endforeach; 这样的速记。我不想学习速记我只想了解何时何地可以省略大括号的条件。

【问题讨论】:

  • 顺便说一下,没有必要在右大括号后放置分号。 this 的句法含义是在它们之间添加一个空语句。除了在 C 和 C++ 中声明 structclass 之外,所有类 C 语言都是如此。
  • 您需要了解语句和表达式之间的区别才能了解何时可以省略大括号。然后仍然需要对表达凝聚力有深刻的理解。

标签: php if-statement foreach curly-braces


【解决方案1】:

当你省略大括号时,它只会将下一条语句视为条件的主体。

if ($x) echo 'foo';

相同
if ($x) { echo 'foo'; }

但请记住

if ($x)
  echo 'foo';
  echo 'bar';

总是打印“bar”

在内部则相反:if 只会查看下一个表达式,但 PHP 将 {} 中的所有内容视为单个“分组”表达式。

其他控制语句也一样(foreach,等等)

【讨论】:

  • 非常好的简短解释,谢谢! :) 它适用于每个控制结构吗?
  • 应该的。目前不知道(也无法测试)do{}while($X); 或“开关”是什么。
  • @headacheCoder 是的,它适用于forwhileforeachif。对于每种具有类 C 语法的语言也是如此。请注意@tkone 的回答,关于始终使用大括号的良好做法。
  • @headacheCoder:它甚至适用于每个表达式,请参阅php.net/expressions
  • 有一个例外;它不适用于Exceptions。双关语完全是故意的。
【解决方案2】:

有些地方你可以,但你永远不应该。

显式总是优于隐式。

谁知道你什么时候必须回去修改旧代码。很容易错过这些东西,而且这样做没有任何收获。

【讨论】:

    【解决方案3】:

    如果你里面只有一个参数,它会工作得很好!。但是如果你想省略花括号,你可以使用冒号和结尾。 示例:

    if(a < 1 ) :
        echo "a is less than 1";
    else :
        echo "a is greater than 1";
    endif;
    

    【讨论】:

      【解决方案4】:

      如前所述,您不想了解速记,并且接受的答案给出了省略curly braces 的好例子,但还有一些东西要补充。如您所见,在if ($x) echo 'foo'; 的情况下省略curly braces 很好。代码没有问题,没有性能或其他问题,其他开发人员可以阅读。并且示例还向您展示了,如果您编写

      if ($x)
          echo 'foo';
          echo 'bar';
      

      而不是

      if ($x)
          echo 'foo';
      
      echo 'bar';
      

      您可能会遇到不需要的结果,其中打印了 bar 而您不希望它被打印,如果您的代码中充满了此类语句,那么您将更难阅读自己的代码,甚至更多其他人更难阅读。

      我不想了解速记,我只想了解何时何地可以省略大括号的条件。

      这些东西是密切相关的,所以如果你真的想了解可以省略大括号的地方,那么你应该了解或至少知道速记,阅读过

      1. PHP Control Structures
      2. The PHP ternary conditional operators and expressions in general

      所以我的大问题是:我什么时候可以省略花括号以及在哪个结构/循环/功能中?

      花括号不是必需的,但是为了可读性和维护,许多开发人员会认为不包含它们是不好的风格。当您可以省略花括号时,前 2 个链接应为您提供做出自己决定所需的信息。 例如,下面的代码 sn-ps 没有任何问题,它们都做同样的事情。

      带花括号

      if (PHP_VERSION_ID < 70000)
      {
          print "PHP >= 7.0 required yours is ";
          print phpversion();
          print "\n";
          exit(1);
      }
      

      if (PHP_VERSION_ID < 70000) :
          print "PHP >= 7.0 required yours is ";
          print phpversion();
          print "\n";
          exit(1);
      endif;
      

      或者你可以使用点运算符

      if (PHP_VERSION_ID < 80000)
          (print "PHP >= 7.0 required yours is ") . (print phpversion()) . (print "\n") . exit(1);
      

      你可以使用三元条件运算符,甚至可以省略if它自己,除了省略花括号

      (PHP_VERSION_ID > 70000) ?: (print "PHP >= 7.0 required yours is ") . (print phpversion()) . (print "\n") . exit(1);
      

      由于我们只打印,我们可以缩短它并去掉一些 print string functions,它们在这里表示语句中不带花括号的多个函数

      (PHP_VERSION_ID > 70000) ?: (print "PHP >= 7.0 required yours is " . phpversion() . "\n") . exit(1);
      

      从 php 7 开始,我们可以使用 Null 合并运算符

      (PHP_VERSION_ID > 70000) ?: null ?? (print "PHP >= 7.0 required yours is ".phpversion() . "\n") . exit(1);
      

      可以看出,有很多方法可以获得完全相同的结果。这不仅适用于这个if 示例,而且同样适用于structure/loop/function。所以对于您的大问题,没有一个答案。应该主要考虑以下。

      1. 您编写的代码是否易于维护。
      2. 您能自己回答一下,您是否可以通过省略花括号来赢得一些东西。

      【讨论】:

      • 嗯,我不知道他们在 Elvis 运算符中添加了一个空合并运算符……很整洁。但是运算符的哪一侧为空,它是否允许在条件块中未设置变量?
      • $I_want_value = $if_im_not_null_use_me ?? $if_first_is_null_use_me ?? $if_second_is_null_use_me; 因此,如果先前的变量为 NULL,您可以有尽可能多的选择; PHP 7 New-features
      • 有趣,所以它是一个无限运算符......但它是否适用于未定义的变量?我会检查文档。我认为这是拥有空合并运算符的唯一目的,否则为什么不直接使用 Elvis。 ?:)
      • 啊,是吗?确实适用于未设置的变量,文档说。精彩的!这可能会减少 PHP 中 isset() 调用的大量麻烦。
      【解决方案5】:

      我在我的 PHP 模板中省略了花括号。例如。您可以按如下方式使用循环:

      <ul>
          <?php foreach ($var as $value): ?>
              <li><?php echo $value; ?></li>
          <?php endforeach; ?>
      </ul>
      

      【讨论】:

      • 替代语法有所不同。
      • OP 甚至说他知道替代语法,而不是问题所在。
      【解决方案6】:

      您可以将它用于简单的事情,例如:

      if($a === true) continue;
      

      但对于一些更复杂的子条件,它可能会给你带来问题:

          $a = false;
          $b = false;
          if ($a === true)
              if ($b === true)
                  echo 1;
          else
              echo 2;
      

      使用上面的代码,您希望看到“2”作为输出,但您不会。

      【讨论】:

        【解决方案7】:

        为了补充@Marko的答案,请注意,在使用点运算符时,您应该将每个操作括在括号中,否则会颠倒顺序。

        例如,下面这段代码将打印PHP &gt;= 7.0 required yours is 5.6.15

        (print "PHP >= 7.0 required yours is ") . (print phpversion()) . (print "\n");
        

        虽然这将打印5.6.151PHP &gt;= 7.0 required yours is 1

        print("PHP >= 7.0 required yours is ") . print(phpversion()) . print("\n");
        

        您也可以使用and 运算符来实现此目的。像这样:

        if (PHP_VERSION_ID < 70000)
            print("PHP >= 7.0 required yours is ") and
            print(phpversion()) and
            print("\n");
        

        【讨论】:

          【解决方案8】:

          对于单行语句。

          如果你尝试这样做

          foreach($array as $x => $y)
              $do_something = $x;
              $do_something_else = $y;
          

          除非我弄错了,否则 php 解释器会将 foreach 语句下的第二行视为隐含大括号之外

          由于缩进,如果您稍后返回此代码,或者其他开发人员查看您的工作,这会令人困惑。

          因此,在这些语句中始终使用大括号通常是明智的。它将避免以后的头痛/困惑

          【讨论】:

          • 你是对的。第二行不在循环内。只有下一个表达式是。
          【解决方案9】:

          当您的子句后只有一个表达式时,这是可能的/

          例如,

          foreach($var as $value)
              if(1 + 1 == 2) {
                  $arr[] = $value;
              };
          

          是正确的,但是

          foreach($var as $value)
              $somevar = $var;
              if(1 + 1 == 2) {
                  $arr[] = $value;
              };
          

          不是,php解释器会认为if语句在foreach之外

          【讨论】:

            【解决方案10】:

            答案很简单。在 C/C++ 中也是如此。

            if, if/else, if/else if/else and loops => 如果下一条语句是单行,你可以省略花括号。

            例如:

            for($i= 0; $i<=100; $i++)
            {
                if($i % 7 == 0)
                {   
                    echo $i . "<br>";
                }
            
            }
            

            也可以这样写:

            for($i= 0; $i<=100; $i++) if($i % 7 == 0) echo $i . "<br>";
            

            【讨论】:

              【解决方案11】:

              我什么时候可以省略花括号以及在哪个结构/循环/功能中? 我知道我绝对可以在 if 和 else 中这样做。但是关于 while、for 和 foreach?

              对于 If/else,通过使用以下构造,可以使 singlemultiple statements 不带花括号:

              <?php
                if ($x):
                  echo 'foo';
                  echo 'bar';
                else:
                  echo 'nofoo';
                  echo 'nobar';
                endif;
              ?>
              

              this answer中所述

              对于whileforforeach,只允许单个语句不带大括号

              <?php
              foreach($array as $x => $y)
                  $do_something = $x;
              ?>
              

              【讨论】:

                【解决方案12】:

                PHP 速记表达式从 PHP 5.3 开始提供

                $condition ? $value_if_true : $value_if_false
                
                $a ? $b : ( $c ? $d : ( $e ? $f : $g ) )
                

                【讨论】: