发新话题
打印

[强推] Zend Framework 留言本实战 -- 显示留言列表

本主题由 tomsou 于 2008-4-7 17:36 设置高亮

[强推] Zend Framework 留言本实战 -- 显示留言列表

五、显示留言列表

      在留言本这个应用中,我们设计以下功能:留言列表(分页)、新增留言、删除(管理员登陆后)。首先我们来看显示留言列表这个功能。

       5.1 概括梳理
      经过前面的学习,应该对ZF现MVC的套路有了一些了解了,那么要显示留言列表我们的程序涉及到哪些方面,如果通过ZF提高的MVC框架来实现呢?当访问留言本应用时,我们在首页显示留言列表,并在页面最下方显示新增留言的表单。既然时首页,那么我们的控制器就命名为IndexController.php,当然是存放在/application/controllers目录下面了;紧接着是模型层,既然是显示留言,肯定是gb_message表,那么我们把模型层命名为Message.php(与表明相关联,便于识别),存放在/application/models目录下;最后是视图层,那就是我们的模板页面了,模板页面推荐与控制器同名,即index.phtml,存放在/application/views/scripts/index目录下(这里需要在scripts目录下根据控制器名称建立子目录,便于通过ZF无路径调用并更好的管理模板文件)。现在我们来一起梳理下相关的文件和目录:
      /application/controllers/IndexController.php          控制器层
      /application/models/Message.php                       模型层
       /application/views/scripts/index                           视图层

      以下部分当然是编写三个文件的源代码了,我将会把源代码详细列下,并配上详细说明,有问题的可以留言!

      5.2 代码及注释
      IndexController.php
<?php
//控制器必须继承自Zend_Controller_Action类
class IndexController extends Zend_Controller_Action
{
      //初始化函数,相当于PHP5类中的construct函数,会在类初始化时自动调用
      function init()
     {
            //初始化视图层,并获取应用根路径赋值给视图层
            $this->initView();
            $this->view->baseUrl = $this->_request->getBaseUrl();

            //加载模型类,就是数据库操作类,放在init函数中加载的好处是不用在具体的xxxAction函数中分别加载
            Zend_Loader::loadClass('Message');
      }

      //Action方法,负责执行具体的任务
      function indexAction()
      {
            //定义每页显示的记录条数
            $psize = 10;

            //获取当前页码,如果不为正整数则重新赋值为1
            $page = (int)$this->_request->getParam('page');    //注意,这就是ZF中获取get参数的方法,下面会总结
            if($page<1){$page = 1;}
      
             //初始化Message类并获取留言分页列表数据。listMessage函数接收两个参数,分别是每页记录数和当前页码
            $message = new Message();
            $count = $message->countAll();
            $list = $message->listMessage($psize, $page);
            
            //生成分页页码链接,为了简化起见,将所有页码一股脑儿显示出来
             $pstr = "";
             $maxpage = ceil($count/$psize);
             for($i=1; $i<=$maxpage; $i++)
            {
                  if ($page==$i)
                   {
                         $pstr .= "<b>{$i}</b>";
                   }
                   else
                   {
                         $pstr .= "<a href='/index/page/{$i}>{$i}</a>";
                   }
             }
            
            //向视图层赋值并输出视图
            $this->view->title = "留言本@ZF Powered"; //将页面标题(html中的title标签)赋值给视图层
            $this->view->list = $list;
            $this->view->page = $pstr;
            $this->render();    //输出视图
      }

      //析构函数,注销不再需要的资源,可选(PHP5会自动回收)
      function __destruct()
      {
            unset($this->view);
      }
}
?>
*****************IndexController涉及到的知识点总结*********************
(1)init函数,控制器的初始化函数,相当于类的构造函数,会在初始化是自动调用,因此最好将整个控制器公用的一些资源放在这个函数中,比如一些公用类的加载和初始化、全局的变量等。
(2)Action函数,实际上是一些形如xxxAction的函数,每一个Action函数负责执行一个具体的请求(或者说任务),这个函数名称中的xxx就是由 http://localhost/xxx 中的xxx,不明白的可以看看ZF的URL解析规则,前面有讲到。
(3)ZF获取参数的方法:get参数==$this->_request->getParam('xxx');,post参数==$this->_request->getPost('xxx');,$this当然是指向当前控制器的。
(4)向视图层赋值。如果在init函数中执行了$this->initView();,则直接调用$this->view->变量名=值;就行了。实际上initView()就是建立一个新的视图实例并赋值给控制器的变量view(当然还有其它相关的操作)。
(5)视图输出。如果严格按照ZF推荐的方式进行目录安排和命名,则显示视图只需调用$this->render();,这样ZF会自动在/application/views/scripts/目录下查找和当前控制器名称同名的目录下的和当前action同名的.phtml文件作为模板显示输出。

      Message.php
<?php
//模型类,必须继承自Zend_Db_Table
class Message extends Zend_Db_Table
{
      //默认情况下,zend_db_table类会将其类名当作数据库中表名,不是则重新定义,详见ZF手册
      protected $_name = 'gb_message';

      //重构主键,本例中不需使用,ZF默认表的主键为id,如果不是则重新定义,便于Db类的一些便捷操作,详见ZF手册
      protected $_primary = 'mess_id';

      //构造函数,获取在入口文件中注册的数据库连接对象
      function __construct()
      {
            parent::__construct();
            $this->db = Zend_Registry::get('db');
      }

      //获取数据总量供分页使用,以下用到Db::select对象,详细请参看ZF手册
      function countAll()
      {
            $select = $this->db->select();
            $select->from($this->_name, 'mess_id');
            $count = count($this->db->fetchAll($select));
            if($count)
            {
                  return $count;
            }
            return 0;
      }

      //获取分页后数据,注意最好给参数制定默认值
      function listMessage($page=1,$count=20)
      {
            $select = $this->db->select();

            //制定表和获取字段列表
            $select->from($this->_name,'*');
            
            //制定排序依据
            $select->order('mess_addtime DESC');

            //分页获取数据并返回
            $select->limitPage($page,$count);
            return $this->db->fetchAll($select);
      }

      //删除留言
      function delMessage($mess_id)
      {
            //使用$this->db->quoteInto来生成sql语句防止sql注入
            $where = $this->db->quoteInto('mess_id =?',$mess_id);
            $this->db->delete($this->_name,$where);
      }
}
?>
*****************Message涉及到的知识点总结*********************
(1)ZF框架Db类表名、主键等相关命名规则和操作,比较对,在本教程中就不再赘述,自己去看ZF手册吧,讲的很清楚。
(2)Db::select对象,为我们提高了一种不受数据库约束构建select的sql语句的工具,详见ZF手册9.2。
(3)ZF提高的防sql注入的方法,安全一定要注意,ZF提供了quote方法和quoteInto方法来帮助构造sql语句,详细请看下ZF手册“第 9 章 Zend_Db”。
      PS:大家不要嫌我懒,老是说“见ZF手册”,实际上是因为手册上已经讲解的很详细了,在这里就不需要赘述了,而且本教程是实例教程,偏向于实践,条条款款的东西就少写了。

      index.phtml
//be continue       今天累了,明天接着写吧

[ 本帖最后由 tomsou 于 2008-4-7 17:29 编辑 ]

TOP

LZ辛苦了。好文章。我看过以后茅塞顿开啊

TOP

lz怎么不写了,还等着你的index.phtml呢

TOP

正在学习,希望楼主继续写下去,正在期待、、、、、、、、

TOP

发新话题