Помогите оценить PHP в .tpl файлах - PullRequest
0 голосов
/ 10 февраля 2011

Я использую эту функцию для загрузки файлов шаблонов:

public function loadTemplate ($replaceToken = array(), $path = 'master.tpl') {
    $template = $this->tru->objectFactory('file', $this->tru->config->get('root.path').'/lib/template/email/'.$path);

    $templateContent = $template->readAll();

    if (count($replaceToken) > 0) {
        foreach ($replaceToken as $token => $value) {
            $templateContent = str_replace('{$'.$token.'}', $value, $templateContent);
        }
    }

    return $templateContent;
}

Это позволяет мне вызывать такие переменные, как {$title}. Этого было достаточно сейчас с очень простыми электронными письмами. Но теперь я дошел до того, что мне нужно использовать циклы и, следовательно, иметь возможность запускать PHP в этих файлах .tpl. Я изо всех сил пытаюсь определить лучший маршрут, я знаю, что eval () редко является хорошим решением, но он здесь правильный?

Вот пример одного из моих файлов tpl:

            <tr style='border-top: 1px solid rgb(204, 204, 204); border-bottom: 1px solid rgb(204, 204, 204);'>
                <td style='border-color: #ccc; border-style: solid none; border-width: 1px medium; color: #494949 !important; padding: 5px 10px !important; font-size: 12px;'>Description</td>
                <td style='border-color: #ccc; border-style: solid none; border-width: 1px medium; color: #494949 !important; padding: 5px 10px !important; font-size: 12px;'>Vehicle</td>
                <td style='border-color: #ccc; border-style: solid none; border-width: 1px medium; color: #494949 !important; padding: 5px 10px !important; font-size: 12px; text-align: right;'>Unit price</td>
                <td style='border-color: #ccc; border-style: solid none; border-width: 1px medium; color: #494949 !important; padding: 5px 10px !important; font-size: 12px; text-align: right;'>Qty</td>
                <td style='border-color: #ccc; border-style: solid none; border-width: 1px medium; color: #494949 !important; padding: 5px 10px !important; font-size: 12px; text-align: right;'>Amount</td>
            </tr>
            <?
            foreach ($order['productList'] as $product) {
            ?>
            <tr>
                <td style='padding: 10px; border-bottom: 1px <?=$product['border']?> rgb(204, 204, 204); color: #666 !important;'><?=$product['title']?></td>
                <td style='padding: 10px; border-bottom: 1px <?=$product['border']?> rgb(204, 204, 204); color: #666 !important;'><?=$product['vehicle']?></td>
                <td style='padding: 10px; border-bottom: 1px <?=$product['border']?> rgb(204, 204, 204); color: #666 !important; text-align: right;'>$<?=$product['price']?></td>
                <td style='padding: 10px; border-bottom: 1px <?=$product['border']?> rgb(204, 204, 204); color: #666 !important; text-align: right;'><?=$product['quantity']?></td>
                <td style='padding: 10px; border-bottom: 1px <?=$product['border']?> rgb(204, 204, 204); color: #666 !important; text-align: right;'>$<?=$product['lineTotal']?></td>
            </tr>
            <?
            }
            ?>
            <tr>
                <td colspan='3'></td>
                <td style='padding: 2px 5px; text-align: right; font-size: 12px;'>Subtotal</td>
                <td style='padding: 2px 5px; text-align: right; font-size: 12px;'>$<?=$order['subtotal']?></td>
            </tr>

обновление

Каковы риски безопасности при использовании eval(), например:

public function loadTemplate ($replaceToken = array(), $path = 'master.tpl') {
    $template = $this->tru->objectFactory('file', $this->tru->config->get('root.path').'/lib/template/email/'.$path);

    $templateContent = $template->readAll();

    if (count($replaceToken) > 0) {
        foreach ($replaceToken as $token => $value) {
            $$token = $value;
            $templateContent = str_replace('{$'.$token.'}', $value, $templateContent);
        }
    }

    ob_start();
    eval('?>'.$templateContent.'<?');
    $templateContent = ob_get_contents();
    ob_end_clean();
    return $templateContent;
}

Я не могу думать о том, как это может быть небезопасно. Переменные, даже если они содержат код PHP, не являются eval (), поэтому наши файлы .tpl (которые в любом случае требуют нашего собственного доступа разработчика)

Ответы [ 2 ]

1 голос
/ 10 февраля 2011

Это похоже на тег Smarty.Если это так, вы оборачиваете PHP в тег {php}.

Правка для добавления примера кода:

This is a smarty tag: {$title}

{* this is a smarty foreach loop *}
{forach from=$some_array item=i}
    {$i}
{/foreach}

{php}
// this is literal PHP within a smarty template
foreach ($some_array as $k=>$v) {
   print $k.'=>'.$v.'<br />';
}
{/php}
0 голосов
/ 10 февраля 2011

Вы можете принять вызов и написать собственный анализатор для этой проблемы.

Более простым и подходящим способом для вашего вопроса будет использование уже существующих шаблонизаторов, таких как Smarty . С его помощью вы можете либо определить собственные функции (так называемые «блоки»), которые выполняют фактическое выполнение PHP, либо использовать предопределенные директивы ({foreach ...}).

Все будет в порядке с вашим существующим стилем шаблона, поскольку Smarty оценивает переменные шаблона, как в вашем примере: они выражаются как {$variable}.


EDIT

Я плохо себя чувствую, печатая это. eval на самом деле опечатка. a на самом деле i. Вот и мы:

Это способ достижения вашей цели , но пожалуйста не используйте это в производственной среде:

$template = '<?php for($i = 0; $i < 10; $i++) { ?>
    <b>something</b><?php
} ?>';

eval('?>' . $template);

Этот фрагмент кода дает вам демонстрацию десяти "foo" s.

...