Adakah cara untuk memecah pernyataan if dalam PHP?

129

Apakah ada perintah dalam PHP untuk berhenti mengeksekusi pernyataan saat ini atau induknya if, sama dengan breakatau break(1)untuk switch/ loop. Sebagai contoh

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

echo "finish";

dalam kode di atas PHP tidak akan melakukan echo "test";dan akan pergi keecho "finish";

Saya butuh ini untuk jika

$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";

Saya ingin breakpara ifpernyataan di atas dan berhenti mengeksekusi echo "yes";atau kode seperti yang tidak lagi diperlukan untuk dieksekusi, mungkin ada atau mungkin tidak kondisi tambahan, apakah ada cara untuk melakukan hal ini?

Pembaruan: Hanya 2 tahun setelah memposting pertanyaan ini, saya tumbuh dewasa, saya belajar bagaimana kode dapat ditulis dalam potongan kecil, mengapa bersarang jika itu bisa menjadi bau kode dan bagaimana menghindari masalah seperti itu di tempat pertama dengan menulis fungsi kecil yang dapat diatur.

Muhammad Usman
sumber
15
Tak satu pun dari contoh Anda yang masuk akal secara logis.
Tim Pietzcker
1
@ Usman: Jika tidak ada kondisi, maka echo(dalam contoh Anda) tidak akan pernah dieksekusi. Jadi sebaiknya Anda hapus saja.
Oliver Charlesworth
2
Bukan try catchpilihan?
giannis christofakis
Pertama saya pikir Tim hanya kasar ... Tapi kemudian saya pikir dia benar ... Mengapa Anda memiliki kode di balik jeda tanpa syarat? Debugging? Saya suka keluar untuk loop dengan melanjutkan; Dan alangkah baiknya memecah pertanyaan yang sangat sulit dengan perintah "berhenti di sini" ...if (condition) { if ( oneothercondition ) stop; if ( yetothercondition ) stop; // go ahead , all is fine }
Joeri
@ Joeri saya tidak tahu ide awal Muhhamad mengapa dia perlu istirahat; Tetapi dalam kasus saya sekarang ini tujuan debugging, benar. Dalam beberapa kasus ini akan menghemat waktu. Dalam kasus-kasus ketika tidak dapat menambahkan breakpoint '(ketika tidak menggunakan IDE dan / atau harus bekerja di situs langsung karena beberapa alasan, dll.)
Viktor Borítás

Jawaban:

216

Jangan khawatir tentang komentar pengguna lain, saya bisa mengerti Anda, TERKADANG ketika mengembangkan hal-hal "mewah" ini diperlukan . Jika kita dapat memecahkan if, banyak if bersarang tidak diperlukan, membuat kode jauh lebih bersih dan estetika.

Kode sampel ini menggambarkan bahwa SITUASI TERTENTU di mana rusak jika bisa jauh lebih cocok daripada banyak ifs bersarang jelek ... jika Anda belum menghadapi situasi tertentu tidak berarti itu tidak ada .

Kode jelek

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

}

Kode yang terlihat bagus

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

Seperti @NiematojakTomasz mengatakan, penggunaan gotoadalah alternatif, hal buruk tentang ini adalah Anda selalu perlu mendefinisikan label (target poin).

AgelessEssence
sumber
29
Bagus! Terkadang pertanyaan disalahpahami karena perasaan mereka yang dalam. Anda mendapatkannya dengan sempurna, saya perlu kode bersih untuk menghindari pelacakan akhirif
Muhammad Usman
4
Saya perlu menjalankan kode yang sama setelah setiap tes yang berhasil (sekitar 3 atau 4 tes), dan menempatkan elseifpada setiap tes yang gagal. Ini persis apa yang saya cari, sekarang kode saya KISS dan DRY compliant :) Terima kasih!
s3v3n
3
Man ini terasa kotor! Tapi itu mendapat dukungan saya .. Saya sedang mengerjakan sistem yang kotor;)
LeonardChallis
8
@rdlowrey, bicara gratis, jadi TOLONG tunjukkan pada kami contoh "OOP yang ditulis dengan baik" untuk menyelesaikan pertanyaan OP: 3
AgelessEssence
7
Jangan bingung permintaan sampel untuk serangan pribadi ... pada kenyataannya, Anda kehilangan sesuatu yang penting, tidak semua pengkodean harus OOP, adalah hal gila menulis tugas-tugas sederhana dengan * sihir OOP.
AgelessEssence
98

Enkapsulasi kode Anda dalam suatu fungsi. Anda dapat berhenti menjalankan fungsi returnkapan saja.

Maxim Krizhanovsky
sumber
2
Saya pikir Anda ingin jika, bukan fungsi? ;)
Arnaud Le Blanc
3
@ arnaud576875 jika kode tersebut dalam suatu fungsi, maka Anda dapat menggunakan kembali dalam pernyataan if, untuk menghentikan eksekusi.
Maxim Krizhanovsky
1
Suatu fungsi harus memiliki "1 jalan masuk" dan "1 jalan keluar". Banyak RETURNS ceroboh dan rentan kesalahan.
Pak Tua Walter
@OldManWalter Itu hanya berlaku untuk mengembalikan data aktual. Namun penanganan kesalahan adalah pengecualian umum untuk aturan ini. Pengecualian lemparan atau pengembalian salah di beberapa lokasi sangat dapat diterima tanpa memukul perangkap umum mentalitas "1 jalan masuk, 1 jalan keluar" berusaha melindungi.
danielson317
41

cara yang tepat untuk melakukan ini:

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

Setelah membaca beberapa komentar, saya menyadari bahwa penanganan pengecualian tidak selalu masuk akal untuk kontrol aliran normal. Untuk aliran kontrol normal, lebih baik menggunakan "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();
}

Anda juga dapat menyimpan nilai pengembalian proses dalam variabel dan kemudian memeriksa blok kegagalan / pengecualian yang prosesnya gagal.

Rahul Ranjan
sumber
1
Pengecualian bisa bermanfaat dalam kasus ini tetapi tampaknya Anda menyalahgunakannya. Pengecualian luar biasa, bukan untuk aliran program normal. Jika kegagalannya luar biasa maka process_x-z harus membuang pengecualian dengan sendirinya; clean_all_processes () akan lebih baik di akhirnya-blok karena itu bersih yang harus dilakukan pula.
Jimmy T.
Saya telah meningkatkan solusinya.
Rahul Ranjan
Alasan saya tidak menggunakan akhirnya adalah, itu tidak didukung sampai php5.5
Rahul Ranjan
20

Karena Anda dapat mematahkan keluar dari do a / while, mari kita " melakukan " satu putaran. Dengan beberapa saat (false) pada akhirnya, kondisinya tidak pernah benar dan tidak akan terulang lagi.

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
sumber
Tidak ada yang mengatakan Anda harus menggunakannya. Itu hanyalah contoh untuk "keluar".
Markus Zeller
2
Pendekatan rapi - melakukan pekerjaan.
benjaminhull
16

kebagian :

The goto operator dapat digunakan untuk melompat ke bagian lain dalam program ini. Titik target ditentukan oleh label diikuti oleh titik dua, dan instruksi diberikan sebagai goto diikuti oleh label target yang diinginkan. Ini bukan goto tanpa batasan penuh . Label target harus berada dalam file dan konteks yang sama, artinya Anda tidak dapat melompat keluar dari fungsi atau metode, juga tidak dapat melompat ke dalamnya. Anda juga tidak dapat melompat ke struktur loop atau switch apa pun. Anda mungkin melompat keluar dari ini, dan umum digunakan adalah dengan menggunakan goto di tempat multi-level istirahat ...

NiematojakTomasz
sumber
82
Setiap kali Anda menggunakan goto, Bayi Yesus makan anak kucing. Juga, xkcd.com/292
12
Maaf karena konsisten. Saya telah mereferensikan halaman manual php yang menjelaskan penggunaan tepat dari kata kunci yang disebutkan. Dan bahkan jika itu solusi kotor itu masih solusi yang benar.
NiematojakTomasz
3
Saya tidak mengerti persis bagaimana itu bukan praktik yang baik untuk melakukannya? Ini jauh lebih sederhana daripada semua solusi lain?
538ROMEO
1
Setuju dengan Sébastien. Dalam beberapa kasus, operator goto sangat berguna, dan sederhana.
Jerry
6
Jangan khawatir, programmer akan selalu membuat Anda merasa Anda tidak melakukan pengkodean dengan benar dan ingin kami membuat kode seperti mereka. Ini bahkan lebih benar di komunitas php karena kami adalah sekelompok pembuat kode hipster dan PHP memberi kami kata kunci kebebasan ini dan kebebasan untuk menghakimi tentang bagaimana semua orang melakukan sesuatu. Saya telah menggunakan (tidak secara luas) gotokata kunci dalam kode produksi dan saya tidak pernah mengalami kesulitan.
vdegenne
7

Ada perintah: goto

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


}



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

Namun, ingat gotobukan praktik yang disarankan, karena membuat kode harus diformat secara tidak biasa.

T.Todua
sumber
1
Saya telah menguji skrip ini, kode di bawah ini kebagian Area1; tidak akan dieksekusi.
Leon Armstrong
6

Anda bisa menggunakan do-while (false):

    <?php
    do if ($foo)
    {
      // Do something first...

      // Shall we continue with this block, or exit now?
      if ($abort_if_block) break;

      // Continue doing something...

    } while (false);
    ?>

seperti yang dijelaskan dalam http://php.net/manual/en/control-structures.if.php#90073

UltraDEVV
sumber
5

Tidak, tidak ada cara untuk "memecahkan" blok if seperti yang Anda lakukan di dalam loop. :(
Jadi ubah tes Anda menjadi switch!

Saya bertanya-tanya mengapa tidak ada yang mendorong Anda untuk menggunakan pernyataan beralih sejak (bahkan jika Anda belum banyak menguji kasus)
Apakah Anda pikir itu terlalu bertele-tele?

Saya pasti akan melakukannya di sini

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

Bagi saya Pengecualian dimaksudkan untuk meningkatkan kesalahan dan tidak benar-benar untuk mengontrol cacat eksekusi.
Jika perilaku break yang Anda coba setel bukan tentang kesalahan yang tidak terduga, penanganan pengecualian bukan solusi yang tepat di sini :/.

Stphane
sumber
Ide yang menarik tetapi saya tidak akan menggunakannya untuk kode "nyata".
Jimmy T.
1
"asli", apa maksudmu? :/
Stphane
1
@Stphane Sebuah komentar terlambat, tetapi menggunakan saklar dalam situasi ini bertentangan dengan prinsip paling tidak heran. Pernyataan switch diharapkan untuk mengontrol pemilihan data, bukan untuk mengontrol aliran program.
FWDekker
« Sakelar membandingkan ekspresi terhadap nilai differents dan menjalankan blok kode tertentu bergantung pada nilai ekspresi yang sama dengan.» Kemudian setiap blok dapat mengevaluasi ekspresi anak perusahaan yang pada gilirannya dapat menginstruksikan aliran eksekusi untuk mengembalikan atau melewati beberapa instruksi ... Saya tidak berpikir saklar akan bertentangan dengan prinsip paling tidak mengherankan dalam penggunaan kata kunci yang sangat sempit ini, tetapi, ini mengatakan, konteks asli dan persyaratan mungkin memang memerlukan beberapa refactoring.
Stphane
4
$a = 1;

switch($a) {

  case "1":

    if  ($condition1){
      break;
    }

    if  ($condition2){
      break;
    }

    if  ($condition3){
      break;
    }
}

Dengan cara ini saya mendapatkan apa yang saya inginkan. Saya menggunakan switch hanya memiliki case yang pasti dan kemudian menggunakan break in case untuk memilih kondisi jika. Alasan mengapa saya menggunakan break: condition1 dan condition2 keduanya dapat memuaskan, dalam situasi itu hanya condition1 diterapkan. JIKA selektif sesuai urutan.

pengguna3530437
sumber
8
Anda tidak perlu variabel untuk ini. Cukup gunakanswitch(true) { case true:
Maxim Krizhanovsky
1

Tidak.

Tapi bagaimana dengan:

$a="test";
if("test"==$a)
{
  if ($someOtherCondition)
  {
    echo "yes";
  }
}
echo "finish";
Oliver Charlesworth
sumber
3
Terima kasih, tetapi saya mencari versi yang lebih sederhana untuk menghindari terlalu banyak ifpernyataan
Muhammad Usman
2
@ Usman: Jika Anda memiliki beberapa kondisi, maka Anda perlu memeriksanya. Memeriksa suatu kondisi secara tradisional melibatkan suatu ifpernyataan. Saya tidak yakin bagaimana Anda berharap untuk menghindari ini.
Oliver Charlesworth
1

Pindahkan kode yang tidak seharusnya dieksekusi ke else/elseifcabang. Saya tidak benar-benar mengerti mengapa Anda ingin melakukan apa yang Anda coba lakukan.

Mchl
sumber
1

Jawaban sederhananya adalah tidak, tidak ada cara untuk melepaskan diri dari suatu ifpernyataan tanpa sepenuhnya menghentikan eksekusi (via exit). Solusi lain tidak akan berfungsi untuk saya karena saya tidak dapat mengubah struktur ifpernyataan, karena saya menyuntikkan kode ke plugin, seperti:

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
David
sumber
0

Menjawab pertanyaan Anda apakah itu dapat dicapai atau tidak, maka ya itu dapat dicapai dengan menggunakan operator "goto" dari php.

Tapi secara etis, itu bukan praktik yang baik untuk menggunakan "goto" dan jika ada kebutuhan untuk menggunakan goto maka ini berarti bahwa kode perlu direkonstruksi sedemikian rupa sehingga persyaratan goto dapat dihapus.

Menurut kode sampel yang Anda posting di atas, dapat dilihat dengan jelas bahwa kode tersebut dapat direkonstruksi dan kode yang tidak diperlukan lagi dapat dihapus atau dikomentari (jika ada kemungkinan untuk digunakan di masa mendatang).

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

menggabungkan pernyataan Anda, saya pikir ini akan memberi Anda hasil yang Anda inginkan. bersih dan sederhana, tanpa terlalu banyak pernyataan.

untuk kode jelek dan tampan, rekomendasi saya adalah:

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

suatu tempat di kode normal Anda

myfunction();
Arthur Kielbasa
sumber
0

Saya pikir Anda mencari ini:

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

    // go ahead , all is fine
}

Manual php menunjukkan forcontoh, tetapi saya pikir ini juga berfungsi untukif

Joeri
sumber
-1

saya punya solusi sederhana tanpa banyak perubahan. pernyataan awal adalah

Saya ingin memecahkan pernyataan if di atas dan berhenti mengeksekusi gema "ya"; atau kode-kode semacam itu yang tidak perlu lagi dieksekusi, mungkin ada atau tidak ada syarat tambahan, apakah ada cara untuk melakukan ini?

jadi, sepertinya sederhana. coba kode seperti ini.

$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";

jika Anda ingin mencoba tanpa kode ini, sederhana saja. dan Anda dapat kembali kapan saja. solusi lain adalah blok komentar. atau hanya berpikir dan mencoba kode lain yang terpisah dan salin tempel hanya hasil dalam kode akhir Anda. dan jika kode tidak lagi diperlukan, dalam kasus Anda, hasilnya bisa

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

dengan kode ini, pernyataan asli benar-benar dihormati .. :) dan lebih mudah dibaca!

christian audebert
sumber
-2

Solusi sederhana adalah berkomentar.

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

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

Manfaat tambahannya adalah Anda tidak mengubah kode asli dan Anda dapat menentukan tanggal, menginisialisasinya dan memberikan alasan mengapa.

Mengapa suara turun, menurut permintaan OP saya pikir ini adalah solusi yang sangat valid.

"Saya ingin [memecah pernyataan if di atas dan] berhenti mengeksekusi gema" ya "; atau kode seperti itu yang tidak perlu lagi dieksekusi, mungkin ada atau mungkin tidak ada syarat tambahan, apakah ada cara untuk melakukan ini?"

Bahkan seseorang dapat melihat beberapa solusi lain, setahun kemudian dan bertanya-tanya apa yang sedang terjadi di sana. Sesuai saran saya, orang dapat meninggalkan dokumentasi yang baik untuk referensi di masa depan, yang selalu merupakan praktik yang baik.

ArtisticPhoenix
sumber
2
Ini tidak menyelesaikan masalah. Istirahat juga bisa menjadi jika.
Jimmy T.
Anda tidak bisa berkomentar di pernyataan if? Atau komentar satu? Apakah maksud Anda menggunakan jika untuk mengecualikan eksekusi? Kalau begitu, apa gunanya istirahat itu, bukankah itu artinya jika pernyataan itu untuk? Beri komentar juga. Maaf, tetapi tidak mengerti maksud Anda.
ArtisticPhoenix
Sesuatu seperti ini: a: if ("test" == $ a) {... if (...) break a; ...}
Jimmy T.
-3

Bagaimana dengan menggunakan operator ternary?

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

Yang identik dengan pernyataan if / else ini:

<?php
 if (empty($_POST['action'])) {
   $action = 'default';
 } else {
   $action = $_POST['action'];
 }
?>
Martin Stone
sumber
Dalam PHP7:$a = $_POST['action'] ?? 'default';
Tobias Mühl
-3

Untuk sepenuhnya menghentikan sisa skrip agar tidak berjalan, Anda cukup melakukannya

keluar; // Di tempat istirahat. Sisa kode tidak akan dieksekusi

tandai kasina
sumber
-4

Saya terlambat ke pesta tetapi saya ingin berkontribusi. Saya terkejut bahwa tidak ada yang menyarankan exit(). Itu bagus untuk pengujian. Saya menggunakannya sepanjang waktu dan bekerja seperti pesona.

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

Kode akan berhenti exit()dan semuanya tidak akan berjalan.

Hasil

Clark Kent is Superman

Ini bekerja dengan foreach()dan while()juga. Ini bekerja di mana pun Anda menempatkannya.

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

echo "finish";

Hasil

nothing gets printed here.

Gunakan dengan a forloop()

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

Hasil

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

Dalam skenario kasus normal

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

Hasil

Make hot chocolate great again!
Pertarungan balon
sumber
-7
$a="test";
if("test"!=$a)
{
echo "yes";                   
}
 else
 {
  echo "finish";
}
Shanon
sumber