diff --git a/README.md b/README.md index a9fda06..06cd58d 100644 --- a/README.md +++ b/README.md @@ -3,65 +3,117 @@ ## 实现原理 注册N个自定义进程做渲染进程,进程内关闭协程环境,并监听UNIXSOCK,客户端调用携程的client客户端发送数据给进程渲染,进程再返回结果给客户端,用来解决PHP模板引擎协程安全问题。可以实现渲染接口,根据自己的喜好引入smarty或者是blade或者是其他引擎. -### 原理基础实现 +## 引入模板引擎类 + +下面列举一些常用的模板引擎包方便引入使用: + +### [smarty/smarty](https://github.com/smarty-php/smarty) + +Smarty是一个使用PHP写出来的模板引擎,是目前业界最著名的PHP模板引擎之一 + +> composer require smarty/smarty=~3.1 + + +### [league/plates](https://github.com/thephpleague/plates) + +使用原生PHP语法的非编译型模板引擎,更低的学习成本和更高的自由度 + +> composer require league/plates=3.* + +### [duncan3dc/blade](https://github.com/duncan3dc/blade) + +Laravel框架使用的模板引擎 + +> composer require duncan3dc/blade=^4.5 + +### [topthink/think-template](https://github.com/top-think/think-template) + +ThinkPHP框架使用的模板引擎 + +> composer require topthink/think-template + + +## 渲染模板 + +选择一个心仪的模板引擎,并实现RenderInterface接口,当进程收到一条渲染指令时,会调用该实现类的render方法进行渲染,渲染结束后调用afterRender方法,可在此处进行变量释放清理等操作,以Smarty引擎为例,创建一个渲染器, 并渲染的最小例子如下 + +### 用Smarty作为渲染器 + ```php +engine = new \Smarty(); + $this->engine->setTemplateDir($viewsDir); + $this->engine->setCacheDir($cacheDir); + $this->engine->setCompileDir($cacheDir); } - public function afterRender(?string $result, string $template, array $data = [], array $options = []) + /** + * 模板渲染 + * @param string $template + * @param array $data + * @param array $options + * @return string|null + * @throws SmartyException + */ + public function render(string $template, array $data = [], array $options = []): ?string { - // TODO: Implement afterRender() method. + foreach ($data as $key => $item) { + $this->engine->assign($key, $item); + } + return $this->engine->fetch($template); } - public function onException(Throwable $throwable):string + /** + * 每次渲染完成都会执行清理 + * @param string|null $result + * @param string $template + * @param array $data + * @param array $options + */ + public function afterRender(?string $result, string $template, array $data = [], array $options = []) { - return $throwable->getMessage(); + } + /** + * 异常处理 + * @param Throwable $throwable + * @return string + * @throws Throwable + */ + public function onException(Throwable $throwable): string + { + throw $throwable; + } } +// 配置渲染器 $config = new Config(); -$config->setRender(new R()); +$config->setRender(new SmartyRender()); $render = new Render($config); +// 启动Swoole(在框架中使用时可以省略) $http = new swoole_http_server("0.0.0.0", 9501); -$http->on("request", function ($request, $response)use($render) { - $response->end($render->render('a.html')); +$http->on("request", function (\Swoole\Http\Request $request, \Swoole\Http\Response $response)use($render) { + $content = $render->render('smarty.tpl',['time'=>time()]); // 调用渲染器进行渲染 + $response->end($content); }); $render->attachServer($http); - $http->start(); -``` - -## 用Smarty作为渲染器 -``` -use EasySwoole\Template\Config; -use EasySwoole\Template\Render; -use EasySwoole\Template\Test\Smarty; - -$config = new Config(); -$config->setRender(new Smarty()); -$render = new Render($config); - -$http = new swoole_http_server("0.0.0.0", 9501); -$http->on("request", function ($request, $response)use($render) { - $response->end($render->render('smarty.tpl',[ - 'time'=>time() - ])); -}); -$render->attachServer($http); - -$http->start(); -``` -> EasySwoole\Template\Test\Smarty 为测试用渲染器,测试前请引入smarty/smarty包。 - -## 用Blade作为渲染器 \ No newline at end of file +``` \ No newline at end of file diff --git a/composer.json b/composer.json index d94b25d..8750dfb 100644 --- a/composer.json +++ b/composer.json @@ -2,9 +2,14 @@ "name": "easyswoole/template", "type": "library", "description": "An efficient swoole framework", - "keywords" : ["swoole", "framework", "async","easyswoole"], - "homepage" : "https://www.easyswoole.com/", - "license" : "Apache-2.0", + "keywords": [ + "swoole", + "framework", + "async", + "easyswoole" + ], + "homepage": "https://www.easyswoole.com/", + "license": "Apache-2.0", "authors": [ { "name": "YF", @@ -13,14 +18,24 @@ ], "require": { "easyswoole/spl": "^1.0", - "easyswoole/component": "^1.5" + "easyswoole/component": "^1.5", + "phpunit/phpunit": "^8.1", + "smarty/smarty": "~3.1", + "league/plates": "3.*", + "duncan3dc/blade": "^4.5" }, "require-dev": { - "easyswoole/swoole-ide-helper": "^1.1" + "easyswoole/swoole-ide-helper": "^1.1", + "topthink/think-template": "^2.0" }, "autoload": { "psr-4": { "EasySwoole\\Template\\": "src/" } + }, + "autoload-dev": { + "psr-4": { + "EasySwoole\\Template\\TestCase\\": "tests/" + } } } diff --git a/tests/Engine/Blade.php b/tests/Engine/Blade.php new file mode 100644 index 0000000..2ba8dd2 --- /dev/null +++ b/tests/Engine/Blade.php @@ -0,0 +1,66 @@ +engine = new BladeInstance($viewsDir, $cacheDir); + } + + /** + * 模板渲染 + * @param string $template + * @param array $data + * @param array $options + * @return string|null + */ + public function render(string $template, array $data = [], array $options = []): ?string + { + $content = $this->engine->render($template, $data); + return $content; + } + + /** + * 每次渲染完成都会执行清理 + * @param string|null $result + * @param string $template + * @param array $data + * @param array $options + */ + public function afterRender(?string $result, string $template, array $data = [], array $options = []) + { + + } + + /** + * 异常处理 + * @param Throwable $throwable + * @return string + * @throws Throwable + */ + public function onException(\Throwable $throwable): string + { + throw $throwable; + } +} \ No newline at end of file diff --git a/tests/Engine/Plates.php b/tests/Engine/Plates.php new file mode 100644 index 0000000..e72159b --- /dev/null +++ b/tests/Engine/Plates.php @@ -0,0 +1,63 @@ +engine = new PlatesEngine($viewsDir); + } + + /** + * 模板渲染 + * @param string $template + * @param array $data + * @param array $options + * @return string|null + */ + public function render(string $template, array $data = [], array $options = []): ?string + { + $content = $this->engine->render($template, $data); + return $content; + } + + /** + * 每次渲染完成都会执行清理 + * @param string|null $result + * @param string $template + * @param array $data + * @param array $options + */ + public function afterRender(?string $result, string $template, array $data = [], array $options = []) + { + + } + + /** + * 异常处理 + * @param Throwable $throwable + * @return string + * @throws Throwable + */ + public function onException(\Throwable $throwable): string + { + throw $throwable; + } +} \ No newline at end of file diff --git a/tests/Engine/Smarty.php b/tests/Engine/Smarty.php new file mode 100644 index 0000000..791637e --- /dev/null +++ b/tests/Engine/Smarty.php @@ -0,0 +1,67 @@ +engine = new \Smarty(); + $this->engine->setTemplateDir($viewsDir); + $this->engine->setCacheDir($cacheDir); + $this->engine->setCompileDir($cacheDir); + } + + /** + * 模板渲染 + * @param string $template + * @param array $data + * @param array $options + * @return string|null + * @throws SmartyException + */ + public function render(string $template, array $data = [], array $options = []): ?string + { + foreach ($data as $key => $item) { + $this->engine->assign($key, $item); + } + return $this->engine->fetch($template); + } + + /** + * 每次渲染完成都会执行清理 + * @param string|null $result + * @param string $template + * @param array $data + * @param array $options + */ + public function afterRender(?string $result, string $template, array $data = [], array $options = []) + { + + } + + /** + * 异常处理 + * @param Throwable $throwable + * @return string + * @throws Throwable + */ + public function onException(Throwable $throwable): string + { + throw $throwable; + } +} \ No newline at end of file diff --git a/tests/Engine/Think.php b/tests/Engine/Think.php new file mode 100644 index 0000000..cc089f2 --- /dev/null +++ b/tests/Engine/Think.php @@ -0,0 +1,70 @@ + $viewsDir . '/', + 'cache_path' => $cacheDir . '/', + 'view_suffix' => 'html', + ]; + $this->engine = new ThinkEngine($config); + } + + /** + * 模板渲染 + * @param string $template + * @param array $data + * @param array $options + * @return string|null + */ + public function render(string $template, array $data = [], array $options = []): ?string + { + ob_start(); + $this->engine->fetch($template, $data); + $content = ob_get_clean(); + return $content; + } + + /** + * 每次渲染完成都会执行清理 + * @param string|null $result + * @param string $template + * @param array $data + * @param array $options + */ + public function afterRender(?string $result, string $template, array $data = [], array $options = []) + { + + } + + /** + * 异常处理 + * @param Throwable $throwable + * @return string + * @throws Throwable + */ + public function onException(\Throwable $throwable): string + { + throw $throwable; + } +} \ No newline at end of file diff --git a/tests/Plates.php b/tests/Plates.php deleted file mode 100644 index b2dd5da..0000000 --- a/tests/Plates.php +++ /dev/null @@ -1,26 +0,0 @@ -smarty = new \Smarty(); - $this->smarty->setTemplateDir(__DIR__.'/'); - $this->smarty->setCacheDir("{$temp}/smarty/cache/"); - $this->smarty->setCompileDir("{$temp}/smarty/compile/"); - } - - public function render(string $template, array $data = [], array $options = []): ?string - { - foreach ($data as $key => $item){ - $this->smarty->assign($key,$item); - } - return $this->smarty->fetch($template,$cache_id = null, $compile_id = null, $parent = null, $display = false, - $merge_tpl_vars = true, $no_output_filter = false); - } - - public function afterRender(?string $result, string $template, array $data = [], array $options = []) - { - - } - - public function onException(\Throwable $throwable): string - { - $msg = "{$throwable->getMessage()} at file:{$throwable->getFile()} line:{$throwable->getLine()}"; - trigger_error($msg); - return $msg; - } -} \ No newline at end of file diff --git a/tests/TemplateCache/.gitignore b/tests/TemplateCache/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/tests/TemplateCache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/tests/TemplateViews/blade.blade.php b/tests/TemplateViews/blade.blade.php new file mode 100644 index 0000000..553987e --- /dev/null +++ b/tests/TemplateViews/blade.blade.php @@ -0,0 +1 @@ +Hello, I'm {{ $engine }} Engine render at {{ $time }}. \ No newline at end of file diff --git a/tests/TemplateViews/plates.php b/tests/TemplateViews/plates.php new file mode 100644 index 0000000..fcdf5ac --- /dev/null +++ b/tests/TemplateViews/plates.php @@ -0,0 +1 @@ +Hello, I'm Engine render at . \ No newline at end of file diff --git a/tests/TemplateViews/smarty.tpl b/tests/TemplateViews/smarty.tpl new file mode 100644 index 0000000..59e0cba --- /dev/null +++ b/tests/TemplateViews/smarty.tpl @@ -0,0 +1 @@ +Hello, I'm {$engine} Engine render at {$time}. \ No newline at end of file diff --git a/tests/TemplateViews/think.html b/tests/TemplateViews/think.html new file mode 100644 index 0000000..59e0cba --- /dev/null +++ b/tests/TemplateViews/think.html @@ -0,0 +1 @@ +Hello, I'm {$engine} Engine render at {$time}. \ No newline at end of file diff --git a/tests/smarty.tpl b/tests/smarty.tpl deleted file mode 100644 index bb8e905..0000000 --- a/tests/smarty.tpl +++ /dev/null @@ -1 +0,0 @@ -hello smarty ,now is {$time} \ No newline at end of file diff --git a/tests/testServer.php b/tests/testServer.php new file mode 100644 index 0000000..e0880b5 --- /dev/null +++ b/tests/testServer.php @@ -0,0 +1,53 @@ + Blade::class, 'think' => Think::class, 'smarty' => Smarty::class, 'plates' => Plates::class]; +$templates = ['blade' => 'blade', 'think' => 'think', 'smarty' => 'smarty.tpl', 'plates' => 'plates']; +if (array_key_exists($name, $engines)) { + $engine = $engines[$name]; +} else { + echo "\nnot supported engine: {$name}\n\n"; + exit; +} + +/** @var RenderInterface $engine */ +$engine = new $engine($viewsDir, $cacheDir); +$config = new Config; +$config->setRender($engine); +$render = new Render($config); + +// 启动服务 +$http = new swoole_http_server("0.0.0.0", 9501); +$http->on("request", function (Request $request, Response $response) use ($engine, $templates, $name) { + $response->end($engine->render($templates[$name], [ + 'engine' => $name, + 'time' => date('Y-m-d H:i:s') + ])); +}); + +$render->attachServer($http); +echo "\ntemplate engine: {$param_arr['e']}\nlisten at: http://0.0.0.0:9501\n"; +$http->start(); \ No newline at end of file