模板引擎

渲染驱动

EasySwoole引入模板渲染驱动的形式,把需要渲染的数据,通过协程客户端投递到自定义的同步进程中进行渲染并返回结果。为何要如此处理,原因在于,市面上的一些模板引擎在Swoole协程下存在变量安全问题。例如以下流程:

  • request A reached, static A assign requestA-data
  • compiled template
  • write compiled template (yiled current coroutine)
  • request B reached,static A assign requestB-data
  • render static A data into complied template file

    以上流程我们可以发现,A请求的数据,被B给污染了。为了解决该问题,EasySwoole引入模板渲染驱动模式。

安装

  1. composer require easyswoole/template

基础实现讲解

实现渲染引擎

  1. use EasySwoole\Template\Config;
  2. use EasySwoole\Template\Render;
  3. use EasySwoole\Template\RenderInterface;
  4. class R implements RenderInterface
  5. {
  6. public function render(string $template, array $data = [], array $options = []):?string
  7. {
  8. return 'asas';
  9. }
  10. public function afterRender(?string $result, string $template, array $data = [], array $options = [])
  11. {
  12. // TODO: Implement afterRender() method.
  13. }
  14. public function onException(Throwable $throwable):string
  15. {
  16. return $throwable->getMessage();
  17. }
  18. }

HTTP服务中调用

  1. //在全局的主服务中创建事件中,实例化该Render,并注入你的驱动配置
  2. Render::getInstance()->getConfig()->setRender(new R());
  3. $http = new swoole_http_server("0.0.0.0", 9501);
  4. $http->on("request", function ($request, $response)use($render) {
  5. //调用渲染器,此时会通过携程客户端,把数据发往自定义的同步进程中处理,并得到渲染结果
  6. $response->end(Render::getInstance()->render('a.html'));
  7. });
  8. $render->attachServer($http);
  9. $http->start();

重启渲染引擎

由于某些模板引擎会缓存模板文件 导致可能出现以下情况: × 用户A请求1.tpl 返回‘a’ × 开发者修改了1.tpl的数据,改成了‘b’ × 用户B,C,D在之后的请求中,可能会出现‘a’,‘b’两种不同的值

那是因为模板引擎已经缓存了A所在进程的文件,导致后面的请求如果也分配到了A的进程,就会获取到缓存的值

解决方案如下: 1:重启easyswoole,即可解决 2:模板渲染引擎实现了重启方法restartWorker,直接调用即可

  1. Render::getInstance()->restartWorker();

用户可根据自己的逻辑,自行调用restartWorker方法进行重启 例如在控制器新增reload方法:

  1. <?php
  2. namespace App\HttpController;
  3. use EasySwoole\Http\AbstractInterface\Controller;
  4. use EasySwoole\Template\Render;
  5. class Index extends Controller
  6. {
  7. function index()
  8. {
  9. $this->response()->write(Render::getInstance()->render('index.tpl',[
  10. 'user'=>'easyswoole',
  11. 'time'=>time()
  12. ]));
  13. }
  14. function reload(){
  15. Render::getInstance()->restartWorker();
  16. $this->response()->write(1);
  17. }
  18. }

Smarty 渲染

引入Smarty

  1. composer require smarty/smarty - request A reached, static A assign requestA-data
  2. - compiled template
  3. - write compiled template (yiled current coroutine)
  4. - request B reachedstatic A assign requestB-data
  5. - render static A data into complied template file

实现渲染引擎

  1. use EasySwoole\Template\RenderInterface;
  2. use EasySwoole\Template\RenderInterface;
  3. class Smarty implements RenderInterface
  4. {
  5. private $smarty;
  6. function __construct()
  7. {
  8. $temp = sys_get_temp_dir();
  9. $this->smarty = new \Smarty();
  10. $this->smarty->setTemplateDir(__DIR__.'/');
  11. $this->smarty->setCacheDir("{$temp}/smarty/cache/");
  12. $this->smarty->setCompileDir("{$temp}/smarty/compile/");
  13. }
  14. public function render(string $template, array $data = [], array $options = []): ?string
  15. {
  16. foreach ($data as $key => $item){
  17. $this->smarty->assign($key,$item);
  18. }
  19. return $this->smarty->fetch($template,$cache_id = null, $compile_id = null, $parent = null, $display = false,
  20. $merge_tpl_vars = true, $no_output_filter = false);
  21. }
  22. public function afterRender(?string $result, string $template, array $data = [], array $options = [])
  23. {
  24. }
  25. public function onException(\Throwable $throwable): string
  26. {
  27. $msg = "{$throwable->getMessage()} at file:{$throwable->getFile()} line:{$throwable->getLine()}";
  28. trigger_error($msg);
  29. return $msg;
  30. }
  31. }

HTTP服务中调用

  1. //在全局的主服务中创建事件中,实例化该Render,并注入你的驱动配置
  2. Render::getInstance()->getConfig()->setRender(new Smarty());
  3. Render::getInstance()->getConfig()->setTempDir(EASYSWOOLE_TEMP_DIR);
  4. Render::getInstance()->attachServer(ServerManager::getInstance()->getSwooleServer());
  5. //在action中实现响应
  6. Render::getInstance()->render('a.html');

支持常用的模板引擎

下面列举一些常用的模板引擎包方便引入使用:

smarty/smarty

Smarty是一个使用PHP写出来的模板引擎,是目前业界最著名的PHP模板引擎之一

::: warning composer require smarty/smarty=~3.1 :::

league/plates

使用原生PHP语法的非编译型模板引擎,更低的学习成本和更高的自由度

::: warning composer require league/plates=3.* :::

duncan3dc/blade

Laravel框架使用的模板引擎

::: warning composer require duncan3dc/blade=^4.5 :::

topthink/think-template

ThinkPHP框架使用的模板引擎

::: warning composer require topthink/think-template :::