本文讲述的是swoole+yaf与smarty模板的整合
首先下载smarty模板 smarty下载地址,下载完后解压到/application/library/下;然后在application下建立一个modules
文件夹,并在里面建立一个Adm模块(要在配置文件中配置其合法),在Adm在建立controllers和views文件夹 如下图所示。
然后修改conf/application.ini
[common] application.directory = APPLICATION_PATH "/application" ;项目文件 application.dispatcher.catchException = TRUE ;输出异常 application.modules= 'Index,Adm,Monitor' ;合法模块定义,例如访问http://test.com/adm/index/index 即访问Adm/index控制器下的index方法 application.ext = php ;默认脚本 application.view.ext = html ;视图默认文件形式 可以改成htm,phtml等等 [product : common] smarty.left_delimiter = "{{" ;smarty渲染标签 例如{{ $content }} 如果改成"{-" 那么渲染就是{- $content -} 很好理解的 smarty.right_delimiter = "}}" smarty.template_dir= APPLICATION_PATH "/application/modules/Adm/views/" ;模板文件目录 smarty.compile_dir= APPLICATION_PATH "/application/cache/compile" smarty.cache_dir= APPLICATION_PATH "/application/cache/"
然后在application中的Bootstrap.php(yaf默认加载库文件的文件)中配置smarty初始化
<?php /** * @name Bootstrap * @author lancelot * @desc 所有在Bootstrap类中, 以_init开头的方法, 都会被Yaf调用, * @see http://www.php.net/manual/en/class.yaf-bootstrap-abstract.php * 这些方法, 都接受一个参数:Yaf_Dispatcher $dispatcher * 调用的次序, 和申明的次序相同 */ class Bootstrap extends Yaf_Bootstrap_Abstract{ public function _initConfig() { //把配置保存起来 $arrConfig = Yaf_Application::app()->getConfig(); Yaf_Registry::set('config', $arrConfig); } public function _initPlugin(Yaf_Dispatcher $dispatcher) { //注册一个插件 $objSamplePlugin = new SamplePlugin(); $dispatcher->registerPlugin($objSamplePlugin); } public function _initRoute(Yaf_Dispatcher $dispatcher) { //在这里注册自己的路由协议,默认使用简单路由 } public function _initView(Yaf_Dispatcher $dispatcher){ //在这里注册自己的view控制器,例如smarty,firekylin Yaf_Dispatcher::getInstance()->disableView(); //因为要用smarty引擎作为渲染,所以关闭yaf自身的自动渲染功能 } public function _initSmarty(Yaf_Dispatcher $dispatcher) { Yaf_Loader::import( APPLICATION_PATH ."/application/library/smarty-3.1.32/libs/Adapter.php");//引入yaf与smarty的适配文件 $smarty = new Smarty_Adapter(null, Yaf_Application::app()->getConfig()->smarty);//实例化引入文件的类 Yaf_Dispatcher::getInstance()->setView($smarty);//渲染模板 } }
然后在library/smarty-3.1.32/libs下新建一个适配文件Adapter.php
<?php Yaf_Loader::import( APPLICATION_PATH ."/application/library/smarty-3.1.32/libs/Smarty.class.php"); //echo 'APPLICATION_PATH ."/application/library/smarty-3.1.32/libs/Smarty.class.php';exit(); Yaf_Loader::import( APPLICATION_PATH . "/application/library/smarty-3.1.32/libs/sysplugins/smarty_internal_templatecompilerbase.php"); Yaf_Loader::import( APPLICATION_PATH . "/application/library/smarty-3.1.32/libs/sysplugins/smarty_internal_templatelexer.php"); Yaf_Loader::import( APPLICATION_PATH . "/application/library/smarty-3.1.32/libs/sysplugins/smarty_internal_templateparser.php"); Yaf_Loader::import( APPLICATION_PATH . "/application/library/smarty-3.1.32/libs/sysplugins/smarty_internal_compilebase.php"); Yaf_Loader::import( APPLICATION_PATH . "/application/library/smarty-3.1.32/libs/sysplugins/smarty_internal_write_file.php"); class Smarty_Adapter implements Yaf_View_Interface /*Smarty_Adapter类为yaf与smarty之间的适配器*/ { /** * Smarty object * @var Smarty */ public $_smarty; /** * Constructor * * @param string $tmplPath * @param array $extraParams * @return void */ public function __construct($tmplPath = null, $extraParams = array()) { $this->_smarty = new Smarty; if (null !== $tmplPath) { $this->setScriptPath($tmplPath); } foreach ($extraParams as $key => $value) { $this->_smarty->$key = $value; } } /** * Return the template engine object * * @return Smarty */ public function getEngine() { return $this->_smarty; } /** * Set the path to the templates * * @param string $path The directory to set as the path. * @return void */ public function setScriptPath($path) { if (is_readable($path)) { $this->_smarty->template_dir = $path; return; } throw new Exception('Invalid path provided'); } /** * Retrieve the current template directory * * @return string */ public function getScriptPath() { return $this->_smarty->template_dir; } /** * Alias for setScriptPath * * @param string $path * @param string $prefix Unused * @return void */ public function setBasePath($path, $prefix = 'Zend_View') { return $this->setScriptPath($path); } /** * Alias for setScriptPath * * @param string $path * @param string $prefix Unused * @return void */ public function addBasePath($path, $prefix = 'Zend_View') { return $this->setScriptPath($path); } /** * Assign a variable to the template * * @param string $key The variable name. * @param mixed $val The variable value. * @return void */ public function __set($key, $val) { $this->_smarty->assign($key, $val); } /** * Allows testing with empty() and isset() to work * * @param string $key * @return boolean */ public function __isset($key) { return (null !== $this->_smarty->get_template_vars($key)); } /** * Allows unset() on object properties to work * * @param string $key * @return void */ public function __unset($key) { $this->_smarty->clear_assign($key); } /** * Assign variables to the template * * Allows setting a specific key to the specified value, OR passing * an array of key => value pairs to set en masse. * * @see __set() * @param string|array $spec The assignment strategy to use (key or * array of key => value pairs) * @param mixed $value (Optional) If assigning a named variable, * use this as the value. * @return void */ public function assign($spec, $value = null) { if (is_array($spec)) { $this->_smarty->assign($spec); return; } $this->_smarty->assign($spec, $value); } /** * Clear all assigned variables * * Clears all variables assigned to Zend_View either via * {@link assign()} or property overloading * ({@link __get()}/{@link __set()}). * * @return void */ public function clearVars() { $this->_smarty->clear_all_assign(); } /** * Processes a template and returns the output. * * @param string $name The template to process. * @return string The output. */ public function render($name, $value = NULL) { return $this->_smarty->fetch($name); } public function display($name, $value = NULL) { echo $this->_smarty->fetch($name); } }
然后在Adm的控制器新建一个文件Index.php
<?php class IndexController extends Yaf_Controller_Abstract { /** * 默认动作 * Yaf支持直接把Yaf_Request_Abstract::getParam()得到的同名参数作为Action的形参 * 对于如下的例子, 当访问http://yourhost/Test/index/index/index/name/lancelot 的时候, 你就会发现不同 */ public function indexAction() { //1. fetch query //$get = $this->getRequest()->getQuery("get", "default value"); // $get = HttpServer::$get; //2. fetch model $model = new SampleModel(); //3. assign $this->getView()->assign("name", "test"); $this->getView()->display('index/index.html');}}
然后在views新建一个index文件夹然后在里面新建一个index.html
<a>{{$content}}</a>
因为修改了php文件所以要重新启动server.php 重启以后访问你的http://test.com:9095/adm/index/index就可以看到浏览器输出test了,至此smarty与swoole_yaf的适配成功了。
在swoole中修改了php文件每一次都要重启server.php是非常麻烦的事情,可以
ps aux | grep server.php 获取进程号 kill -USR1 进程号 kill指令是意思是给进程发送信号的意思,不是只有杀死进程的意思,至于发送什么信号就看传入的参数
通过以上两条指令就可以实现平滑重启server.php,这样做的好处是不会影响到线上正在使用的用户。不然每次强制重启服务会导致数据丢失,或者客户的服务中断,是非常不好的。swoole里也有一个平滑重启的方法swoole_server->reload。
接下来在swoole可以引入静态文件,为了文件的良好管理建议在项目文件下新增一个public目录,在下面放入我们所需要引入的静态文件,然后在server.php中配置参数
$http->set([ 'worker_num' => 16, 'daemonize' => true, //开启守护进程模式,即让server.php在后台运行 'max_request' => 10000, 'enable_static_handler'=>true,//开启静态模板 'document_root' => '/home/wwwroot/swoole-yaf/' //静态模板的地址 ] );
然后在adm/view/index/index.html中引入静态文件的格式是
为什么是/public/static/test.css 这是取决于你的index.php这个入口文件在哪 <link rel="stylesheet" type="text/css" href="/public/static/test.css" />