Я создаю очень большую страницу, которая в разных частях должна проходить через массив данных следующим образом:
$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, который будет его окружать.
Как я могу выделить все снаружи? Даже если он такой же хакерский, как:
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+, пожалуйста, поделитесь в любом случае. Спасибо.
Вместо создания новой структуры управления (как это было бы в 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
}
Вы не можете сделать что-то подобное в PHP
, но для обработки данных, которые будут показаны в HTML
использовать что-то вроде Twig
или похожие.
Я смог получить то, что хотел, используя обратные вызовы.
Сначала определите функцию-обертку («макрос») следующим образом:
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
,
Я все еще рекомендую прочитать совет @ Марти в комментариях к вопросу для правильного, не хакерского подхода. Но да, это то, что я сделал.