PHP'de if ifadesini kırmanın herhangi bir yolu var mı?


129

Mevcut veya ebeveyn yürütme durdurmak için PHP herhangi bir komut var mı ifaynı ifadeyi, breakya break(1)için switch/ ' loop. Örneğin

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

echo "finish";

yukarıdaki kodda PHP yapmayacak echo "test";ve gidecekecho "finish";

Buna ihtiyacım var eğer

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

Ben istiyorum yukarıdaki deyimi ve durdurmak yürütme veya artık yürütülecek gerekli olan bu tür kodları, olabilir veya ek koşul olmayabilir, bunun için orada bir yoldur?breakifecho "yes";

Güncelleme: Bu soruyu gönderdikten sadece 2 yıl sonra büyüdüm, küçük parçalara kodun nasıl yazılabileceğini, niçin iç içe geçmişse kod kokusu olabileceğini ve bu tür sorunların nasıl önlenebileceğini ilk etapta yönetilebilir, küçük işlevler yazarak öğrendim.


15
Örneklerinizden hiçbiri mantıklı bir anlam ifade etmiyor.
Tim Pietzcker

1
@Usman: Bir koşul yoksa, o zaman echo(sizin örneğinizde) asla yürütülmez. Yani onu silebilirsin.
Oliver Charlesworth

2
try catchBir seçenek değil mi?
giannis christofakis

Önce Tim'in kaba olduğunu düşündüm ... Ama sonra haklı olduğunu düşündüm ... Neden koşulsuz bir molanın arkasında herhangi bir kodunuz olsun ki? Hata ayıklama? Continue ile döngülerin dışına çıkmayı seviyorum; Ve çok zor sorguları "sadece burada dur" komutuyla ayırmak güzel olurdu ...if (condition) { if ( oneothercondition ) stop; if ( yetothercondition ) stop; // go ahead , all is fine }
Joeri

@Joeri, Muhhamad'ın neden molaya ihtiyacı olduğunu bilmiyorum; Ama benim durumumda şimdi hata ayıklama amaçlı, doğru. Bazı durumlarda zaman kazandırır. Kesme noktalarının eklenemediği durumlarda (IDE kullanılmadığında ve / veya bazı nedenlerle canlı bir sitede çalışmak zorunda
kaldığınızda

Yanıtlar:


216

Diğer kullanıcıların yorumları hakkında endişelenmeyin, sizi anlayabiliyorum, BAZEN geliştirirken bu "süslü" şeyler gereklidir . Bir if'i kırabilirsek, çok sayıda iç içe ifs gerekli olmayacak ve kodu çok daha temiz ve estetik hale getirecektir.

Bu örnek kod göstermek çirkin iç içe IFS çok çok daha uygun olabilir eğer ... breaked o Certains DURUMLARLA belirli durum da mevcut değil anlamına gelmez karşılaştığı değil eğer .

Çirkin kod

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

}

Güzel görünen kod

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'ın dediği gibi, kullanımı gotobir alternatiftir, bununla ilgili kötü olan şey, her zaman etiketi (nokta hedefi) tanımlamanız gerekmesidir.


29
Harika! Bazen sorular derin anlamlarından dolayı yanlış anlaşılır. Kusursuz anladınız, sonunu izlemekten kaçınmak için temiz koda ihtiyacım varif
Muhammed Usman

4
Her başarılı testten sonra (yaklaşık 3 veya 4 test) aynı kodu çalıştırmam ve elseifbaşarısız olan her teste bir tane koymam gerekiyordu . Tam olarak aradığım şey buydu, şimdi kodum KISS ve DRY uyumlu :) Teşekkürler!
s3v3n

3
Adamım bu pis hissettiriyor! Ama oyumu alıyor .. Kirli bir sistem üzerinde çalışıyorum;)
LeonardChallis

8
@rdlowrey, konuşma ücretsizdir, bu yüzden LÜTFEN bize OP sorusunu çözmek için bir "İyi yazılmış OOP" örneği gösterin: 3
YaşlanmayanEssence

7
Numunenin talebini kişisel saldırılarla karıştırmayın ... aslında, önemli bir şeyi kaçırıyorsunuz, tüm kodlamalar OOP olmamalı, OOP'nin büyüsü * ile basit görevler yazmak çılgınca bir şey.
YaşlanmayanEssence

98

Kodunuzu bir işlevin içine alın. İle bir işlevi çalıştırmayı returnistediğiniz zaman durdurabilirsiniz .


2
Bir işlev değil, bir eğer istediğini sanıyordum? ;)
Arnaud Le Blanc

3
@ arnaud576875 eğer kod bir işlev içindeyse, if deyiminde dönüşü kullanarak yürütmeyi kesebilirsiniz.
Maxim Krizhanovsky

1
Bir işlev "1 giriş yolu" ve "1 çıkış yolu" olmalıdır. Birden çok İADE özensiz ve hataya meyillidir.
Old Man Walter

@OldManWalter Bu yalnızca gerçek verileri döndürmek için doğrudur. Ancak hata işleme, bu kuralın genel bir istisnasıdır. Birden fazla konumda bir istisna atma veya yanlış dönüş, "1 giriş, 1 çıkış" zihniyetinin korumaya çalıştığı ortak tuzaklara çarpmadan tamamen kabul edilebilir.
danielson317

41

bunu yapmanın uygun yolu:

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

Bazı yorumları okuduktan sonra, istisna işlemenin normal akış kontrolü için her zaman mantıklı olmadığını fark ettim. Normal kontrol akışı için "Aksi takdirde" kullanmak daha iyidir:

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

Ayrıca işlem dönüş değerlerini değişkenlere kaydedebilir ve ardından işlemin başarısız olduğu hata / istisna bloklarını kontrol edebilirsiniz.


1
Bu durumlarda istisnalar yararlı olabilir, ancak bunları kötüye kullandığınız görülüyor. İstisnalar istisnai olup normal program akışı için değildir. Başarısızlık istisnai ise, process_x-z istisnayı kendi kendine atmalıdır; clean_all_processes (), yine de yapılması gereken temiz olduğundan, bir nihayet bloğunda daha iyi olurdu.
Jimmy T.

Çözümü geliştirdim.
Rahul Ranjan

Sonunda kullanmamamın nedeni php5.5'e kadar desteklenmiyor
Rahul Ranjan

20

Eğer Çünkü kırmak bir do dışarı / döngü sırasında, bize "let yapmak için bir aşamadan". Sonunda bir süre (yanlış) ile, durum asla doğru değildir ve bir daha tekrarlamayacaktır.

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

Kimse onu kullanman gerektiğini söylemiyor. Bu sadece "kaçmak" için bir örnek.
Markus Zeller

2
Düzenli yaklaşım - işi yapar.
benjaminhull

16

git :

Goto operatör programı içinde başka bir geçiş yapmak için kullanılabilir. Hedef nokta bir etiket ve ardından iki nokta üst üste işareti ile belirtilir ve talimat goto ve ardından istenen hedef etiket olarak verilir. Bu tamamen sınırsız bir gidiş değildir . Hedef etiket aynı dosya ve bağlam içinde olmalıdır, yani bir işlev veya yöntemden atlayamazsınız veya birine atlayamazsınız. Ayrıca herhangi bir döngü türüne veya anahtar yapısına atlayamazsınız. Bunlardan atlayabilirsiniz ve ortak kullanım, çok seviyeli bir mola yerine bir goto kullanmaktır ...


82
gotoBebek İsa her kullandığınızda bir kedi yavrusu yer. Ayrıca, xkcd.com/292

12
Tutarlı olduğum için üzgünüm. Bahsedilen anahtar kelimenin tam olarak kullanımını açıklayan php kılavuz sayfasına başvurdum. Ve kirli çözüm olsa bile yine de doğru çözümdür.
NiematojakTomasz

3
Bunu yapmanın nasıl iyi bir uygulama olmadığını tam olarak anlamıyorum? Diğer tüm çözümlerden çok daha basit mi?
538ROMEO

1
Sébastien ile anlaştı. Bazı durumlarda, goto operatörü çok kullanışlı ve basittir.
Jerry

6
Endişelenmeyin, programcılar size her zaman doğru kodlamadığınızı hissettirecek ve onlar gibi kodlamamızı isteyecektir. Bu php topluluğunda daha da doğrudur çünkü biz bir grup yenilikçi kodlayıcıyız ve PHP bize bu özgürlük anahtar kelimelerini ve herkesin işleri nasıl yaptığı konusunda böylesine yargılayıcı olma özgürlüğünü verir. gotoAnahtar kelimeyi (kapsamlı değil) üretim kodlarında kullandım ve hiç sorun yaşamadım.
vdegenne

7

Komut var: goto

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


}



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

Ancak, gotokodun alışılmadık şekilde biçimlendirilmesine neden olduğu için önerilen bir uygulama olmadığını unutmayın .


1
Bu betiği test ettim, aşağıdaki kod Area1'e gidin; idam edilmeyecek.
Leon Armstrong


5

Hayır, bir if bloğunu döngülerin içinde yaptığınız gibi "kırmanın" bir yolu yoktur. :(
Bu yüzden testinizi bir switch!

O zamandan beri kimse sizi neden switch deyimini kullanmaya teşvik etmediğini merak ediyorum (pek çok test vakasına katılmamış olsanız bile)
Sence çok ayrıntılı mı?

Kesinlikle burada giderdim

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

Bana göre İstisnalar, hataları arttırmak içindir ve gerçek anlamda yürütme kusurunu kontrol etmek değildir.
Ayarlamaya çalıştığınız kırılma davranışı beklenmedik hatalarla ilgili değilse, burada özel durum işleme doğru çözüm değildir :/.


İlginç fikir ama bunu "gerçek" kod için kullanmazdım.
Jimmy T.

1
"gerçek", ne demek istiyorsun? :/
Stphane

1
@Stphane Geç bir yorum, ancak bu durumda bir anahtar kullanmak en az şaşkınlık ilkesine aykırıdır. Bir anahtar deyiminin, program akışını kontrol etmek için değil, veri seçimini kontrol etmesi beklenir.
FWDekker

« Anahtar , bir ifadeyi farklı değerlerle karşılaştırır ve ifadenin hangi değere eşit olduğuna bağlı olarak belirli bir kod bloğu yürütür." Daha sonra her blok, yürütme akışına bazı talimatları geri döndürme veya atlama talimatı verebilecek yardımcı ifadeleri değerlendirebilir ... Bu çok daraltılmış kullanım durumunda anahtarın en az şaşkınlık ilkesine aykırı olacağını düşünmüyorum, ancak bu, orijinal bağlam ve gereksinimler gerçekten de bazı yeniden düzenleme gerektirebilir.
Stphane

4
$a = 1;

switch($a) {

  case "1":

    if  ($condition1){
      break;
    }

    if  ($condition2){
      break;
    }

    if  ($condition3){
      break;
    }
}

Bu şekilde istediğimi elde ettim. Bir anahtarın yalnızca belirli bir durumu var ve ardından koşulunu seçmek için break kullanıyorum. Break'i kullanmamın nedeni: koşul1 ve koşul2'nin her ikisi de tatmin edebilir, bu durumda yalnızca koşul1 uygulanır. IF, sıraya göre seçicidir.


8
Bunun için değişkene ihtiyacınız yok. Sadece kullanswitch(true) { case true:
Maxim Krizhanovsky 01

1

Hayır.

Peki ya:

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

3
Teşekkürler, ama çok fazla ififadeden kaçınmak için bunun daha basit bir versiyonunu arıyorum
Muhammed Usman

2
@Usman: Birden fazla koşulunuz varsa, onları kontrol etmeniz gerekir. Bir koşulu kontrol etmek geleneksel olarak bir ififade içerir . Bundan nasıl kaçınmayı umduğundan emin değilim.
Oliver Charlesworth

1

Yürütülmemesi gereken kodu else/elseifdallara taşıyın . Yapmaya çalıştığın şeyi neden yapmak isteyesin gerçekten anlamıyorum.


1

Basit cevap, hayır, ifyürütmeyi tamamen durdurmadan bir ifadeden kopmanın bir yolu olmadığıdır exit. ifBir eklentiye kod enjekte ettiğim için ifadenin yapısını değiştiremediğim için diğer çözümler benim için işe yaramayacak :

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

Bunun ulaşılabilir olup olmadığı sorunuzu yanıtlayarak, o zaman evet bu php'nin "goto" operatörü kullanılarak elde edilebilir.

Ancak etik olarak, "goto" yu kullanmak iyi bir uygulama değildir ve goto kullanımına ihtiyaç duyulduğunda bu, kodun goto gereksiniminin ortadan kaldırılabileceği şekilde yeniden yapılandırılması gerektiği anlamına gelir.

Yukarıda gönderdiğiniz örnek koda göre, kodun yeniden yapılandırılabileceği ve artık gerekli olmayan kodun silinebileceği veya yorumlanabileceği (gelecekte kullanım olasılığı varsa) açıkça görülebilir.


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

İfadelerinizi birleştirerek, bence bu size dilediğiniz sonucu verecektir. çok fazla ifade olmadan temiz ve basit.

çirkin ve güzel görünen kod için tavsiyem şöyle olacaktır:

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

normal kodunuzda bir yerde

myfunction();

0

Sanırım bunu arıyorsun:

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

    // go ahead , all is fine
}

Php kılavuzu forörnekler gösterir , ancak bunun için de işe yaradığını düşünüyorumif


-1

Çok fazla değişiklik yapmadan basit bir çözümüm var. ilk ifade

Yukarıdaki if ifadesini kırmak ve echo "yes" i yürütmeyi durdurmak istiyorum; veya artık yürütülmesi gerekmeyen bu tür kodlar, ek bir koşul olabilir veya olmayabilir, bunu yapmanın bir yolu var mı?

bu yüzden basit görünüyor. bunun gibi bir kod deneyin.

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

bu kod olmadan denemek istiyorsanız, çok basit. ve istediğin zaman geri dönebilirsin. diğer bir çözüm ise yorum bloklarıdır. veya sadece düşünerek ayrı bir kod deneyin ve yalnızca sonucu son kodunuza yapıştırın. ve eğer bir kod artık gerekli değilse, sizin durumunuzda sonuç

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

bu kod ile orijinal ifadeye tamamen saygı duyulur .. :) ve daha okunaklı!


-2

Basit çözüm, onu yorumlamaktır.

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

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

Eklenen fayda, orijinal kodunuzu değiştirmemenizdir ve tarih atabilir, paraf atabilir ve nedenini belirtebilirsiniz.

OP'nin talebine göre neden olumsuz oy kullanılıyor? Bunun mükemmel bir çözüm olduğunu düşünüyorum.

"Yukarıdaki if ifadesini [kırmak ve] yankı" evet "i yürütmeyi durdurmak istiyorum; veya bu tür kodlar artık çalıştırılması gerekmeyen, ek bir koşul olabilir veya olmayabilir, bunu yapmanın bir yolu var mı?"

Aslında birisi, bir yıl sonra diğer çözümlerden bazılarına bakabilir ve orada neler olduğunu merak edebilir. Benim önerime göre, ileride başvurmak üzere iyi belgeler bırakılabilir ki bu her zaman iyi bir uygulamadır.


2
Bu sorunu çözmez. Ara, bir eğer de olabilir.
Jimmy T.

Bir if ifadesinde yorum yapamıyor musunuz? Veya bir yorum mu? Yürütmeyi dışlamak için if kullanmak mı istiyorsunuz? Eğer öyleyse, kırılmanın amacı ne, ifadeler ne içindi? Bunu da yorumlayın. Üzgünüm ama ne demek istediğini anlamayın.
ArtisticPhoenix

Bunun gibi bir şey: a: if ("test" == $ a) {... if (...) break a; ...}
Jimmy T.

-3

Üçlü operatör kullanmaya ne dersiniz?

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

Bu if / else ifadesiyle aynı olan:

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

PHP7'de:$a = $_POST['action'] ?? 'default';
Tobias Mühl

-3

Komut dosyasının geri kalanının çalışmasını tamamen durdurmak için şunu yapabilirsiniz:

çıkış; // Mola yerine. Kodun geri kalanı çalışmayacak


-4

Partiye geç kaldım ama katkıda bulunmak istedim. Kimsenin önermemesine şaşırdım exit(). Test etmek için iyidir. Her zaman kullanıyorum ve cazibe gibi çalışıyor.

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

Kod duracak exit()ve sonrasındaki her şey çalışmayacaktır.

Sonuç

Clark Kent is Superman

foreach()Ve while()ile de çalışır . Gerçekten yerleştirdiğiniz her yerde çalışır.

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

echo "finish";

Sonuç

nothing gets printed here.

İle kullanın forloop()

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

Sonuç

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

Normal bir durum senaryosunda

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

Sonuç

Make hot chocolate great again!

-7
$a="test";
if("test"!=$a)
{
echo "yes";                   
}
 else
 {
  echo "finish";
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.