2009-09-17 38 views
40

chúng tôi đang cố gắng để thực hiện chủ trương phong cách mã hóa mới cho đội bóng của chúng tôi, codesniffer php được in cảnh báo trên switch trường hợp báo cáo khi không có "đột phá" được tìm thấy như:Mã hóa kiểu PHP trả về; trong chuyển/trường hợp

switch ($foo) { 
    case 1: 
     return 1; 
    case 2: 
     return 2; 
    default: 
     return 3; 
} 

là có bất kỳ lý do chính đáng để sử dụng:

switch ($foo) { 
     case 1: 
     return 1; 
     break; 
    } 

?? phá vỡ không bao giờ đạt được?

+0

Tôi khuyên bạn nên đặt câu hỏi @category thành một câu hỏi riêng biệt vì câu hỏi này không liên quan. –

+0

Có thể codesniffer chỉ sai và không kiểm tra 'return' nhưng chỉ cho' break'. – Gumbo

Trả lời

65

Đó là hoàn toàn hợp lệ để bỏ qua break khi bạn return từ switch.

Nhưng thực tế là khá phổ biến để thêm rõ ràng break s vào mỗi case làm thực tiễn defensive programming.

switch ($foo) { 
    case 1: 
     return 1; 
     break; 

    case 2: 
     return 2; 
     break; 
} 

Ý tưởng là bạn nên sau đó thay đổi mã của bạn trong case 1 và loại bỏ các câu lệnh return, bạn có thể quên thêm một break.

Điều đó vô tình khiến luồng chương trình rơi qua case 2.

switch ($foo) { 
    case 1: 
     somethingDifferent(); 

    case 2: 
     return 2; 
     break; 
} 

Báo cáo trường hợp thông thường không bình thường và bạn nên thêm nhận xét vào mã khi bạn thực hiện để cho biết rằng đó là ý định.

switch ($foo) { 
    case 1: 
     somethingDifferentAndWeWantToDoCase2AsWell(); 
     // fallthrough 

    case 2: 
     return 2; 
     break; 
} 

Như với nhiều thực hành lập trình phòng thủ, bạn phải cân bằng liệu mã có sưng lên - có khả năng cắt mã của bạn và làm cho mã không đọc được - có đáng hay không.

+0

_ "sau đó bạn nên thay đổi mã của bạn trong trường hợp 1" _ sau đó bạn nên thay đổi tất cả các mã theo yêu cầu và kiểm tra nó. Mã phải dễ đọc, rõ ràng và rõ ràng, để thực hiện các thay đổi trong tương lai đơn giản. Nhưng trong một cái gì đó đơn giản như báo cáo chuyển đổi nó là cách OTT đặt trong điều khoản chống gotcha như thế này. Nó có thể cho là làm cho ý định ít rõ ràng hơn. "Một break ?? nhưng có một trở lại ??" _ "sau đó bạn nên thay đổi mã của bạn trong trường hợp 1 và loại bỏ các báo cáo trở lại, bạn có thể quên thêm một break" _ sau đó bạn có lẽ nên có một break dài từ devving, bởi vì bạn sau đó có một trường hợp không có gì trong đó ... – James

-11

Từ hướng dẫn PHP (http://us3.php.net/manual/en/control-structures.switch.php):

PHP tiếp tục thực hiện những điều khoản cho đến khi kết thúc của khối chuyển đổi, hoặc lần đầu tiên nó thấy một câu lệnh break. Nếu bạn không viết một câu lệnh break ở cuối danh sách câu lệnh của trường hợp, PHP sẽ tiếp tục thực hiện các câu lệnh của trường hợp sau đây. Ví dụ:

<?php 
switch ($i) { 
    case 0: 
     echo "i equals 0"; 
    case 1: 
     echo "i equals 1"; 
    case 2: 
     echo "i equals 2"; 
} 
?> 

Ở đây, nếu $ i bằng 0, PHP sẽ thực hiện tất cả các câu lệnh echo! Nếu $ i bằng 1, PHP sẽ thực hiện hai câu lệnh echo cuối cùng. Bạn sẽ nhận được hành vi mong đợi ('i bằng 2' sẽ được hiển thị) chỉ khi $ i bằng 2. Vì vậy, điều quan trọng là không quên các câu lệnh ngắt (mặc dù bạn có thể muốn tránh cung cấp chúng theo mục đích trong một số trường hợp nhất định).

+3

Nhưng anh ấy đang nói về việc trở về từ một công tắc, bạn không trả lời câu hỏi của mình –

+0

Không liên quan trong trường hợp này. Khối 'case' được thoát bởi' return'. – Gumbo

+2

Bạn nói đúng - tôi không đọc câu hỏi đúng cách. xin lỗi cho rằng – Sander

-1

Tôi không phải là một chuyên gia trong mã hóa hoàn hảo nhưng tôi nghĩ rằng các validator muốn một cái gì đó như thế

switch ($foo) { 
    case 1: 
     $ret = 1; 
     break; 
    case 2: 
     $ret = 2; 
     break; 
    default: 
     $ret = 3 

} 
return $ret 

Tôi nghĩ rằng sử dụng trở lại trong trường hợp tuyên bố phá vỡ dòng chảy của mã này là không thực sự là một thực hành tốt nhất. Vì vậy, đó là lý do tại sao các validator nói rằng không có đột phá ...

Đối với câu hỏi của bạn về ở thể loại, tôi không biết ... xin lỗi

+0

... có lẽ không phải là sở thích của @ therefromhere bởi vì tiêu thụ "không yêu cầu" thuộc tính ... Nhưng là một lựa chọn tốt khi '$ ret' đã tồn tại (là bắt buộc) để làm điều gì đó trong thuật toán. –

3

Tôi có giải pháp tốt hơn nhiều.Vui lòng làm theo mã bên dưới để biết thống kê chuyển đổi ở trên:

$result = 3; // for default case 
switch ($foo) { 
    case 1: 
     $result = 1; 
     break; 
    case 2: 
     $result = 2; 
     break;  
    default: 
     // do nothing 
} 
return $result; 

Nó sẽ không dẫn đến bất kỳ lỗi và mã nào cũng tốt với khái niệm.

1

Nếu "php codesniffer của bạn đang in cảnh báo", hãy thử lấy một bộ mã hóa mã hóa tốt hơn và đừng quên sử dụng phiên bản PHP ổn định cuối cùng. Bạn có thể, tất nhiên, viết một break sau một return, nhưng nó không có ý nghĩa, bởi vì nó sẽ không bao giờ được đọc cả. Mã của bạn là OK.

Nhìn này:

$fn = function($ar) { 
    switch ($ar) { 
     case 1: 
      return "uno"; 
     case 2: 
      return "two"; 
     default: 
      return "mehr als zwei"; 
    } 
}; 
$str = $fn(4); // return "mehr als zwei" 

Theo tôi đây là đơn giản hơn và tốt hơn: chưa lines => ít mã để duy trì :-)

0

Để trả lời câu hỏi của bạn, không có không có lý do chính đáng để có cái gì đó không làm gì cả. Hãy suy nghĩ về nó theo cách này, một bình luận sau khi return thay vì một break nói "đừng quên" sẽ có tác động tương tự - không. Và đặt theo cách đó nghe có vẻ ngớ ngẩn, đúng không?

Trừ khi bạn cần đặt biến số để sử dụng sau, tôi khuyên bạn nên có cách tiếp cận hoàn toàn phù hợp. Tôi biết ý định của mã trong vòng 2 giây khi nhìn vào nó. Có một break chỉ tạo ra sự nhầm lẫn.

Không có kích thước nào phù hợp với tất cả. Cách tiếp cận chính xác phụ thuộc vào việc nào phù hợp với kịch bản. Đặt biến trong mỗi case và có một số break có thể là đúng cách hoặc có lẽ chỉ cần trả về là hợp lý.

 
 


Một số quan sát về các đề xuất khác thực hiện trong câu trả lời:

1)Không có một break sau return nghĩa vấn đề có thể phát sinh nếu mã được sau đó đổi

Wh nếu có thể, mã phải rõ ràng, cũng như dễ đọc và rõ ràng. Chúng tôi cũng có thể viết mã theo cách để thực hiện các thay đổi trong tương lai dễ dàng hơn. Nhưng trong một cái gì đó đơn giản như là một switch nó sẽ không có vấn đề và không cần mạng lưới an toàn để refactor một case sau đó để thêm hoặc loại bỏ một return hoặc break.

Trong thực tế, nếu bạn loại bỏ một return và "không để ý không có break" thì đó là một sai lầm nghèo và có thể được thực hiện trong bất kỳ phần nào của mã hóa. Không có kiểm tra gotcha sẽ giúp bạn tiết kiệm từ đó. Và người ta phải rất cẩn thận viết mã cho các tiềm năng trong tương lai, vì tiềm năng đó có thể không bao giờ xảy ra, hoặc cái gì khác có thể xảy ra, và bạn chỉ cần duy trì mã lỗi thời trong nhiều năm.

Trong cùng một tĩnh mạch, điều này được cho là mạng an toàn cho các thay đổi trong tương lai - Điều gì sẽ xảy ra nếu bạn xóa return và vô tình để lại trong mạng an toàn đó break khi bạn nên xóa nó?

Thậm chí nếu tuyên bố chuyển đổi này là một kịch bản sống hoặc chết, mã thực sự nghiêm trọng, tôi sẽ chống lại việc thêm "vô nghĩa" nghỉ sau khi trở về.Chỉ cần chắc chắn rằng bất cứ ai đang làm việc trên các mã biết những gì họ đã làm, và nó đã được xem xét lại bằng mã mắt đủ và kiểm tra đầy đủ.
Nếu nó nghiêm trọng, thì bạn sẽ có kiểm tra bổ sung tại chỗ tốt hơn so với mạng lưới an toàn được đề xuất để phát hiện các nhà phát triển cẩu thả.

Để tranh luận rằng việc ngắt sau khi trả lại thêm một mạng lưới an toàn, có nghĩa là bạn không mã hóa hoặc kiểm tra đúng cách. Nếu đây là một mạng lưới an toàn được coi là hữu ích thì có khả năng có rất nhiều lỗi trong mã ở những nơi có khả năng nghiêm trọng hơn.

Các bài viết wiki của "Lập trình phòng thủ" được liên kết đến, nhưng nó không liên quan ở đây:

trình phòng thủ là một hình thức thiết kế phòng thủ nhằm đảm bảo chức năng liên tục của một phần mềm dưới không lường trước được hoàn cảnh.

Rời khỏi lưới an toàn break trong trường hợp không phải là trường hợp bất thường, cũng như lập trình phòng thủ. Nó chỉ là mã hóa xấu, và bạn không thể xả rác mã của bạn bằng mã sao lưu chỉ trong trường hợp bạn không mã chính xác khi bạn thay đổi một cái gì đó. Đó là một cách tiếp cận xấu để viết mã. Đối số rằng "nếu ai đó xóa trả lại, nó sẽ không hoạt động", bạn cũng có thể có lỗi đánh máy trong trường hợp var hoặc quên viết trường hợp, hoặc ...

return trả về và bạn không ' Mã "phòng thủ" để tránh thất bại. Điều đó có nghĩa là PHP bị hỏng, và bạn sẽ phải điền mã của bạn với các lưới an toàn để phục vụ cho điều đó. Đó là điều bạn có ở cấp độ cao hơn nhiều.

2)break sau return giữ nó rõ ràng

Nhưng nó một cách rõ ràng sai. Số tiền trả về return, do đó, thời gian nghỉ sẽ không xảy ra. Đối với tôi đó là thời gian đầu trăn tự hỏi nếu tôi đã bỏ lỡ ý định - không lâu vì nó rõ ràng những gì sẽ xảy ra, nhưng sẽ có một thời điểm mà tôi suy nghĩ nó để đảm bảo tôi đã không bỏ lỡ một cái gì đó.

Mặc dù không hợp lệ hoặc có lỗi return và sau đó break trong cùng một case, nó hoàn toàn vô nghĩa khi break không làm gì cả. Đó là mã vô nghĩa mà cần phải được nhìn thấy, duy trì, và tìm ra vì nó không hợp lý.

Nếu rõ ràng là mục tiêu cốt lõi có một break sau một return urks bạn bởi vì nó vô nghĩa, sau đó tôi muốn nói rằng nó muốn được tốt hơn để thiết lập một biến và break, sau đó trở biến sau một pha tạt từ công tắc.
Giống như @RageZ câu trả lời https://stackoverflow.com/a/1437476/2632129

 

3)Đặt một biến và trở lại sau khi báo cáo kết quả chuyển đổi hoàn tất

Không có gì sai với cách tiếp cận này là ở tất cả, nhưng nếu không có lý do để lưu trữ các giá trị trong một biến (sau này sử dụng vv) sau đó nó là tốt để trở lại ngay lập tức khi không có cần phải treo xung quanh để làm bất cứ điều gì khác.

Điều đó thể hiện mục đích rõ ràng - trả lại giá trị ngay sau khi trường hợp được khớp.

Các vấn đề liên quan