有没有办法在 PHP 中创建 "custom" 循环或控制结构?

Is there a way to create a "custom" loop or control structure in PHP?

我正在创建一个非常大的页面,它的各个部分都需要像这样遍历数据数组:

$processed = array();
foreach( $data as $program )
{
    if( $program['f_enabled'] == 'N' ) continue;
    $pid = $program['f_programId'];
    if( !array_key_exists($pid, $processed) )
    {
        /**
         *  Do things with $pid and $program['f_foobar'], including
         *  ?>
         *      <span>HTML with <?=$inlined_vars?></span>
         *  <?php
         */
        $processed[] = $pid;
    }
}

这让我想起了 WordPress 循环。我知道我可以将所有循环压缩成一个,将 HTML 输出存储在变量中并在最后将它们拼凑在一起,但我强烈希望代码与围绕它的 HTML 对齐。

我怎样才能把外面的一切都分解出来?即使它像这样 hacky:

MY_HORRIFYING_MACRO
{
        /**
         *  Do things with $pid and $program['f_foobar'], including
         *  ?>
         *      <span>HTML with <?=$inlined_vars?></span>
         *  <?php
         */
}

我不关心这里的正确性——我只需要这个演示可以工作,并且代码在演示文稿中从上到下可读,并且同步感知页面上的其他内容。最好是 PHP 5.3 兼容——不肯定演示服务器将是 运行 PHP 5.4+——但如果存在使用 PHP 5.4+ 构造的解决方案,请无论如何分享。谢谢。

您不能在 PHP 中执行类似的操作,但要在 HTML 中显示数据处理,请使用类似 Twig 或类似的操作。

无需制作新的控制结构(如您在 Ruby 中所做的那样),您可以使用更多样板但更惯用 PHP 来做一些事情,如下所示:

$processed = array();
function preloop($program) {
    if( $program['f_enabled'] == 'N' ) return true;
    $pid = $program['f_programId'];
    if( !array_key_exists($pid, $processed) )
    {
        $processed[] = $pid;
        return false;
    }
    return true;
}
foreach( $data as $program ) {
    if (preloop($program))
        continue;

    // do things with program
}
// somewhere else
foreach( $data as $program ) {
    if (preloop($program))
        continue;

    // do things with program
}

我能够通过使用回调得到我想要的东西。

首先,定义包装器("macro")函数,如下所示:

function my_macro($data, $fn)
{
    foreach( $data as $program )
    {
        if( $program['f_enabled'] == 'N' ) continue;
        $pid = $program['f_programId'];
        if( !array_key_exists($pid, $processed) )
        {
            call_user_func($fn, $program, $pid);
        }
    }
}

所以在上面,我将 $program$pid 传递给一个尚未定义的回调函数,因为这两个变量总是需要的,而且经常需要。

要实际使用此构造,只需执行以下操作:

my_macro(function($program, $pid)
{
    /**
     *  Do things here, including
     *  ?>
     *      <span>HTML with <?=$pid?> and <?=$program['title']?></span>
     *  <?php
     */
});

您可以将其分散在页面中的任何位置。除了 $program$pid.

之外,您当然可以拥有任意多的常用变量

我仍然建议阅读问题评论中@Marty 的建议,以获得正确的、非 hacky 的方法。但是,是的,我就是这么做的。