phploopscontrol-structure

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


I'm creating a very large page that at various parts needs to loop through a data array like this:

$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;
    }
}

This is reminiscent to me of the WordPress Loop. I know I can compact all the loops into one, storing HTML output in variables and piecing them together at the end, but I strongly desire for code to appear in alignment with the HTML that will surround it.

How can I factor out everything on the outside? Even if it's as hacky as:

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

I'm not concerned about correctness here—I just need this demo to work, and for the code to be readable in a presentation top-to-bottom with a synchronized sense of what else is on the page. Preferably PHP 5.3-compatible—not positive the demo server will be running PHP 5.4+—but if a solution exists using PHP 5.4+ constructs, please share anyway. Thank you.


Solution

  • I was able to get what I wanted by using callbacks.

    First, define the wrapper ("macro") function, like so:

    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);
            }
        }
    }
    

    So in the above, I'm passing down $program and $pid to a not-yet-defined callback function, as these two variables are always needed, and needed frequently.

    To actually use this construct, one would simply do this:

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

    And you can disperse this wherever you like in your page. You can of course have as many frequently-used variables as you like in addition to $program and $pid.

    I still recommend reading @Marty's advice in the question's comments for a proper, non-hacky approach. But yeah, that's what I did.