如何从 CakePHP 中的字符串 load/execute 视图模板

How to load/execute a view template from a string in CakePHP

我开发了一个 CakePHP 插件,允许站点管理员将自定义报告定义为执行的 SQL 查询列表,并通过 .ctp 模板显示结果。

现在我需要允许管理员编辑模板,与报告一起存储在数据库中。 因此,我需要呈现一个位于字符串内部而不是 .ctp 文件中的模板,我在核心中找不到任何有用的东西。

我最初考虑过在 .ctp 文件中编写模板并从那里加载它们的方法,但我怀疑这个解决方案存在缺陷:文件的位置和相关权限。

更好的解决方案似乎是覆盖视图 class 并添加一个方法来执行此操作。

谁能提出更好的方法?

P.S。安全在这里不是问题,因为管理员基本上是无法访问代码的开发人员。

Hmmm.. 也许创建一个变量来存储生成的代码,并且只是 'echo' 这个变量在 ctp 文件中。

我有类似的问题 (cakephp 3) 控制器方法:

public function preview($id = null) {

    $this->loadModel('Templates');
    $tempate = $this
        ->Templates
        ->findById($id)
        ->first();

    if(is_null($template)) {
        $this->Flash->error(__('Template not found'));
        return $this->redirect($this->referer());
    }

    $html = $template->html_content;
    $this->set(compact('html'));
}

而 preview.ctp 只是:

<?= $html

在 CakePHP 2.0 中: View::render()方法使用

导入模板文件

include

The include statement includes and evaluates the specified file.

已评估的模板会立即在它包含的任何范围内执行。要复制此功能,您需要使用

eval()

Caution: The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged. If you have carefully verified that there is no other option than to use this construct, pay special attention not to pass any user provided data into it without properly validating it beforehand.

(这个警告是专门对你说的)


...如果您希望继续...这是您如何实现这一目标的基本示例:

$name = 'world';
$template = 'Hello <?php echo $name ?>... <br />';

echo $template;
// Output: Hello ...

eval(' ?>' . $template . '<?php ');
// Output: Hello world...

这(几乎)完全相同:

$name = 'world';
$template = 'Hello <?php echo $name ?>... <br />';
file_put_contents('path/to/template.php', $template);

include 'path/to/template.php';

除非人们不会因为使用 eval()

而对你大吼大叫

在您的 CakePHP 应用程序中:

app/View/EvaluatorView.php

class EvaluatorView extends View
{
    public function renderRaw($template, $data = [])
    {
        if (empty($data)) {
            $data = $this->viewVars;
        }
        extract($data, EXTR_SKIP);

        ob_start();
        eval(' ?>' . $template . '<?php ');
        $output = ob_get_clean();

        return $output;
    }
}

app/Controller/ReportsController.php

class ReportsController extends AppController
{
    public function report()
    {
        $this->set('name', 'John Galt');
        $this->set('template', 'Who is <?php echo $name; ?>?');
        $this->viewClass = 'Evaluator';
    }
}

app/View/Reports/report.ctp

// Content ...

$this->renderRaw($template);

或者,您可能想查看现有的模板引擎,例如:Mustache, Twig, and Smarty.