首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

Zend Framework 資料庫操作實戰:Zend_Db_Table CRUD、關聯查詢、分頁完整範例

     編輯:PHP 綜合知識

前言:Zend_Db_Table 核心定位

Zend_Db_Table 實現 Table Data Gateway 模式,封裝單表 CRUD、關聯查詢、Row/Rowset 物件映射。本文示範:資料庫設定、Model 建立、Controller 實作增刪改查、View 顯示與分頁,並說明 Zend_Db_Select 進階查詢技巧。

一、資料庫設定 (application.ini)

resources.db.adapter = PDO_MYSQL
resources.db.params.host = localhost
resources.db.params.username = root
resources.db.params.password = secret
resources.db.params.dbname = zf1demo
resources.db.params.charset = utf8
resources.db.isDefaultTableAdapter = true

Bootstrap 會自動初始化 Zend_Db_Table::setDefaultAdapter()。

二、建立 Model (application/models/Message.php)

class Message extends Zend_Db_Table_Abstract {
    protected $_name = 'message';
    protected $_primary = 'id';
    protected $_rowClass = 'Message_Row'; // 可選:自定義 Row 類
}

對應資料表:

CREATE TABLE message (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(200) NOT NULL,
    content TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

三、Controller 實作 CRUD (IndexController)

class IndexController extends Zend_Controller_Action {
    public function init() {
        $this->view->baseUrl = $this->_request->getBaseUrl();
    }

    // 列表 + 分頁
    public function indexAction() {
        $table = new Message();
        $page = (int)$this->_getParam('page', 1);
        $perPage = 10;
        $select = $table->select()->order('created_at DESC');
        $paginator = Zend_Paginator::factory($select);
        $paginator->setCurrentPageNumber($page)
                  ->setItemCountPerPage($perPage)
                  ->setPageRange(5);
        $this->view->paginator = $paginator;
    }

    // 新增
    public function addAction() {
        if ($this->getRequest()->isPost()) {
            $data = $this->_getAllParams();
            // 簡易過濾
            $filter = new Zend_Filter_StripTags();
            $data = array_map([$filter, 'filter'], $data);
            $table = new Message();
            $table->insert([
                'title' => $data['title'],
                'content' => $data['content'],
            ]);
            $this->_helper->flashMessenger('新增成功');
            $this->_redirect('/');
        }
        // GET 顯示表單
    }

    // 編輯
    public function editAction() {
        $id = (int)$this->_getParam('id');
        $table = new Message();
        if ($this->getRequest()->isPost()) {
            $data = $this->_getAllParams();
            $filter = new Zend_Filter_StripTags();
            $data = array_map([$filter, 'filter'], $data);
            $where = $table->getAdapter()->quoteInto('id = ?', $id);
            $table->update([
                'title' => $data['title'],
                'content' => $data['content'],
            ], $where);
            $this->_helper->flashMessenger('更新成功');
            $this->_redirect('/');
        } else {
            $row = $table->find($id)->current();
            if (!$row) { $this->_redirect('/'); }
            $this->view->row = $row;
        }
    }

    // 刪除
    public function deleteAction() {
        $id = (int)$this->_getParam('id');
        if ($id > 0) {
            $table = new Message();
            $where = $table->getAdapter()->quoteInto('id = ?', $id);
            $table->delete($where);
            $this->_helper->flashMessenger('刪除成功');
        }
        $this->_redirect('/');
    }
}

四、View 腳本

index.phtml (列表 + 分頁)

paginator as $row): ?>
ID標題建立時間操作
id; ?> escape($row->title); ?> created_at; ?> 編輯 刪除

新增留言

add.phtml / edit.phtml (表單)



返回列表

partials/pagination.phtml (分頁局部)

五、進階查詢:Zend_Db_Select

$select = $table->select()
    ->from($table, ['id', 'title', 'created_at'])
    ->where('title LIKE ?', '%關鍵字%')
    ->order('created_at DESC')
    ->limitPage($page, $perPage); // 等同 limit/offset

// 關聯查詢 (假設有 user 表)
$select->setIntegrityCheck(false) // 允許 JOIN 產生非 Table 行物件
    ->joinLeft('user', 'message.user_id = user.id', ['username' => 'name']);

六、Row / Rowset 物件操作

  • $row = $table->find($id)->current() 取得單筆 Zend_Db_Table_Row,可直接 $row->title = '新標題'; $row->save();
  • $rowset = $table->fetchAll($select) 取得 Zend_Db_Table_Rowset,可 foreach ($rowset as $row) 迭代。
  • Row 物件支援 toArray()、setFromArray()、delete()。

七、常見錯誤與最佳實踐

結語

Zend_Db_Table 提供「表模型物件化、查詢物件化、結果物件化」的優雅體驗。掌握 insert/update/delete/find/fetchAll、Zend_Db_Select 鏈式語法、Zend_Paginator 整合、Row/Rowset 操作,即可高效完成多數資料庫需求。遷移至 ZF2/3 (Laminas\Db) 或 Doctrine/PDO 時,Table Gateway、Query Builder、Entity Manager 概念一脈相承。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
問題原因解決
SQL 注入風險直接拼接字串永遠使用 quoteInto()、Zend_Db_Select 參數綁定
更新/刪除影響 0 行Where 條件型別不符 (字串 vs 整數)確保 (int)$id、quoteInto('id = ?', $id)
分頁總筆數慢大表 COUNT(*) 全掃建立覆蓋索引、使用近似計數、或快取總數
關聯查詢無法存回JOIN 產生唯讀 RowsetsetIntegrityCheck(false) 僅供讀取,寫入請操作原 Table