模板引擎集成

框架秉承高度自由的理念,既可以作为API框架,也可以作为常规的全站框架,开发混合式Web服务,本例介绍了如何集成当下常用的三种模板引擎,为框架集成View层,提供渲染模板视图的能力

引擎名称 说明 仓库地址 开发参考手册
Smarty 业界最著名的PHP模板引擎之一 GitHub 官方文档
think-template ThinkPHP 5.1 官方分离的模板引擎 GitHub 官方手册
Blade Laravel的模板引擎组件 GitHub 官方手册

引入支持库

无论使用哪个模板引擎,首先都要引入模板引擎的支持库文件,我们推荐使用 Composer 进行第三方组件包的管理,请确保已经正确安装了 Composer 然后执行下面对应的命令,引入引擎的支持库包

  1. # 使用Smarty引擎
  2. composer require smarty/smarty
  3. # 使用think-template
  4. composer require topthink/think-template
  5. # 使用Blade
  6. composer require duncan3dc/blade

第三方模板引擎支持库不属于框架的维护范围,如果遇到问题,请首先考虑升级到最新版本,如果问题无法解决,请到群里求助

建立自定义控制器抽象类

为了简化渲染页面的操作,我们需要建立一个自定义的控制器抽象类,以便自动初始化模板引擎,以及对输出方法进行封装,简化操作。下面给出的三段代码例子,分别针对不同的模板引擎,请按照自己使用的引擎参照对应的代码建立抽象控制器,请注意模板引擎都需要编译缓存目录以及模板视图目录,请提前新建好对应的目录

下面所示的例子中,视图控制器抽象类都直接存放在 APP 文件夹中,如果放在其他文件夹中,请注意命名空间,确保能自动加载到文件

Smarty

  1. <?php
  2. namespace App;
  3. use EasySwoole\Config;
  4. use EasySwoole\Core\Http\AbstractInterface\Controller;
  5. use EasySwoole\Core\Http\Request;
  6. use EasySwoole\Core\Http\Response;
  7. /**
  8. * 视图控制器
  9. * Class ViewController
  10. * @author : evalor <master@evalor.cn>
  11. * @package App
  12. */
  13. abstract class ViewController extends Controller
  14. {
  15. protected $view;
  16. /**
  17. * 初始化模板引擎
  18. * ViewController constructor.
  19. * @param string $actionName
  20. * @param Request $request
  21. * @param Response $response
  22. */
  23. function __construct(string $actionName, Request $request, Response $response)
  24. {
  25. $this->view = new \Smarty();
  26. $tempPath = Config::getInstance()->getConf('TEMP_DIR'); # 临时文件目录
  27. $this->view->setCompileDir("{$tempPath}/templates_c/"); # 模板编译目录
  28. $this->view->setCacheDir("{$tempPath}/cache/"); # 模板缓存目录
  29. $this->view->setTemplateDir(EASYSWOOLE_ROOT . '/Views/'); # 模板文件目录
  30. $this->view->setCaching(false);
  31. parent::__construct($actionName, $request, $response);
  32. }
  33. /**
  34. * 输出模板到页面
  35. * @param string|null $template 模板文件
  36. * @author : evalor <master@evalor.cn>
  37. * @throws \Exception
  38. * @throws \SmartyException
  39. */
  40. function fetch($template = null)
  41. {
  42. $content = $this->view->fetch($template);
  43. $this->response()->write($content);
  44. $this->view->clearAllAssign();
  45. $this->view->clearAllCache();
  46. }
  47. /**
  48. * 添加模板变量
  49. * @param array|string $tpl_var 变量名
  50. * @param mixed $value 变量值
  51. * @param boolean $nocache 不缓存变量
  52. * @author : evalor <master@evalor.cn>
  53. */
  54. function assign($tpl_var, $value = null, $nocache = false)
  55. {
  56. $this->view->assign($tpl_var, $value, $nocache);
  57. }
  58. }

Think-Template

  1. <?php
  2. namespace App;
  3. use EasySwoole\Config;
  4. use EasySwoole\Core\Http\AbstractInterface\Controller;
  5. use EasySwoole\Core\Http\Request;
  6. use EasySwoole\Core\Http\Response;
  7. use think\Template;
  8. /**
  9. * 视图控制器
  10. * Class ViewController
  11. * @author : evalor <master@evalor.cn>
  12. * @package App
  13. */
  14. abstract class ViewController extends Controller
  15. {
  16. protected $view;
  17. /**
  18. * 初始化模板引擎
  19. * ViewController constructor.
  20. * @param string $actionName
  21. * @param Request $request
  22. * @param Response $response
  23. */
  24. function __construct(string $actionName, Request $request, Response $response)
  25. {
  26. $this->view = new Template();
  27. $tempPath = Config::getInstance()->getConf('TEMP_DIR'); # 临时文件目录
  28. $this->view->config([
  29. 'view_path' => EASYSWOOLE_ROOT . '/Views/', # 模板文件目录
  30. 'cache_path' => "{$tempPath}/templates_c/", # 模板编译目录
  31. ]);
  32. parent::__construct($actionName, $request, $response);
  33. }
  34. /**
  35. * 输出模板到页面
  36. * @param string|null $template 模板文件
  37. * @param array $vars 模板变量值
  38. * @param array $config 额外的渲染配置
  39. * @author : evalor <master@evalor.cn>
  40. */
  41. function fetch($template, $vars = [], $config = [])
  42. {
  43. ob_start();
  44. $this->view->fetch($template, $vars, $config);
  45. $content = ob_get_clean();
  46. $this->response()->write($content);
  47. }
  48. }

Blade

  1. <?php
  2. namespace App;
  3. use EasySwoole\Config;
  4. use EasySwoole\Core\Http\AbstractInterface\Controller;
  5. use EasySwoole\Core\Http\Request;
  6. use EasySwoole\Core\Http\Response;
  7. use duncan3dc\Laravel\BladeInstance;
  8. /**
  9. * 视图控制器
  10. * Class ViewController
  11. * @author : evalor <master@evalor.cn>
  12. * @package App
  13. */
  14. abstract class ViewController extends Controller
  15. {
  16. protected $view;
  17. /**
  18. * 初始化模板引擎
  19. * ViewController constructor.
  20. * @param string $actionName
  21. * @param Request $request
  22. * @param Response $response
  23. */
  24. function __construct(string $actionName, Request $request, Response $response)
  25. {
  26. $tempPath = Config::getInstance()->getConf('TEMP_DIR'); # 临时文件目录
  27. $this->view = new BladeInstance(EASYSWOOLE_ROOT . '/Views', "{$tempPath}/templates_c");
  28. parent::__construct($actionName, $request, $response);
  29. }
  30. /**
  31. * 输出模板到页面
  32. * @param string $view
  33. * @param array $params
  34. * @author : evalor <master@evalor.cn>
  35. */
  36. function render(string $view, array $params = [])
  37. {
  38. $content = $this->view->render($view, $params);
  39. $this->response()->write($content);
  40. }
  41. }

进行模板渲染

建立一个测试控制器进行模板渲染,请提前建立好模板文件,这里假设你已经有了一个index模板文件

  1. <?php
  2. namespace App\HttpController;
  3. use App\ViewController;
  4. /**
  5. * Class Index
  6. * @author : evalor <master@evalor.cn>
  7. * @package App\HttpController
  8. */
  9. class Index extends ViewController
  10. {
  11. function index()
  12. {
  13. // Blade View
  14. $this->render('index'); # 对应模板: Views/index.blade.php
  15. // Think-Template
  16. $this->fetch('index'); # 对应模板: Views/index.html
  17. // Smarty
  18. $this->fetch('index.html'); # 对应模板: Views/index.html
  19. }
  20. }

静态资源文件处理

由于 URL Dispatcher 的解析,直接使用 Swoole 作为HTTP服务器,在默认情况下并不能处理静态文件的返回,需要编辑全局配置文件,加入额外的配置项如下:

  1. <?php
  2. return [
  3. 'MAIN_SERVER' => [
  4. 'HOST' => '0.0.0.0',
  5. 'PORT' => 9501,
  6. 'SERVER_TYPE' => \EasySwoole\Core\Swoole\ServerManager::TYPE_WEB_SERVER,
  7. 'SOCK_TYPE' => SWOOLE_TCP,
  8. 'RUN_MODEL' => SWOOLE_PROCESS,
  9. 'SETTING' => [
  10. 'worker_num' => 8, // worker进程
  11. 'max_request' => 5000, // 执行5000次后重启worker进程
  12. 'task_worker_num' => 8, // 异步任务进程
  13. 'task_max_request' => 10, // 执行10次后重启task进程
  14. // 加入以下两条配置以返回静态文件
  15. 'document_root' => EASYSWOOLE_ROOT.'/Public', // 静态资源目录
  16. 'enable_static_handler' => true,
  17. ],
  18. ]
  19. // 以下配置省略.......
  20. ];

注意静态资源目录需要提前新建好 改为自己的目录 !!!不要直接复制!!!

前端服务器

由于 Swoole Server 对 HTTP 协议的支持并不完整,建议仅将 EasySwoole 作为后端服务,并且在前端增加 NGINX 或 APACHE 作为代理,参照下面的例子添加转发规则

NGINX

  1. server {
  2. root /data/wwwroot/;
  3. server_name local.swoole.com;
  4. location / {
  5. proxy_http_version 1.1;
  6. proxy_set_header Connection "keep-alive";
  7. proxy_set_header X-Real-IP $remote_addr;
  8. if (!-e $request_filename) {
  9. proxy_pass http://127.0.0.1:9501;
  10. }
  11. }
  12. }

APACHE

  1. <IfModule mod_rewrite.c>
  2. Options +FollowSymlinks
  3. RewriteEngine On
  4. RewriteCond %{REQUEST_FILENAME} !-d
  5. RewriteCond %{REQUEST_FILENAME} !-f
  6. #RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] fcgi下无效
  7. RewriteRule ^(.*)$ http://127.0.0.1:9501/$1 [QSA,P,L]
  8. #请开启 proxy_mod proxy_http_mod request_mod
  9. </IfModule>