繁体   English   中英

这个有效的 php 代码如何?

[英]How is this valid php code?

我正在修改 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'; ?>

您的(简化的)示例代码等效于:

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

现在很清楚了,但现在我们可以完全不用冒号语法了。

感谢 Lekensteyn 指出这一点!

请参阅下面的讨论以了解更多奇怪之处。

您的代码将不起作用,因为 PHP 在?>之后删除了一个换行符(如果存在)。 ?>[newline]<?php?><?php

像下面这样的东西会更有意义( functionfn替换,因为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;
?>

请注意,在两个 if 上没有: ,它们将被视为一个if ,它期望在它旁边有一个主体。 换一种方式写:

<?php
if (condition) {
    if (!condition || !fn()) {
        echo "some";
    }
} else if (condition) {
    if (!condition || !fn()) {
        echo "thing";
    }
}
?>

如果您不使用,则需要跟进:嵌套 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;

“这是无效的,因为缩进的 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

这是无效的,因为缩进的 if 语句没有结束

事实上,他们确实如此。 ?>像其他任何语句一样终止语句,因此:

<?php
if(condition):
    if(!condition || !function());
elseif(condition):
    if(!condition || !function());
endif;
?>

如果不是这种情况,那么以下也将是语法错误:

Lol <?php echo "cakes" ?> extravaganza <?php echo "innit" ?>

我看到的是,您正在混淆在 php 中构建“if”结构的两种可能形式。

第一种形式是:

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

... 是没有意义的(因为你详细说明了一个 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 )属于第一个 if。


<?php if (true) ?>
<?php elseif(foo){ }; ?>

这是另一个例外,因为您没有在结束标记和开始标记之间放置任何内容,因此解析器“优化”它们(不完全一样,但它是正确的近似值)。 尝试在两个 php 标签之间放置任何内容,例如:

<?php if (true) ?>
anything
<?php elseif(foo){ }; ?>

...并看到“语法错误,意外的 T_ELSEIF”出现。

查看 PHP.net 的解释

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM