我开发了一个CakePHP插件,允许网站管理员将自定义报告定义为执行的SQL查询列表以及.ctp模板显示的结果。
现在我需要允许管理员编辑存储在数据库中的模板以及报告。 因此,我需要渲染一个字符串内部而不是.ctp文件中的模板,而我在核心中找不到任何有用的内容。
我最初考虑过在.ctp文件中编写模板并从那里加载它们的方法,但我怀疑这个解决方案是否有错误:文件的位置和相关权限。
更好的解决方案似乎会覆盖View类并添加一个方法来执行此操作。
有人能提出更好的方法吗?
P.S。安全性不是问题,因为管理员基本上是一个无法访问代码的开发人员。
答案 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);