有什么办法可以打破PHP中的if语句?


129

是否有任何PHP命令停止执行当前或父if陈述,相同breakbreak(1)switch/ loop。例如

$arr=array('a','b');
foreach($arr as $val)
{
  break;
  echo "test";
}

echo "finish";

在上面的代码中,PHP将无法运行,echo "test";并且将转到echo "finish";

我需要这个

$a="test";
if("test"==$a)
{
  break;
  echo "yes"; // I don't want this line or lines after to be executed, without using another if
}
echo "finish";

我想对上面breakif语句停止执行,echo "yes";或者不再需要执行这样的代码,可能存在或可能没有其他条件,有没有办法做到这一点?

更新:发布此问题仅两年后,我长大了,我学会了如何以小块形式编写代码,为什么嵌套if可能是代码的味道,以及如何首先通过编写可管理的小函数来避免此类问题。


15
从逻辑上讲,您的示例都没有任何意义。
Tim Pietzcker 2011年

1
@Usman:如果没有条件,则echo(在您的示例中)将永远不会执行。因此,您最好将其删除。
奥利弗·查尔斯沃思

2
不能try catch选择吗?
giannis christofakis 2014年

首先我以为Tim太粗鲁了...但是后来我以为他是对的...为什么在无条件的中断后面会有任何代码?调试?我喜欢用continue打破for循环;并且使用“只在这里停止”命令来分解非常困难的查询将是很好的……if (condition) { if ( oneothercondition ) stop; if ( yetothercondition ) stop; // go ahead , all is fine }
Joeri

@Joeri我不知道穆罕默德最初的想法为什么他需要休息。但就我而言,这只是调试目的,对。在某些情况下,可以节省时间。在无法添加断点的情况下(由于某些原因而未使用IDE和/或必须在实时站点上工作时等)
ViktorBorítás

Answers:


216

不用担心其他用户的评论,我可以理解您,有时在开发这种“花哨的”东西时是必需的。如果我们可以打破一个if,那么就不需要很多嵌套的if,这会使代码更加简洁和美观。

此示例代码说明,在某些情况下中断if可能比许多丑陋的嵌套ifs更适合…… 如果您没有面对某些情况并不意味着它不存在

丑陋的代码

if(process_x()) {

    /* do a lot of other things */

    if(process_y()) {

         /* do a lot of other things */

         if(process_z()) {

              /* do a lot of other things */
              /* SUCCESS */

         }
         else {

              clean_all_processes();

         }

    }
    else {

         clean_all_processes();

    }

}
else {

    clean_all_processes();

}

好看的代码

do {

  if( !process_x() )
    { clean_all_processes();  break; }

  /* do a lot of other things */

  if( !process_y() )
    { clean_all_processes();  break; }

  /* do a lot of other things */

  if( !process_z() )
    { clean_all_processes();  break; }

  /* do a lot of other things */
  /* SUCCESS */

} while (0);

就像@NiematojakTomasz所说的那样,可以使用goto替代方法,但是不好的事情是您总是需要定义标签(点目标)。


29
大!有时,问题由于其深刻的理解而被误解了。您的操作非常完美,我需要简洁的代码来避免跟踪结尾if
Muhammad Usman

4
在每个成功的测试(大约3或4个测试)之后,我需要执行相同的代码,并elseif在每个失败的测试上添加一个。这正是我要搜索的内容,现在我的代码符合KISS和DRY要求:)谢谢!
s3v3n 2012年

3
男人,这感觉很脏!但是,这让我感到
欣喜

8
@rdlowrey,交谈是免费的,因此请向我们展示“精心编写的OOP”示例以解决OP问题:3
AgelessEssence

7
不要将样本的请求与人身攻击混为一谈……实际上,您缺少了一些重要的东西,并不是所有的编码都应该是OOP,这是用OOP的魔力*编写简单任务的疯狂事情。
AgelessEssence

98

将您的代码封装在一个函数中。您可以随时停止执行功能return


2
我虽然你想要一个if,而不是一个函数?;)
Arnaud Le Blanc

3
@ arnaud576875(如果代码在函数中),则可以在if语句中使用return来中断执行。
Maxim Krizhanovsky

1
一个功能应具有“ 1种方式”和“ 1种方式”。多个RETURNS草率且容易出错。
沃尔特老人

@OldManWalter这仅适用于返回实际数据。但是,错误处理是此规则的常见例外。在多个位置抛出异常或返回false是完全可以接受的,而不会遇到“ 1进1出”的心态试图防止的常见陷阱。
danielson317

41

正确的方法:

try{
    if( !process_x() ){
        throw new Exception('process_x failed');
    }

    /* do a lot of other things */

    if( !process_y() ){
        throw new Exception('process_y failed');
    }

    /* do a lot of other things */

    if( !process_z() ){
        throw new Exception('process_z failed');
    }

    /* do a lot of other things */
    /* SUCCESS */
}catch(Exception $ex){
    clean_all_processes();
}

阅读了一些评论之后,我意识到对于正常的流控制而言,异常处理并不总是有意义。对于常规控制流,最好使用“ If else”:

try{
  if( process_x() && process_y() && process_z() ) {
    // all processes successful
    // do something
  } else {
    //one of the processes failed
    clean_all_processes();
  }
}catch(Exception ex){
  // one of the processes raised an exception
  clean_all_processes();
}

您还可以将流程返回值保存在变量中,然后检入失败/异常块,哪个流程失败了。


1
在这种情况下,异常可能很有用,但似乎您滥用了它们。异常是例外,不是正常的程序流程。如果失败很特殊,那么process_x-z应该自己抛出异常;在finally块中,clean_all_processes()会更好,因为它必须清理,但还是必须这样做。
Jimmy T.

我已经改善了解决方案。
Rahul Ranjan 2014年

我最终没有使用的原因是,直到php5.5才支持它
Rahul Ranjan

20

因为您可以打破 do / while循环,所以让我们“ ”一轮。最后有一个while(false),条件永远不会为真,也不会重复。

do
{
    $subjectText = trim(filter_input(INPUT_POST, 'subject'));
    if(!$subjectText)
    {
        $smallInfo = 'Please give a subject.';
        break;
    }

    $messageText = trim(filter_input(INPUT_POST, 'message'));
    if(!$messageText)
    {
        $smallInfo = 'Please supply a message.';
        break;
    }
} while(false);

没有人说您必须使用它。这只是“突围”的一个例子。
马库斯·泽勒

2
整洁的方法-完成工作。
benjaminhull

16

转到

跳转操作符可以用来跳转到计划中的其他部分。目标点由标签和冒号指定,指令以goto给出,后跟所需的目标标签。这不是完全不受限制的goto。目标标签必须在同一文件和上下文中,这意味着您不能跳出一个函数或方法,也不能跳入一个函数或方法。您也不能跳入任何形式的循环或开关结构。您可能会跳过这些,通常的用法是使用goto代替多级中断 ...


82
每次使用时goto,小耶稣都会吃一只小猫。此外,xkcd.com / 292

12
很抱歉保持一致。我参考了php手册页,其中解释了所提到的关键字的确切用法。即使是肮脏的解决方案,它仍然是正确的解决方案。
NiematojakTomasz 2011年

3
我不完全了解这样做不是一种好习惯吗?比所有其他解决方案都简单吗?
538ROMEO

1
同意塞巴斯蒂安。在某些情况下,goto运算符非常有用且简单。
杰里

6
不用担心,程序员总是会让您感到自己编码不正确,并希望我们像他们一样编码。在php社区中,情况更是如此,因为我们是一群时髦的程序员,而PHP为我们提供了这些自由关键字,并且可以自由地判断每个人的行为方式。我goto在生产代码中使用了(不是广泛使用的)关键字,而且我从未遇到过麻烦。
vdegenne

7

存在命令: goto

if(smth) {
   .....
   .....
   .....
   .....
   .....
   goto Area1;
   .....
   .....


}



Area1:
....your code here....

但是,请goto不要记住这种做法,因为这样做会使代码的格式异常。


1
我已经测试了这个脚本,转到goto Area1下面的代码;将不会执行。
Leon Armstrong,


5

不,没有办法像循环内那样“破坏” if块。:(
因此,将您的测试变成一个switch

我想知道为什么没有人鼓励您使用switch语句,因为(即使您没有很多测试用例)
您是否认为它太冗长?

我一定会去这里

  switch($a){
    case 'test':
        # do stuff here ...
        if(/* Reason why you may break */){
           break; # this will prevent executing "echo 'yes';" statement
        }
        echo 'yes';  # ...           
        break; # As one may already know, we might always have to break at the end of case to prevent executing following cases instructions.
    # default:
        # something else here  ..
        # break;
  }

对我来说,异常是指引发错误,而不是真正控制执行缺陷。
如果您要设置的中断行为与意外错误无关,则异常处理不是此处的正确解决方案:/


有趣的主意,但我不会将其用于“真实”代码。
Jimmy T.

1
“真实”,你是什么意思?:/
斯特凡2014年

1
@Stphane最近的评论,但是在这种情况下使用开关违反了最小惊讶原则。预期switch语句将控制数据的选择,而不是控制程序流。
FWDekker

« 开关将表达式与不同值进行比较,并根据表达式等于哪个值执行特定的代码块。» 然后,每个块都可以评估子表达式,这些子表达式又可以指示执行流返回或跳过某些指令……在这种非常狭窄的用例中,我认为切换不会违反最小惊讶原则,但是,这就是原始上下文和需求确实可能需要进行一些重构。
斯特凡

4
$a = 1;

switch($a) {

  case "1":

    if  ($condition1){
      break;
    }

    if  ($condition2){
      break;
    }

    if  ($condition3){
      break;
    }
}

这样我就得到了我想要的。我使用仅具有确定大小写的开关,然后使用大小写中断选择是否满足条件。我使用break的原因:condition1和condition2可能都满足,在这种情况下,仅应用了condition1。IF是根据顺序选择的。


8
您不需要为此变量。只需使用switch(true) { case true:
Maxim Krizhanovsky 2014年

1

没有。

但是如何:

$a="test";
if("test"==$a)
{
  if ($someOtherCondition)
  {
    echo "yes";
  }
}
echo "finish";

3
谢谢,但是,我正在寻找一个更简单的版本,以避免过多的if发言
Muhammad Usman

2
@乌斯曼:如果您有多个条件,则需要检查它们。传统上,检查条件涉及一条if语句。我不确定您希望如何避免这种情况。
奥利弗·查尔斯沃思

1

只需将不应执行的代码移到else/elseif分支即可。我真的不明白您为什么要做自己想做的事情。


1

简单的答案是,不,没有一种方法可以if完全停止执行(通过exit)来中断语句。其他解决方案对我不起作用,因为我无法将if语句的结构更改,因为我将代码注入到插件中,如下所示:

if ( condition ) {
  // Code and variables I want to use

  // Code I have control over

  // Code I don't want to run
}
// More code I want to use

0

回答您的问题是否可以实现,然后使用php的“ goto”运算符可以实现。

但是从道德上讲,使用“ goto”并不是一种好习惯,并且有必要使用goto,这意味着需要重构代码,以便可以删除goto的要求。

根据您在上面发布的示例代码,可以清楚地看到该代码可以重构,不需要的代码可以删除或注释(如果将来有可能使用的话)。


0
$arr=array('test','go for it');
$a='test';
foreach($arr as $val){
  $output = 'test';
  if($val === $a) $output = "";
  echo $output;
}
echo "finish";

结合您的陈述,我想这会给您您所希望的结果。简洁明了,无需过多声明。

对于难看且美观的代码,我的建议是:

function myfunction(){
  if( !process_x() || !process_y() || !process_z()) {
    clean_all_processes();  
    return; 
  }
/*do all the stuff you need to do*/
}

普通代码中的某处

myfunction();

0

我认为您正在寻找:

if (condition) { 
    if ( oneothercondition ) continue;  
    if ( yetothercondition ) continue; 

    // go ahead , all is fine
}

php手册显示了for示例,但我认为它也适用于if


-1

我有一个简单的解决方案,无需太多更改。最初的陈述是

我想破坏上面的if语句并停止执行echo“ yes”; 还是不再需要执行这样的代码,可能存在或可能没有附加条件,是否有办法做到这一点?

因此,这似乎很简单。尝试这样的代码。

$a="test";
if("test"==$a)
{
  if (1==0){
      echo "yes"; // this line while never be executed. 
      // and can be reexecuted simply by changing if (1==0) to if (1==1) 
  }
}
echo "finish";

如果您想尝试不使用此代码,那很简单。然后您可以在需要时返回。另一个解决方案是注释块。或者只是思考并尝试另一个单独的代码,然后将结果仅复制粘贴到最终代码中。如果不再需要代码,则您的结果可能是

$a="test";
echo "finish";

使用此代码,原始语句将得到完全尊重.. :)并且更具可读性!


-2

简单的解决方案是将其注释掉。

$a="test";
if("test"==$a)
{

  //echo "yes"; //no longer needed - 7/7/2014 - updateded bla bla to do foo
}

附加的好处是您无需更改原始代码,并且可以将其标上日期,将其初始化并说明原因。

为什么要拒​​绝投票,根据OP的要求,我认为这是一个完全有效的解决方案。

“我想[打破上面的if语句并]停止执行echo“ yes”;或者不再需要执行这样的代码,可能存在或可能没有附加条件,有没有办法做到这一点?”

实际上,有人会在一年之后查看其他一些解决方案,并想知道那里正在发生什么。根据我的建议,可以将好的文档留作以后参考,这始终是好的做法。


2
这不能解决问题。休息也可能在if中。
Jimmy T.

您不能在if语句中发表评论吗?或发表评论?您的意思是使用if排除执行吗?如果是这样,那么中断的目的是什么,那不是if语句用于什么吗?只需评论一下。抱歉,看不到你的意思。
ArtisticPhoenix

像这样的东西:a:if(“ test” == $ a){... if(...)break a; …
吉米T.

-3

那么使用三元运算符呢?

<?php
 // Example usage for: Ternary Operator
 $action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
?>

与此if / else语句相同:

<?php
 if (empty($_POST['action'])) {
   $action = 'default';
 } else {
   $action = $_POST['action'];
 }
?>

在PHP7:$a = $_POST['action'] ?? 'default';
托比亚斯Mühl的

-3

要完全停止脚本的其余部分运行,您可以执行以下操作

出口; //代替休息。其余代码将不会执行


-4

我参加聚会很晚,但我想贡献自己的力量。我很惊讶没有人提出建议exit()。对测试很好。我一直使用它,就像魅力一样。

$a ='';
$b ='';
if($a == $b){
echo 'Clark Kent is Superman';
exit();
echo 'Clark Kent was never Superman';
}

该代码将在处停止,exit()之后的所有内容都将无法运行。

结果

Clark Kent is Superman

它的工作原理与foreach()while()也。它可以在您真正放置的任何地方使用。

foreach($arr as $val)
{
  exit();
  echo "test";
}

echo "finish";

结果

nothing gets printed here.

与它一起使用 forloop()

for ($x = 2; $x < 12; $x++) {
    echo "Gru has $x minions <br>";
    if($x == 4){
    exit();
    }
}

结果

Gru has 2 minions
Gru has 3 minions
Gru has 4 minions

在正常情况下

$a ='Make hot chocolate great again!';
echo $a;
exit();
$b = 'I eat chocolate and make Charlie at the Factory pay for it.';

结果

Make hot chocolate great again!

-7
$a="test";
if("test"!=$a)
{
echo "yes";                   
}
 else
 {
  echo "finish";
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.