Возвращаются стили кодирования PHP; в выключателе / ​​случае - PullRequest
47 голосов
/ 17 сентября 2009

мы пытаемся реализовать новые рекомендации по стилю кодирования для нашей команды, php codesniffer печатает предупреждение на операторах регистра переключателя, когда «break» не найден, например:

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

есть ли веские основания для использования:

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

?? перерыв никогда не достигается?

Ответы [ 6 ]

77 голосов
/ 17 сентября 2009

Вполне допустимо опускать break, когда вы return из switch.

Но довольно распространенной практикой является добавление явных break s к каждому case в качестве защитного программирования практика.

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

    case 2:
        return 2;
        break;
}

Идея состоит в том, что если позже вы измените свой код в case 1 и удалите оператор возврата, вы можете забыть добавить break.

Это может привести к падению потока программы до case 2.

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

    case 2:
        return 2;
        break;
}

Пропускать операторы case немного необычно, и вы должны добавить комментарий к своему коду, когда вы делаете это, чтобы показать, что он преднамеренный.

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

    case 2:
        return 2;
        break;
}

Как и во многих практиках защитного программирования, вы должны балансировать, стоит ли раздувать код - который потенциально загромождает ваш код и делает его менее читабельным - стоит или нет.

4 голосов
/ 21 октября 2015

Если ваш «php codesniffer выводит предупреждение», попробуйте получить другой лучший код и не забудьте попробовать последнюю стабильную версию PHP. Конечно, вы можете написать break после одного return, но это не имеет смысла, потому что оно никогда не будет прочитано вообще. Ваш код в порядке.

Посмотрите на это:

$fun = function(int $argument): string {
    switch ($argument) {
        case 1:
            return "one";
        case 2:
            return "two";
        default:
            return "more than two";
    }
};
$str = $fun(4); // return "more than two"

На мой взгляд, это проще и лучше: меньше строк => меньше кода для поддержки: -)

3 голосов
/ 02 марта 2018

Чтобы ответить на ваш вопрос, нет никакой веской причины иметь что-то, что ничего не делает. Подумайте об этом так: комментарий после return вместо break, говорящий «не забывайте», будет иметь тот же эффект - ни один. И говоря так, это звучит глупо, верно?

Если вам не нужно устанавливать переменную для последующего использования, я бы посоветовал подход, который у вас есть, вполне подойдет. Я знал намерение кода в течение 2 секунд после его просмотра. Наличие break просто создает путаницу.

Нет единого размера, который подходит всем. Правильный подход зависит от того, что соответствует сценарию. Установите переменную в каждом case, и наличие break может быть правильным способом, или, возможно, просто возврат имеет смысл.



Некоторые замечания по другим предложениям, высказанным в ответах:

1) Отсутствие break после return означает, что могут возникнуть проблемы при последующем изменении кода

Когда это возможно, код должен быть явным, а также читаемым и понятным. Мы также можем кодировать таким образом, чтобы облегчить будущие изменения. Но в таких простых вещах, как switch, проблем не должно быть, и не требуется никакой сети безопасности для рефакторинга case позже, чтобы добавить или удалить return или break.

На самом деле, если вы удалили return и " не заметили, что не было break", то это плохая ошибка, и ее можно допустить в любой части кода. Никакая проверка не поможет вам от этого. И нужно очень тщательно кодировать будущие потенциалы, так как этот потенциал может никогда не произойти, или может произойти что-то еще, и вы просто в конечном итоге будете поддерживать устаревший код годами.

В том же духе это считалось защитной сеткой для будущих изменений. Что если вы удалите return и случайно оставите в этой защитной сети break, когда вы должны были удалить его?

Даже если бы этот оператор switch был сценарием жизни или смерти, действительно серьезного кода, я был бы против добавления «бессмысленного» разрыва после возврата. Просто убедитесь, что тот, кто работал над кодом, знал, что делает, и этот код был проверен достаточным количеством глаз и полностью протестирован.
Если бы это было настолько серьезно, то у вас были бы дополнительные проверки лучше, чем предлагаемая сеть безопасности, чтобы поймать неаккуратных разработчиков.

Утверждение, что перерыв после возврата добавляет защитную сеть, означает, что вы не пишете код или тестируете должным образом. Если эта сеть безопасности считается полезной, то, вероятно, в коде есть множество ошибок в потенциально более серьезных местах.

Ссылка на вики-статью "Защитное программирование" была приведена, но здесь она не актуальна:

Защитное программирование - это форма защитного замысла, призванная обеспечить продолжающаяся функция программного обеспечения в непредвиденных случаях обстоятельства.

Выход из системы безопасности break - это не сценарий непредвиденных обстоятельств и не защитное программирование. Это просто плохое кодирование, , и вы не можете засорять свой код резервным кодом на тот случай, если вы неправильно закодируете, когда что-то измените . Это такой плохой подход к кодированию. Аргумент, что «если кто-то удалил, вернет, это не сработает», хорошо, вы можете также опечатку в регистре var, или забыть написать регистр, или ...

Возвращается return, и вы не кодируете «оборонительно», чтобы избежать сбоя возврата. Это означало бы, что PHP сломан, и вы не будете заполнять свой код сетями безопасности, чтобы удовлетворить это. Это то, что вы имеете на гораздо более высоком уровне.

2) break после return сохраняет его в явном виде

Но это явно неправильно. return возвращается, поэтому перерыва не произойдет. Для меня это время для размышлений, когда я задаюсь вопросом, пропустил ли я намерение - ненадолго, пока ясно, что произойдет , но будет момент, когда я обдумаю это, чтобы убедиться, что я не пропустил что-то.

Хотя не является недействительным или ошибкой иметь return, а затем break в том же case, это просто совершенно бессмысленно, поскольку break ничего не делает. Это бессмысленный код, который нужно видеть, поддерживать и понимать, поскольку он не логичен.

Если явное является основной целью и с break после того, как return попросит вас, потому что это бессмысленно, то я бы сказал, что было бы лучше установить переменную и break, затем верните переменную после отключения от переключателя.
Мне нравится @RageZ ответ https://stackoverflow.com/a/1437476/2632129

3) Установить переменную и вернуться после завершения оператора switch

В этом подходе нет ничего плохого, но если нет причины хранить значение в переменной (позднее использовать и т. Д.), То лучше сразу вернуться, когда нет необходимости зависать, чтобы делать что-то еще.

Это показывает ясное намерение - вернуть значение, как только будет сопоставлен регистр.

3 голосов
/ 01 августа 2014

У меня есть намного лучшее решение. Пожалуйста, следуйте приведенному ниже коду для вышеуказанного состояния переключателя:

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

Это не приведет к ошибке, и код также подойдет для концепций.

0 голосов
/ 17 сентября 2009

Я не эксперт в идеальном кодировании, но я думаю, что валидатор предпочел бы что-то подобное

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

}
return $ret

Я думаю, что использование оператора return в case для прерывания потока кода на самом деле не лучшая практика. Вот почему валидатор говорит, что перерыва нет ...

На ваш вопрос по поводу категории я не знаю ... извините

0 голосов
/ 17 сентября 2009

Из руководства по PHP (http://us3.php.net/manual/en/control-structures.switch.php):

PHP продолжает выполнять операторы до конца блока переключателя или до первого появления оператора break. Если вы не напишете оператор break в конце списка операторов case, PHP продолжит выполнение операторов следующего дела. Например:

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

Здесь, если $ i равно 0, PHP выполнит все операторы echo! Если $ i равно 1, PHP выполнит последние два оператора echo. Вы получите ожидаемое поведение (будет отображаться «i равно 2») только в том случае, если $ i равно 2. Таким образом, важно не забывать операторы break (даже если вы можете избежать их преднамеренного предоставления при определенных обстоятельствах ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...