如何从CakePHP中的字符串加载/执行视图模板

时间:2017-05-19 10:07:58

标签: cakephp cakephp-2.0

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

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

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

更好的解决方案似乎会覆盖View类并添加一个方法来执行此操作。

有人能提出更好的方法吗?

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

2 个答案:

答案 0 :(得分:0)

嗯..也许创建一个变量来存储生成的代码,并在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'));
}

而预览.ctp只是:

<?= $html

答案 1 :(得分:0)

在CakePHP 2 .0: View::render()方法使用

导入模板文件

include

  

include语句包括评估指定的文件。

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

eval()

  

警告: eval()语言构造非常危险,因为它   允许执行任意PHP代码。因此不鼓励使用它。   如果您已经仔细确认除了以外没有其他选择   使用此构造,请特别注意不要传递任何用户   提供数据而未事先正确验证。

(此警告是针对您的,具体而言)

...如果你想继续...... 以下是你如何实现这个目标的基本例子:

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

或者,您可能需要查看现有的模板引擎,例如:MustacheTwigSmarty