PHP разрешает неверный код в выражениях switch - PullRequest
8 голосов
/ 09 июля 2011

У меня возникли проблемы с пониманием того, почему следующее не приводит к ошибке компилятора в 5.3.3 (на моих коллегах 5.2.5 произошла ошибка):

<?php
    echo "starting\n";

    switch(1) {
        case 2:
            echo "two\n";
            break;
        defalut:        // note the misspelling
            echo "deflaut\n";
    }

    echo "ending\n";

Вместо того, чтобы выдавать мне ошибку компилятора (или даже предупреждение), он просто выдает это:

starting
ending

Однако, если я использую его в операторе if, это даст мне то, что я ожидал:

<?php
    if (1 == deflaut)
        echo "deflaut2\n";

дает:

PHP Notice:  Use of undefined constant deflaut - assumed 'deflaut' in ...

Почему это? Есть ли где-то настройка, которую я могу отключить, чтобы она была строгой в отношении такого рода вещей?

Ответы [ 3 ]

8 голосов
/ 09 июля 2011

Возможно, это будет интерпретироваться как просто другая метка (что имеет смысл, учитывая, что технически default - это метка, а case также может быть интерпретирована как особый вид метки), которая может использоваться с goto. Попробуйте goto и узнайте. Я бы хотел, но у меня нет PHP 5.3.3, извините.

4 голосов
/ 09 июля 2011

Проблема в том, что ваш код не делает то, что вы думаете. Блок case заканчивается только тогда, когда появляется следующий блок case, или когда найден default:, или когда достигается закрытие }. Это означает, что defalut является частью блока case 2:. Так что это даже не интерпретируется.

Однако он даже не вызывает синтаксическую ошибку (даже если вы делаете switch (2). Это потому, что оператор goto был введен в PHP 5.3. Синтаксис word: в начало оператора PHP теперь является целью, доступной через goto. Таким образом, goto defalut; может использоваться для перехода к метке.

(На самом деле, он не может из-за ограничения целей внутри блоков switch, чтобы избежать бесконечных циклов, но это должно проиллюстрировать точку ...)

Вы можете принудительно вызвать ошибку, выполнив case defalut, когда обнаружена ожидаемая ошибка.

1 голос
/ 09 июля 2011

Интересно, что на моем 5.3.2 это не удается ЕСЛИ НЕТ другого оператора case выше неправильно введенного по умолчанию.

Умирает с синтаксической ошибкой "T_UNEXPECTED_STRING":

switch (1) {
   defalut:
       echo "this should never come out";
       break;
   default:
       echo "default matched properly"
}

Это работает:

switch (1) {
   case 2:
        echo "2\n";
        break;
   defalut:
        echo "this should never come out";
        break;
   default:
        echo "the default value\n";
}

Похоже, вы нашли ошибку в синтаксическом анализаторе PHP. Не будет серьезной ошибки, но, тем не менее, ошибки.

...