• Zend Framework 整合 Smarty 模板引擎(ZF Study)


    <文章大部分内容取自《PHP Web 2.0 》这本书>,最近在学习这本书 ^ ^

    在使用 Zend Framework(以下简称 ZF) 框架的时候,其中的 Zend_Controller 会自动加载一个名为 ViewRenderer 的插件,它会根据所请求的控制器和动作名来显示一个视图脚本(即模板),也就是说,使用 Smarty 的时候,不用实例化 Smarty 类或者调用 display() 方法来输出模板,因为 ViewRenderer 会为我们做这些工作。

          要想让 Zend 与 Smarty 交互,我们必须扩展 Zend_View_Abstract 类从而达到我们的目的,可以创建一个 Templater 的类,之后就要在 index.php 引导文件中告诉 Zend_Controller 这个类的信息。

    先来看看应用的文件目录信息

    目录

    来简要的介绍一下:

    data:用来存放应用相关的数据文件:

    data

    htdocs:这个是应用的根目录,里面暂时只有一个 index.php 文件。(截图舍去)

    include:这里存放主要的库文件:ZF,Smarty…等一些需要“包含”的文件:(PHP 的 include_path 项已经包含了此目录)

    include

    templates:这里存放模板文件:(暂时只有一个 index 控制器模板目录)

    templates

    httpd.conf:Apache 的子配置文件。(已经包含进了 Apache 的主文件里,这里不做介绍了)

    settings.ini:站点配置文件:

    settings

    -----------------------应用文件目录信息结束,来看看如何创建 Templater 类呢?

          我们将把这个类放入应用的 include/ 文件夹中,看一下第三个截图中的 Templater.php,这就是我们将要创建的类文件。另外呢,我们还要在 include/Templater/ 文件夹中创建一个 plugins/ 的目录,就像这样:include/Templater/plugins/ ,这个目录可以用来存放所有定制 Smarty 插件,通过将我们自己的所有扩展插件存放在一个单独的目录中,可以很容易地升级到 Smarty 的最新版本,而不必总是跟踪我们的哪些文件需要移动。

          现在可以着手创建 Templater.php 了,在其中指定 Smarty 的 template_dir(模板路径)和 compile_dir(编译路径),还要告诉 Smarty ,除去自己的 plugins 目录外,还可以在 include/Templater/plugins/ 中寻找插件。

          要实现这个类,必须实现一些关键的方法,使得 ViewRenderer 能够与 Smarty 交互,其中最重要的方法如下:

    > getEngine()。此方法必须返回 Smarty 的一个实例。由于这个方法可能被调用多次,所以应当将 Smarty 实例缓存起来,这样就只需创建一次实例。为此,将在构造函数中创建 Smarty 对象;
    > __set()。此方法将一个变量赋给模板。实际上,这意味着可以在任何控制器动作中将 $smarty->assign('foo', 'bar') 替换为 $this->view->foo = 'bar'。
    > __get()。此方法返回一个先前赋给模板的变量。
    > render()。此方法显示一个模板。它的效果与调用 $smarty->display 类似,只不过这个方法要返回输出(而不会直接显示),故必须在 Smarty 对象上使用 fetch() 而不是 display()。

    下面的代码则展示了 Templater.php 的代码,注意要与 Zend 框架的类命名结构相一致,这也意味着必须将这个类放在 include/ 目录中

    Templater.php:

    <?php
        class Templater extends Zend_View_Abstract
        {
            protected $_path;
            protected $_engine;
    
            public function __construct()
            {
                $config = Zend_Registry::get('config');
    
                require_once('Smarty/Smarty.class.php');
    
                $this->_engine = new Smarty();
                $this->_engine->template_dir = $config->paths->templates;
                $this->_engine->compile_dir = sprintf('%s/tmp/templates_c',
                                                      $config->paths->data);
    
                $this->_engine->plugins_dir = array($config->paths->base .
                                                    '/include/Templater/plugins',
                                                    'plugins');
            }
    
            public function getEngine()
            {
                return $this->_engine;
            }
    
            public function __set($key, $val)
            {
                $this->_engine->assign($key, $val);
            }
    
            public function __get($key)
            {
                return $this->_engine->get_template_vars($key);
            }
    
            public function __isset($key)
            {
                return $this->_engine->get_template_vars($key) !== null;
            }
    
            public function __unset($key)
            {
                $this->_engine->clear_assign($key);
            }
    
            public function assign($spec, $value = null)
            {
                if (is_array($spec)) {
                    $this->_engine->assign($spec);
                    return;
                }
    
                $this->_engine->assign($spec, $value);
            }
    
            public function clearVars()
            {
                $this->_engine->clear_all_assign();
            }
    
            public function render($name)
            {
                return $this->_engine->fetch(strtolower($name));
            }
    
            public function _run()
            { }
        }
    ?>

    好了,我们的 Templater 类已经完成了,怎样来使用呢?我们需要让 Zend_Controller 使用 Templater 类,而不是默认的 Zend_View 类。为此,我们必须要将下面的代码加入到应用的引导文件(index.php)中:

    // setup the view renderer
    $vr = new Zend_Controller_Action_Helper_ViewRenderer();
    $vr->setView(new Templater());
    $vr->setViewSuffix('tpl');
    Zend_Controller_Action_HelperBroker::addHelper($vr);

    (关于这里的 ZF 知识,请看文章最下方的 ViewRenderer 介绍)

    注意,必须要调用 setViewSuffix() 来指示模板以文件扩展名 .tpl (或者 .htm …)结尾,默认地,Zend_View 使用 .phtml ,来看看我们现在的 bootstrap(引导文件 htdocs/index.php,即应用的引导文件):

    index.php:

    <?php
        /*Old:
        require_once('Zend/Loader.php');
        Zend_Loader::registerAutoload();
        */
        /*ZF 的自动加载机制*/
        require_once('Zend/Loader/Autoloader.php');
        $autoloader = Zend_Loader_Autoloader::getInstance();
        $autoloader->setFallbackAutoloader(true);
    	
        // load the application configuration(导入应用的配置文件)
        $config = new Zend_Config_Ini('../settings.ini', 'development');
        Zend_Registry::set('config', $config);
    
        // create the application logger(加载 ZF 的日志机制)
        $logger = new Zend_Log(new Zend_Log_Writer_Stream($config->logging->file));
        Zend_Registry::set('logger', $logger);
    
        // connect to the database(数据库配置及连接)
        $params = array('host'     => $config->database->hostname,
                        'username' => $config->database->username,
                        'password' => $config->database->password,
                        'dbname'   => $config->database->database);
    
        $db = Zend_Db::factory($config->database->type, $params);
        Zend_Registry::set('db', $db);
    
        // handle the user request(处理用户请求)
        $controller = Zend_Controller_Front::getInstance();
        $controller->setControllerDirectory($config->paths->base .
                                            '/include/Controllers');
    
        // setup the view renderer(这里是我们新加的,用来处理 ViewRenderer)
        $vr = new Zend_Controller_Action_Helper_ViewRenderer();
        $vr->setView(new Templater());
        $vr->setViewSuffix('tpl');
        Zend_Controller_Action_HelperBroker::addHelper($vr);
    
        $controller->dispatch();
    ?>

          现在,一旦执行一个控制器动作,Zend_Controller 就会根据控制器名和动作名自动查找模板。下面使用 index 控制器的 index 动作作为一个简单的测试例子:

    在我们的 include/Controllers/ (用来存放各种控制器)目录中的:IndexController.php:

    IndexController.php:

    <?php
        class IndexController extends CustomControllerAction
        {
            public function indexAction()
            {
            }
        }
    ?>

    注意:CustomControllerAction 类:

    CustomControllerAction.php:

    <?php
        class CustomControllerAction extends Zend_Controller_Action
        {
            public $db;
    
            function init()
            {
                $this->db = Zend_Registry::get('db');
            }
        }
    ?>

    相应的 index 控制器的 index 动作的模板:templates/index/index.tpl:

    index.tpl:

    {include file='header.tpl'}
    
    Web site home
    
    {include file='footer.tpl'}

    至此呢,所有的整合工作都已完成,进入应用站点看看是不是显示:

    succeed

    是的话,就整合成功了!

    --------------------------------------------------------------------------以下为附录部分:

    ViewRenderer 介绍:

    视图解析 (ViewRenderer) 助手为实现下列目标设计:

    • 不需要在控制器内创建视图对象实例;视图对象将在控制器内自动注册。

    • 根据当前的模块自动地设置视图脚本、助手、过滤器路径。指派当前的模块名为助手和过滤器类的类名前缀。

    • 为所有分发的控制器和动作创建全局有效的视图对象。

    • 允许开发人员为所有控制器设置默认的视图解析选项。

    • 加入无需干预自动解析试图脚本的功能。

    • 允许开发人员为视图基路径和视图脚本路径创建自己的规范。

    注意

    如果手动执行_forward()redirect、或者render时,不会发生自动解析。因为执行这些动作时,等于告诉 ViewRenderer,你要自己确定输出结果。

    ViewRenderer 助手默认启用。你可以通过前端控制器的 noViewRenderer 方法、设定参数 ($front->setParam('noViewRenderer', true)) 或者从助手经纪人栈 (helper broker stack) 中移除助手 (Zend_Controller_Action_HelperBroker::removeHelper('viewRenderer')) 等方式禁用该助手。

    创建实例并注册自己的 ViewRenderer 对象,然后传入到助手经纪人:

    $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
    $viewRenderer->setView($view)
                 ->setViewSuffix('php');
    Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);

    通过助手经纪人即时的初始化并/或获取ViewRenderer对象:

    $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
    $viewRenderer->setView($view)
                 ->setViewSuffix('php');

    更多相关的资料可以查看 ZF 的在线 Manual(手册):http://framework.zend.com/manual/zh/zend.controller.html



  • 相关阅读:
    ajax发送请求
    Canvas与SVG的区别
    jquery中attr()和prop()方法的区别
    ab(Apache Benchmark)测试工具的安装
    Nginx与阻塞操作
    构造函数调用顺序
    对一个类求sizeof,虚继承
    代码清单16-4 服务器压力测试程序
    libevent源码分析-TCP服务端代码
    Linux内核源码之红黑树
  • 原文地址:https://www.cnblogs.com/catprayer/p/1865860.html
Copyright © 2020-2023  润新知