现在的位置: 首页 > 综合 > 正文

4、综合使用model,modelmapper,db_table,controller操作数据库中的数据表

2014年04月05日 ⁄ 综合 ⁄ 共 5803字 ⁄ 字号 评论关闭

【新建数据库、数据表,以及插入测试数据】

这一步比较简单,大家可以用我提供的sql语句在phpmyadmin中建立数据库zf以及guestbook数据表

(1)建立数据表代码如下:

CREATE TABLE IF NOT EXISTS `guestbook` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(32) NOT NULL DEFAULT 'noemail@test.com',
  `comment` text,
  `created` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

(2)插入测试数据的sql语句如下:

INSERT INTO `guestbook` (`id`, `email`, `comment`, `created`) VALUES
(1, 'ralph.schindler@zend.com', 'Hello! Hope you enjoy this sample zf application!', '2012-03-22 00:00:00'),
(2, 'foo@bar.com', 'Baz baz baz, baz baz Baz baz baz - baz baz baz.', '2012-03-20 00:00:00');

【在application.ini中配置数据库信息】

resources.db.adapter = "PDO_MYSQL"
resources.db.params.host = "localhost"
resources.db.params.username = "root"
resources.db.params.password = ""
resources.db.params.dbname = "zf"

ps:这里的数据库信息要配置在【production】节点下

【使用zf create db-table在命令行中创建db-table,即数据源(data source)】如下图

在这里说明几点比较重要的内容

(1)zf create db-table Guestbook guestbook

Guestbook表示的是这个db-table的名字

guestbook表示的是实际数据表的名字。我们后面的model,modelmapper也遵循这样的规范,只是为了能够连接到数据库里的数据表上

(2)刚才新建的db-table内容如下

<?php

class Application_Model_DbTable_Guestbook extends Zend_Db_Table_Abstract
{
    protected $_name = 'guestbook';
}

这里定义的$_name,表示连接到的数据表的名字

【使用命令行zf create model 新建modelMapper】,并补齐代码如下

<?php

class Application_Model_GuestbookMapper
{
    protected $_dbTable;

    public function setDbTable($dbTable)
    {
        if (is_string($dbTable)) {
            $dbTable = new $dbTable();
        }
        if (!$dbTable instanceof Zend_Db_Table_Abstract) {
            throw new Exception('Invalid table data gateway provided');
        }
        $this->_dbTable = $dbTable;
        return $this;
    }
 
    public function getDbTable()
    {
        if (null === $this->_dbTable) {
            $this->setDbTable('Application_Model_DbTable_Guestbook');
        }
        return $this->_dbTable;
    }

     public function save(Application_Model_Guestbook $guestbook)
    {
        $data = array(
            'email'   => $guestbook->getEmail(),
            'comment' => $guestbook->getComment(),
            'created' => date('Y-m-d H:i:s'),
        );
 
        if (null === ($id = $guestbook->getId())) {
            unset($data['id']);
            $this->getDbTable()->insert($data);
        } else {
            $this->getDbTable()->update($data, array('id = ?' => $id));
        }
    }
 
    public function find($id, Application_Model_Guestbook $guestbook)
    {
        $result = $this->getDbTable()->find($id);
        if (0 == count($result)) {
            return;
        }
        $row = $result->current();
        $guestbook->setId($row->id)
                  ->setEmail($row->email)
                  ->setComment($row->comment)
                  ->setCreated($row->created);
    }
 
    public function fetchAll()
    {
        $resultSet = $this->getDbTable()->fetchAll();
        $entries   = array();
        foreach ($resultSet as $row) {
            $entry = new Application_Model_Guestbook();
            $entry->setId($row->id)
                  ->setEmail($row->email)
                  ->setComment($row->comment)
                  ->setCreated($row->created);
            $entries[] = $entry;
        }
        return $entries;
    }

}

在这里说明几点重要的内容

(1)本质上这也是一个model,我习惯上称它为modelmapper,这个modelmapper的主要作用是将我们后面要建立的Application_Model_Guestbookl和我们在上一步建立的数据源(data source)对应起来。

注意到了吗?这个model有一个protected $_dbTable的字段,而且这个modelmapper的3个对外的方法save()、find()、fetchAll()都接受了一个Application_Model_Guestbook类型的参数,这个参数就是我们下面要建立的,和数据表真正对应的model。

【使用命令行zf create model Guestbook建立和数据表真正对应的model】

<?php

class Application_Model_Guestbook
{
    protected $_comment;
    protected $_created;
    protected $_email;
    protected $_id;
 
    public function __construct(array $options = null)
    {
        if (is_array($options)) {
            $this->setOptions($options);
        }
    }

    public function setOptions(array $options)
    {
        $methods = get_class_methods($this);
        foreach ($options as $key => $value) {
            $method = 'set' . ucfirst($key);
            if (in_array($method, $methods)) {
                $this->$method($value);
            }
        }
        return $this;
    }
 
    public function __set($name, $value)
    {
        $method = 'set' . $name;
        if (('mapper' == $name) || !method_exists($this, $method)) {
            throw new Exception('Invalid guestbook property');
        }
        $this->$method($value);
    }
 
    public function __get($name)
    {
        $method = 'get' . $name;
        if (('mapper' == $name) || !method_exists($this, $method)) {
            throw new Exception('Invalid guestbook property');
        }
        return $this->$method();
    }

    public function setComment($text)
    {
        $this->_comment = (string) $text;
        return $this;
    }
 
    public function getComment()
    {
        return $this->_comment;
    }
 
    public function setEmail($email)
    {
        $this->_email = (string) $email;
        return $this;
    }
 
    public function getEmail()
    {
        return $this->_email;
    }
 
    public function setCreated($ts)
    {
        $this->_created = $ts;
        return $this;
    }
 
    public function getCreated()
    {
        return $this->_created;
    }
 
    public function setId($id)
    {
        $this->_id = (int) $id;
        return $this;
    }
 
    public function getId()
    {
        return $this->_id;
    }
 
    
}
这里也强调几点重要的内容

(1)__construct()、setOptions()、__set()、__get()四个方法大家在以后的应用中可以照搬。因为这四个方法是在为这个model中后面的所有方法做个铺垫。是在说明如果你以后遇得到setId($id)方法,那么就将$id的值赋值给这个类的变量"protected $_id"即可。

(2)保持这里类变量和数据表中字段的一致性

【使用命令行新建controller】,并完善indexAction()方法,如下

<?php

class GuestbookController extends Zend_Controller_Action
{

    public function init()
    {
        /* Initialize action controller here */
    }

    public function indexAction()
    {
        $guestbook = new Application_Model_GuestbookMapper();
        $this->view->entries =$guestbook->fetchAll();
    }
}

这里说明两点内容

(1)仔细读indexAction()方法里的语句。调用我刚才说的modelMapper,而modelMapper联系了数据源和model,进而可以使用modelMapper的fetchAll(用户自定义)方法,再深一步调用数据源的fetchAll方法(这是系统内置的)来调出和这个数据源对应的model(也可以理解为数据表)中所有的数据。

(2)$this->view->entries =$guestbook->fetchAll();

这一语句将取出的结果赋值给了view的一个名字为entries变量

【在view页面输出结果到html】

这个html页面比较简单,但我还是想说明一点

你打开浏览器后看到了吗?我们上面课程中配置的layout(基本上算是导航栏)也正常的出现在了页面中,是不是感觉到很有意思了?

希望大家能够多关注我的原创博客,如果有任何疑问,可以给我留言,大家一起讨论,一起进步!

抱歉!评论已关闭.