Как этот действительный php-код?
Я изменяю шаблон Wordpress, и мне любопытно, как это допустимая структура управления в PHP. У кого-нибудь есть понимание?
<?php if(condition): ?>
<?php if(!condition || !function()) ?>
<?php elseif(condition): ?>
<?php if(!condition || !function()) ?>
<?php endif; ?>
Если я удалю все теги, я получаю (с более строгим отступом):
<?php
if(condition):
if(!condition || !function())
elseif(condition):
if(!condition || !function())
endif;
?>
что недействительно, поскольку отступы if
не заканчиваются. Итак, как/почему этот код действителен, если во всем мире открываются и закрываются теги php?
Изменить для Kerrek SB. Создайте файл php и запустите его. Это действительно:
<?php if(true): ?>
<?php if(true) ?>
<?php endif; ?>
<?php echo 'here'; ?>
Ответы
Ответ 1
Ваш (приведенный) примерный код эквивалентен этому:
<?php
if(condition):
if(!condition || !function()) { }
endif;
?>
Или даже:
<?php
if(condition):
if(!condition || !function());
endif;
?>
Закрыв тэг <?php
, вы получите бесплатную "пустое выражение".
Ваш реальный пример может быть однострочным:
<?php if(true): if(true); endif; echo 'here'; ?>
Но обратите внимание, что elseif
делает это двусмысленным!
<?php
if(condition):
if(!condition || !function());
elseif(condition): // Bogus! which block does this belong to?
if(!condition || !function());
endif;
?>
Нам нужно было бы устранить эту проблему:
<?php
if(condition):
{
if(!condition || !function());
}
elseif(condition):
{
if(!condition || !function());
}
endif;
?>
Теперь ясно, но теперь мы могли бы полностью избавиться от синтаксиса двоеточия.
Спасибо Лекенштейну за то, что указали это!
См. обсуждение ниже для дальнейших странностей.
Ответ 2
Ваш код не будет работать, потому что PHP удаляет одну новую строку после ?>
, если она существует. ?>[newline]<?php
будет таким же, как ?><?php
Что-то вроде ниже имеет смысл (function
заменяется на fn
, так как function
- это ключевое слово;)):
<?php if(condition): ?>
<?php if(!condition || !fn()) ?>
some
<?php elseif(condition): ?>
<?php if(!condition || !fn()) ?>
thing
<?php endif; ?>
Он будет интерпретироваться как:
<?php
if(condition):
if(!condition || !fn()) echo "some";
elseif(condition):
if(!condition || !fn()) echo "thing";
endif;
?>
Обратите внимание, что на двух ifs нет :
, они будут обрабатываться как if
, которые ожидают тела рядом с ним. Написано другим способом:
<?php
if (condition) {
if (!condition || !fn()) {
echo "some";
}
} else if (condition) {
if (!condition || !fn()) {
echo "thing";
}
}
?>
Ответ 3
Если вы не используете, вам нужно следить за: для логики после вложенных if (s).
<?php
function foobar() {
return true;
}
function bar() {
return false;
}
$foobar = true;
$bar = false;
if($foobar):
if(!$bar || !foobar()):
echo 'foobar';
endif;
elseif($bar):
if(!$foobar || !bar()):
echo 'bar';
endif;
endif;
Ответ 4
", что является недопустимым, поскольку инструкции с отступом if не заканчиваются"
Да, да. Как указано на php.net, смешение обеих нот не поддерживается, а значит, у вас есть новый код-блок (два if()
без следующей двойной точки) в ваших if():
, elseif():
и endif;
.
if(condition):
if(!condition || !function())
// do nothing here, end of first inner if
elseif(condition):
if(!condition || !function())
// also do nothing here, end of second inner if
endif; // end of outer if/else
Ответ 5
что является недопустимым, поскольку инструкции с отступами if не заканчиваются
Собственно, это так. ?>
завершает оператор, как и любой другой, поэтому:
<?php
if(condition):
if(!condition || !function());
elseif(condition):
if(!condition || !function());
endif;
?>
Если бы это было не так, тогда также была бы синтаксическая ошибка:
Lol <?php echo "cakes" ?> extravaganza <?php echo "innit" ?>
Ответ 6
Я вижу, что вы смешиваете две возможные формы построения "if" в php.
Первая форма:
if ( condition ) instruction;
if ( condition ) { more; than; one; instructions; }
Второй:
if ( condition ): instruction; another; endif;
Когда вы пишете
<?php if (condition) ?>
... без тега '{' или ':' перед тегом закрытия?? > , на самом деле вы усекаете команду if, опускающую инструкции, и PHP это принимает. Когда вы снова откроете тег php, вы уже находитесь за пределами if.
То же самое не применимо, если вы просто "забудете" инструкцию в одном блоке, где "endif;" не разрешено в качестве инструкции;
Итак:
<?php if (condition) ?>
anything outside the if
<?php instruction_outside_the_if; ?>
... не имеет смысла (потому что вы разрабатываете, если ничего не делать после него), но не является строгой ошибкой.
<?php if (condition 1): ?> <!-- note the ':' in this if -->
<?php if (condition 2) ?>
anything outside the second if but inside the first
<?php endif; ?> <!-- this closes the first if
... здесь у вас есть первое, если это работает, но второе по-прежнему пусто.
<?php if (condition 1): ?> <!-- note the ':' in this if -->
<?php if (condition 2) ?>
anything outside the second if but inside the first
<?php else: ?>
still outside the second if but inside the first, in the ELSE part
<?php endif; ?> <!-- this closes the first if
... это более или менее похоже на ваш пример, где else (или elseif) принадлежит первому, если.
<?php if (true) ?>
<?php elseif(foo){ }; ?>
Это другое исключение, поскольку вы не помещаете ничего между закрывающим тегом и открывающим тегом, поэтому парсер "оптимизирует" их (это не совсем так, но это правильное приближение). Попробуйте поставить что-нибудь между двумя тегами php, например:
<?php if (true) ?>
anything
<?php elseif(foo){ }; ?>
... и увидите "синтаксическую ошибку, неожиданный T_ELSEIF".
Ответ 7
Проверьте PHP.net объяснение