Bất kỳ cách nào để phá vỡ nếu tuyên bố trong PHP?


129

Có lệnh nào trong PHP để dừng thực thi ifcâu lệnh cha hoặc hiện tại , giống như breakhoặc break(1)cho switch/ loop. Ví dụ

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

echo "finish";

trong đoạn mã trên PHP sẽ không làm echo "test";và sẽ đi đếnecho "finish";

Tôi cần cái này nếu

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

Tôi muốn breakcác iftuyên bố trên và dừng thực hiện echo "yes";hoặc mã như vậy mà không còn cần thiết để được thực hiện, có thể có hoặc có thể không phải là một điều kiện bổ sung, là có cách để làm điều này?

Cập nhật: Chỉ 2 năm sau khi đăng câu hỏi này, tôi lớn lên, tôi đã học được cách viết mã thành từng đoạn nhỏ, tại sao lồng nhau nếu có thể là mùi mã và cách tránh những vấn đề như vậy ngay từ đầu bằng cách viết các hàm nhỏ có thể quản lý được.


15
Không có ví dụ nào của bạn làm cho bất kỳ ý nghĩa logic.
Tim Pietzcker

1
@Usman: Nếu không có điều kiện, thì echo(trong ví dụ của bạn) sẽ không bao giờ được thực thi. Vì vậy, bạn cũng có thể xóa nó.
Oliver Charlesworth

2
Không phải là try catchmột lựa chọn?
gianni christofakis

Đầu tiên tôi nghĩ Tim thật thô lỗ ... Nhưng sau đó tôi nghĩ anh ấy đúng ... Tại sao bạn lại có bất kỳ mật mã nào sau một lần nghỉ vô điều kiện? Gỡ lỗi? Tôi thích thoát ra khỏi các vòng lặp với tiếp tục; Và thật tuyệt khi chia tay các truy vấn rất khó bằng lệnh "chỉ dừng ở đây" ...if (condition) { if ( oneothercondition ) stop; if ( yetothercondition ) stop; // go ahead , all is fine }
Joeri

@Joeri tôi không biết những ý tưởng ban đầu của Muhhamad tại sao anh ấy cần nghỉ ngơi; Nhưng trong trường hợp của tôi bây giờ nó là mục đích gỡ lỗi, phải. Trong một số trường hợp, nó sẽ tiết kiệm thời gian. Trong trường hợp khi không thể thêm điểm dừng '(khi không sử dụng IDE và / hoặc phải làm việc trên một trang web trực tiếp vì một số lý do, v.v.)
Viktor Borítás

Câu trả lời:


216

Đừng lo lắng về những bình luận của người dùng khác, tôi có thể hiểu bạn, SOMETIMES khi phát triển những thứ "lạ mắt" này là bắt buộc . Nếu chúng ta có thể phá vỡ một if, rất nhiều if lồng nhau sẽ không cần thiết, làm cho mã sạch hơn và thẩm mỹ hơn nhiều.

Mã mẫu này minh họa rằng CÁC TÌNH HÌNH CERTAIN nơi bị phá vỡ nếu có thể phù hợp hơn nhiều so với các ifs xấu xí lồng nhau ... nếu bạn không phải đối mặt với tình huống nhất định không có nghĩa là nó không tồn tại .

Mã xấu

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

}

Mã đẹp trai

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

Như @NiematojakTomasz nói, việc sử dụng gotolà một thay thế, điều tồi tệ về điều này là bạn luôn cần xác định nhãn (mục tiêu điểm).


29
Tuyệt quá! Đôi khi các câu hỏi bị hiểu lầm do ý nghĩa sâu sắc của họ. Bạn đã nhận được nó một cách hoàn hảo, tôi cần mã sạch để tránh theo dõi kết thúcif
Muhammad Usman

4
Tôi cần thực thi cùng một mã sau mỗi thử nghiệm thành công (khoảng 3 hoặc 4 thử nghiệm) và đặt một elseifthử nghiệm cho mỗi thử nghiệm thất bại. Đây chính xác là những gì tôi đang tìm kiếm, bây giờ mã của tôi là tuân thủ KISS và DRY :) Cảm ơn!
s3v3n

3
Người đàn ông này cảm thấy bẩn! Nhưng nó nhận được sự ủng hộ của tôi .. Tôi đang làm việc trên một hệ thống bẩn;)
LeonardChallis

8
@rdlowrey, nói chuyện là miễn phí, vì vậy, hãy cho chúng tôi xem một ví dụ về "OOP được viết tốt" để giải quyết câu hỏi OP: 3
AglessEssence

7
Đừng nhầm lẫn yêu cầu của mẫu đối với các cuộc tấn công cá nhân ... thực tế, bạn đang thiếu một thứ quan trọng, không phải tất cả mã hóa phải là OOP, là một điều điên rồ khi viết các tác vụ đơn giản với phép thuật * của OOP.
AglessEssence

98

Đóng gói mã của bạn trong một hàm. Bạn có thể ngừng thực thi một chức năng returnbất cứ lúc nào.


2
Tôi mặc dù bạn muốn một nếu, không phải là một chức năng? ;)
Arnaud Le Blanc

3
@ arnaud576875 nếu mã nằm trong hàm, hơn bạn có thể sử dụng return trong câu lệnh if, để phá vỡ sự thực thi.
Maxim Krizhanovsky

1
Một chức năng nên có "1 cách vào" và "1 lối ra". Nhiều RETURNS là cẩu thả và dễ bị lỗi.
Ông già Walter

@OldManWalter Điều đó chỉ đúng khi trả về dữ liệu thực tế. Tuy nhiên, xử lý lỗi là một ngoại lệ phổ biến cho quy tắc này. Một ngoại lệ ném hoặc trả lại sai ở nhiều vị trí là hoàn toàn có thể chấp nhận được mà không gặp phải những cạm bẫy phổ biến mà tâm lý "1 cách vào, 1 lối ra" đang cố gắng bảo vệ chống lại.
danielson317

41

cách thích hợp để làm điều này:

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

Sau khi đọc một số ý kiến, tôi nhận ra rằng việc xử lý ngoại lệ không phải lúc nào cũng có ý nghĩa đối với việc kiểm soát luồng bình thường. Đối với luồng điều khiển bình thường, tốt hơn là sử dụng "Nếu khác":

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

Bạn cũng có thể lưu các giá trị trả về của quá trình trong các biến và sau đó kiểm tra các khối thất bại / ngoại lệ mà quá trình đã thất bại.


1
Trường hợp ngoại lệ có thể hữu ích trong trường hợp này nhưng có vẻ như bạn sử dụng sai chúng. Các ngoại lệ là ngoại lệ, không dành cho luồng chương trình bình thường. Nếu thất bại là ngoại lệ thì process_x-z sẽ tự ném ngoại lệ; Clean_all_ Processes () sẽ tốt hơn trong một khối cuối cùng vì nó được dọn sạch mà phải được thực hiện bằng mọi cách.
Jimmy T.

Tôi đã cải thiện giải pháp.
Rahul Ranjan

Lý do cuối cùng tôi không sử dụng là vì nó không được hỗ trợ cho đến php5.5
Rahul Ranjan

20

Bởi vì bạn có thể thoát ra khỏi vòng lặp do / while, hãy để chúng tôi " làm " một vòng. Với một khoảng thời gian (sai) ở cuối, điều kiện không bao giờ đúng và sẽ không lặp lại.

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

Không ai nói bạn phải sử dụng điều đó. Nó chỉ là một ví dụ để "thoát" ra.
Markus Zeller

2
Cách tiếp cận gọn gàng - thực hiện công việc.
benjaminhull

16

goto :

Các goto điều hành có thể được sử dụng để nhảy đến phần khác trong chương trình. Điểm đích được chỉ định bởi một nhãn theo sau là dấu hai chấm và hướng dẫn được đưa ra dưới dạng goto theo sau là nhãn đích mong muốn. Đây không phải là một goto hoàn toàn không bị hạn chế . Nhãn đích phải nằm trong cùng một tệp và ngữ cảnh, nghĩa là bạn không thể nhảy ra khỏi một hàm hoặc phương thức, cũng như không thể nhảy vào một. Bạn cũng không thể nhảy vào bất kỳ loại cấu trúc vòng lặp hoặc chuyển đổi. Bạn có thể nhảy ra khỏi đây, và một cách sử dụng phổ biến là sử dụng một chiếc goto thay cho sự phá vỡ đa cấp ...


82
Mỗi khi bạn sử dụng goto, Hài nhi Giêsu ăn một con mèo con. Ngoài ra, xkcd.com/292

12
Xin lỗi vì sự nhất quán. Tôi đã tham khảo trang hướng dẫn sử dụng php giải thích việc sử dụng chính xác từ khóa được đề cập. Và ngay cả khi đó là giải pháp bẩn, nó vẫn là giải pháp chính xác.
NiematojakTomasz

3
Tôi không hiểu chính xác làm thế nào nó không thực hành tốt để làm như vậy? Nó đơn giản hơn nhiều so với tất cả các giải pháp khác?
538ROMEO

1
Đồng ý với Sébastien. Trong một số trường hợp, toán tử goto rất hữu ích và đơn giản.
Jerry

6
Đừng lo lắng, các lập trình viên sẽ luôn khiến bạn cảm thấy bạn không viết mã đúng và muốn chúng tôi viết mã như họ. Điều này thậm chí còn đúng hơn trong cộng đồng php vì chúng tôi là một nhóm các lập trình viên hipster và PHP cung cấp cho chúng tôi các từ khóa tự do này và sự tự do để đánh giá về cách mọi người làm mọi việc. Tôi đã sử dụng (không rộng rãi) gototừ khóa trong mã sản xuất và tôi chưa bao giờ gặp rắc rối.
vdegenne

7

Có lệnh tồn tại: goto

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


}



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

Tuy nhiên, hãy nhớ rằng gotokhông phải là một cách thực hành được khuyến nghị, bởi vì nó làm cho mã được định dạng bất thường.


1
Tôi đã thử nghiệm tập lệnh này, mã bên dưới goto Area1; sẽ không được thực thi.
Leon Armstrong


5

Không, không có cách nào để "phá vỡ" một khối if như bạn sẽ ở trong các vòng lặp. :(
Vì vậy, biến bài kiểm tra của bạn thành a switch!

Tôi tự hỏi tại sao không ai khuyến khích bạn sử dụng câu lệnh chuyển đổi kể từ khi (ngay cả khi bạn không có nhiều trường hợp thử nghiệm)
Bạn có nghĩ rằng nó quá dài dòng không?

Tôi chắc chắn sẽ đi cho nó ở đây

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

Đối với tôi Ngoại lệ có nghĩa là để tăng lỗi và không thực sự kiểm soát lỗ hổng thực thi.
Nếu hành vi ngắt mà bạn đang cố gắng đặt không phải là (các) lỗi không mong muốn, xử lý ngoại lệ không phải là giải pháp phù hợp ở đây :/.


Ý tưởng thú vị nhưng tôi sẽ không sử dụng nó cho mã "thực".
Jimmy T.

1
"Thực", ý bạn là gì? :/
Stphane

1
@Stphane Một bình luận muộn, nhưng sử dụng một công tắc trong tình huống này đi ngược lại nguyên tắc ít ngạc nhiên nhất. Một tuyên bố chuyển đổi dự kiến ​​sẽ kiểm soát lựa chọn dữ liệu, không kiểm soát luồng chương trình.
FWDekker

« Switch so sánh một biểu thức với các giá trị khác nhau và thực thi một khối mã cụ thể tùy thuộc vào giá trị mà biểu thức đó bằng.» Sau đó, mỗi khối có thể đánh giá các biểu thức bổ trợ mà lần lượt có thể hướng dẫn luồng thực thi quay lại hoặc bỏ qua một số hướng dẫn. Tôi không nghĩ rằng công tắc sẽ đi ngược lại nguyên tắc ít ngạc nhiên nhất trong usecase rất hẹp này, nhưng, điều này nói, bối cảnh ban đầu và yêu cầu thực sự có thể yêu cầu một số tái cấu trúc.
Stphane

4
$a = 1;

switch($a) {

  case "1":

    if  ($condition1){
      break;
    }

    if  ($condition2){
      break;
    }

    if  ($condition3){
      break;
    }
}

Bằng cách này tôi đã có được những gì tôi muốn. Tôi sử dụng một chuyển đổi chỉ có một trường hợp xác định và sau đó sử dụng break trong trường hợp để chọn nếu điều kiện. Lý do tại sao tôi sử dụng break: condition1 và condition2 đều có thể thỏa mãn, trong tình huống đó chỉ áp dụng điều kiện1 .IF là chọn lọc theo thứ tự.


8
Bạn không cần biến cho điều này. Chỉ cần sử dụngswitch(true) { case true:
Maxim Krizhanovsky

1

Không.

Nhưng làm thế nào về:

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

3
Cảm ơn, nhưng, tôi đang tìm kiếm một phiên bản đơn giản hơn để tránh quá nhiều iftuyên bố
Muhammad Usman

2
@Usman: Nếu bạn có nhiều điều kiện, thì bạn cần kiểm tra chúng. Kiểm tra một điều kiện theo truyền thống liên quan đến một iftuyên bố. Tôi không chắc chắn làm thế nào bạn mong đợi để tránh điều này.
Oliver Charlesworth

1

Chỉ cần di chuyển mã không được phép thực hiện sang else/elseifnhánh. Tôi thực sự không thấy lý do tại sao bạn muốn làm những gì bạn đang cố gắng làm.


1

Câu trả lời đơn giản là không, không có cách nào để thoát khỏi một ifcâu lệnh mà không dừng hoàn toàn việc thực thi (thông qua exit). Các giải pháp khác sẽ không hiệu quả với tôi vì tôi không thể thay đổi cấu trúc của ifcâu lệnh, vì tôi đang tiêm mã vào một plugin, như vậy:

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

Trả lời câu hỏi của bạn cho dù điều đó có thể đạt được hay không, thì có, có thể đạt được bằng cách sử dụng toán tử "goto" của php.

Nhưng về mặt đạo đức, việc sử dụng "goto" không phải là một cách thực hành tốt và không có nhu cầu sử dụng goto thì điều này có nghĩa là mã cần phải được xây dựng lại để yêu cầu của goto có thể được gỡ bỏ.

Theo mã mẫu bạn đã đăng ở trên, có thể thấy rõ rằng mã có thể được xây dựng lại và mã không cần thiết nữa có thể bị xóa hoặc nhận xét (nếu có thể sử dụng trong tương lai).


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

kết hợp các tuyên bố của bạn, tôi nghĩ rằng điều này sẽ cung cấp cho bạn kết quả mong muốn của bạn. sạch sẽ và đơn giản, không có quá nhiều tuyên bố.

đối với mã xấu xí và ưa nhìn, sự phục hồi của tôi sẽ là:

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

một nơi nào đó trong mã thông thường của bạn

myfunction();

0

Tôi nghĩ rằng bạn đang tìm kiếm điều này:

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

    // go ahead , all is fine
}

Hướng dẫn sử dụng php hiển thị các forví dụ, nhưng tôi nghĩ nó cũng hoạt động choif


-1

tôi có một giải pháp đơn giản mà không có nhiều thay đổi. tuyên bố ban đầu là

Tôi muốn phá vỡ câu lệnh if ở trên và ngừng thực hiện echo "yes"; hoặc các mã không còn cần thiết để được thực thi, có thể có hoặc không có một điều kiện bổ sung, có cách nào để làm điều này không?

vì vậy, nó có vẻ đơn giản. thử mã như thế này.

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

nếu bạn muốn thử mà không có mã này, thật đơn giản. và bạn có thể quay lại khi bạn muốn. một giải pháp khác là khối bình luận. hoặc chỉ đơn giản là suy nghĩ và thử trong một mã riêng biệt khác và sao chép chỉ dán kết quả trong mã cuối cùng của bạn. và nếu một mã không còn cần thiết nữa, trong trường hợp của bạn, kết quả có thể là

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

với mã này, tuyên bố ban đầu hoàn toàn được tôn trọng .. :) và dễ đọc hơn!


-2

Giải pháp đơn giản là bình luận nó ra.

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

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

Lợi ích bổ sung là việc bạn không thay đổi mã gốc và bạn có thể hẹn hò với nó, khởi tạo nó và đưa ra lý do tại sao.

Tại sao bỏ phiếu xuống, theo yêu cầu của OP Tôi nghĩ rằng đây là một giải pháp hoàn toàn hợp lệ.

"Tôi muốn [ngắt câu lệnh if ở trên và] dừng thực thi tiếng vang" có "; hoặc các mã không còn cần thiết để thực thi, có thể có hoặc không có điều kiện bổ sung, có cách nào để làm điều này không?"

Trong thực tế, ai đó có thể nhìn vào một số giải pháp khác, một năm sau đó và tự hỏi điều gì đang xảy ra ở đó. Theo đề nghị của tôi, người ta có thể để lại tài liệu tốt để tham khảo trong tương lai, đây luôn là cách thực hành tốt.


2
Điều này không giải quyết được vấn đề. Sự phá vỡ cũng có thể là trong một nếu.
Jimmy T.

Bạn không thể bình luận trong một tuyên bố if? Hoặc bình luận ra một? Bạn có nghĩa là sử dụng một if để loại trừ thực thi? Nếu vậy thì điểm của sự phá vỡ là gì, đó không phải là điều gì nếu các tuyên bố là để làm gì? Chỉ cần bình luận mà ra. Xin lỗi, nhưng không thấy quan điểm của bạn.
ArtisticPhoenix

Một cái gì đó như thế này: a: if ("test" == $ a) {... if (...) break a; ...}
Jimmy T.

-3

Điều gì về việc sử dụng toán tử ternary?

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

Điều này giống hệt với câu lệnh if / other này:

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

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

-3

Để ngăn chặn hoàn toàn phần còn lại của tập lệnh chạy, bạn chỉ cần làm

lối ra; // Thay chỗ nghỉ. Phần còn lại của mã sẽ không thực thi


-4

Tôi đến bữa tiệc muộn nhưng tôi muốn đóng góp. Tôi ngạc nhiên khi không ai đề nghị exit(). Nó tốt cho thử nghiệm. Tôi sử dụng nó mọi lúc và làm việc như bùa mê.

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

Mã sẽ dừng lại ở exit() và mọi thứ sau đó sẽ không chạy.

Kết quả

Clark Kent is Superman

Nó hoạt động với foreach()while()là tốt. Nó hoạt động bất cứ nơi nào bạn đặt nó thực sự.

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

echo "finish";

Kết quả

nothing gets printed here.

Sử dụng nó với một forloop()

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

Kết quả

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

Trong một trường hợp bình thường

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

Kết quả

Make hot chocolate great again!

-7
$a="test";
if("test"!=$a)
{
echo "yes";                   
}
 else
 {
  echo "finish";
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.