PHPのif文を壊す方法はありますか?


129

現在または親実行を停止するにはPHPで任意のコマンドがあるif文は同じ、breakまたはbreak(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";

私がしたい上記とストップの実行文でこれを行う方法があり、そこであってもよいし、追加的な条件ではないかもしれないが、もはや実行するために必要なコードや、そのような?breakifecho "yes";

更新:この質問を投稿してからわずか2年後、私は大きくなりました。コードを小さなチャンクで記述する方法、ネストされたifがコードの匂いになる理由、そして管理しやすい小さな関数を作成することによってそのような問題を最初から回避する方法を学びました。


15
どちらの例も論理的に意味がありません。
Tim Pietzcker

1
@Usman:条件がない場合、echo(例では)は実行されません。したがって、削除することもできます。
オリバーチャールズワース2011

2
try catchオプションではありませんか?
giannis christofakis 2014

最初にティムは失礼だと思ったのですが、それでも彼は正しいと思っていました...無条件の中断の背後にあるコードがあるのはなぜですか?デバッグ?私はforループを続けることで抜け出すのが好きです。そして、非常に困難なクエリを "just stop here"コマンドでif (condition) { if ( oneothercondition ) stop; if ( yetothercondition ) stop; // go ahead , all is fine }
分割

@ジョエリ私はムハマドの休憩が必要な最初のアイデアを知りません。しかし、私の場合、今はデバッグ目的です。場合によっては、時間を節約できます。ブレークポイントを追加できない場合(IDEを使用していない場合や、何らかの理由でライブサイトで作業する必要がある場合など)
ViktorBorítás

回答:


216

他のユーザーのコメントを気にしないでください。私はあなたを理解できます。時々、この「ファンシー」なものを開発する必要があるときがあります。ifを壊すことができれば、ネストされた多くのifsは必要なくなり、コードがよりクリーンで美的になります。

このサンプルコード、壊れたifのCERTAINS SITUATIONSが、醜い入れ子になったifの多くよりもはるかに適していることを示しています

醜いコード

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、トークは無料です。OPの質問を解決するための「よく書かれたOOP」の例を示してください:3
AgelessEssence

7
サンプルのリクエストを個人的な攻撃と混同しないでください...実際、重要なものが欠けています。すべてのコーディングがOOPである必要はありません。OOPの魔法*を使って単純なタスクを書くのはめちゃくちゃです。
AgelessEssence 2013年

98

コードを関数にカプセル化します。で関数の実行returnをいつでも停止できます。


2
私はあなたがifではなく機能を望んでいたのですか?;)
アルノールブラン

3
@ arnaud576875コードが関数内にある場合、ifステートメントでreturnを使用して実行を中断できます。
Maxim Krizhanovsky、2011年

1
関数には、「1つの方法」と「1つの方法」が必要です。複数のRETURNSはずさんでエラーが発生しやすくなります。
オールドマンウォルター

@OldManWalterこれは、実際のデータを返す場合にのみ当てはまります。ただし、エラー処理はこのルールの一般的な例外です。複数の場所でスロー例外またはfalseを返すことは、「一方向、一方向」という考え方が保護しようとしている一般的な落とし穴に陥ることなく、完全に受け入れられます。
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();
}

コメントをいくつか読んだ後、例外処理は通常のフロー制御では必ずしも意味がないことに気づきました。通常の制御フローでは、「もしそうなら」を使用することをお勧めします:

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はそれ自体で例外をスローする必要があります。clean_all_processes()は、とにかく実行する必要があるクリーンアップであるため、finally-blockのほうが適しています。
ジミーT. 14

ソリューションを改善しました。
Rahul Ranjan 14

私が最後に使用しなかった理由は、php5.5までサポートされない
Rahul Ranjan

20

あなたがすることができますので、破る /ループながら、私たちは「聞かせてくださいのうち行う 1ラウンドを」。でしばらく(偽)最後に、条件が真なることはありませんし、もう一度、繰り返すことはしません。

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);

あなたはそれを使わなければならないと誰も言いません。「ブレイクアウト」する例にすぎません。
Markus Zeller、2016年

2
きちんとしたアプローチ-仕事をします。
ベンジャミン

16

goto

後藤のオペレータは、プログラム内の別のセクションにジャンプすることができます。ターゲットポイントは、ラベルとそれに続くコロンで指定され、命令はgotoの後に目的のターゲットラベルが続くように指定されます。これは完全な無制限のgotoではありません。ターゲットラベルは同じファイルとコンテキスト内にある必要があります。つまり、関数またはメソッドからジャンプしたり、そこにジャンプしたりすることはできません。また、ループやスイッチ構造にジャンプすることもできません。あなたはこれらから飛び出すかもしれません、そして一般的な使用はマルチレベルのブレークの代わりにgotoを使うことです...


82
を使用するたびgotoに、赤ん坊のイエスは子猫を食べます。また、xkcd.com / 292

12
一貫して申し訳ありません。上記のキーワードの正確な使用法を説明するphpのマニュアルページを参照しました。そして、それが汚い解決策であったとしても、それはまだ正しい解決策です。
NiematojakTomasz 2011

3
私はそうすることが良い習慣ではないことを正確に理解していませんか?他のすべてのソリューションよりもはるかにシンプルですか?
538ROMEO 2016

1
セバスチャンに同意する。場合によっては、goto演算子は非常に便利で簡単です。
ジェリー

6
心配しないでください。プログラマーは常にあなたがあなたが適切にコーディングしていないと感じさせ、私たちが彼らのようにコーディングすることを望んでいます。私たちはヒップスターのコーダーの集まりであり、PHPは私たちにこれらの自由キーワードと、誰もが物事をどのように行うかについて非常に批判的になる自由を与えてくれるので、これはphpコミュニティではさらに真実です。私は(広範囲ではなく)gotoキーワードを製品コードで使用しており、問題は一度もありません。
vdegenne '19

7

コマンドが存在します: goto

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


}



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

ただし、gotoコードを異常にフォーマットするため、remember は推奨されません。


1
このスクリプトをテストしました。以下のコードは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;
  }

私にとって例外は、エラーを発生させることを意図しており、実際には実行の欠陥を制御することを意図していません。
設定しようとしているブレーク動作が予期しないエラーに関するものではない場合、ここでの例外処理は適切な解決策ではありません:/


興味深いアイデアですが、「実際の」コードには使用しません。
ジミーT. 14

1
「本物」、どういう意味?:/
Stphane 14

1
@Stphane遅いコメントですが、この状況でスイッチを使用することは、最小の驚きの原則に反します。switchステートメントは、プログラムの流れを制御するのではなく、データの選択を制御することが期待されています。
FWDekker 2015

« スイッチは式を異なる値と比較し、式が等しい値に応じて特定のコードブロックを実行します。» 次に、各ブロックが補助式を評価し、それが実行フローに一部の命令を返すかスキップするように指示する場合があります…この非常に狭まったユースケースではスイッチが最小の驚きの原則に反するとは思わないが、これは元のコンテキストと実際、要件によってはリファクタリングが必要になる場合があります。
Stphane

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 '19

2
@Usman:複数の条件がある場合は、それらを確認する必要があります。条件のチェックには、伝統的にifステートメントが含まれます。これをどのように回避することを期待しているのかはわかりません。
オリバーチャールズワース2009

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"の実行を停止したい。または、実行する必要がなくなったコードの場合、追加の条件がある場合とない場合があります。これを行う方法はありますか?」

実際、誰かが他のソリューションのいくつかを見て(1年後)、そこで何が起こっているのか疑問に思うかもしれません。私の提案によると、将来の参考のために良いドキュメントを残すことができます。これは常に良い習慣です。


2
これは問題を解決しません。ブレイクはifにもあります。
ジミーT. 14

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!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.