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

Zend Framework 連接 MySQL 實戰:PDO 適配器、Registry 註冊、Model 查詢、錯誤處理

     編輯:PHP 綜合知識

前言:資料庫連線是應用的生命線

Zend Framework 透過 Zend_Db::factory() 建立適配器,支援 PDO、Mysqli 等驅動。本文示範:PDO MySQL 連線配置、註冊到 Registry 供全域存取、Model 封裝查詢、異常處理、字符集設定、連線池與持久連線考量。

一、PDO MySQL 連線配置 (index.php / Bootstrap)

$params = [
    'host' => '127.0.0.1',
    'username' => 'root',
    'password' => '123456',
    'dbname' => 'happycms',
    'charset' => 'utf8',
    'driver_options' => [
        PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES => false, // 使用原生預處理
    ],
];
$db = Zend_Db::factory('PDO_MYSQL', $params);
// 註冊到 Registry,全域可取
Zend_Registry::set('db', $db);
// 設為 Table 預設適配器
Zend_Db_Table::setDefaultAdapter($db);

二、Model 封裝查詢 (library/App/Article.php)

class App_Article {
    private $db;
    public function __construct() {
        $this->db = Zend_Registry::get('db');
    }
    public function listAll() {
        try {
            $sql = 'SELECT * FROM article ORDER BY addtime DESC';
            return $this->db->fetchAll($sql); // 回傳陣列
        } catch (Zend_Db_Exception $e) {
            // 記錄日誌、拋出自定義異常
            throw new App_Exception('查詢文章列表失敗: ' . $e->getMessage());
        }
    }
    public function findById($id) {
        $sql = 'SELECT * FROM article WHERE articleid = ?';
        return $this->db->fetchRow($sql, [$id]); // 參數綁定
    }
    public function insert($data) {
        return $this->db->insert('article', $data); // 回傳自增 ID
    }
}

三、Controller 使用 Model (ArticleController)

class ArticleController extends Zend_Controller_Action {
    private $articleModel;
    public function __construct() {
        $this->articleModel = new App_Article();
    }
    public function listAllAction() {
        try {
            $articles = $this->articleModel->listAll();
            $this->view->articles = $articles;
        } catch (App_Exception $e) {
            $this->_helper->flashMessenger($e->getMessage());
            $this->_redirect('/');
        }
    }
}

四、View 顯示 (views/scripts/article/list-all.phtml)

articles as $art): ?>
ID標題作者時間
escape($art['articletitle']); ?> escape($art['authorname']); ?>

五、進階:Zend_Db_Select 物件化查詢

$select = $this->db->select()
    ->from('article', ['articleid', 'articletitle', 'authorname', 'addtime'])
    ->where('categoryid = ?', $catId)
    ->where('status = ?', 'published')
    ->order('addtime DESC')
    ->limitPage($page, $perPage);
$rows = $this->db->fetchAll($select);

六、字符集與排序規則最佳實踐

  • 資料庫/表/欄位:CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci (支援 Emoji)。
  • 連線:SET NAMES utf8mb4 (PDO: MYSQL_ATTR_INIT_COMMAND)。
  • PHP 內部:mb_internal_encoding('UTF-8')。

七、錯誤處理與日誌

try {
    $db->query($sql);
} catch (Zend_Db_Adapter_Exception $e) {
    // 連線層面錯誤 (網路、認證)
    error_log('DB Connection Error: ' . $e->getMessage());
} catch (Zend_Db_Statement_Exception $e) {
    // SQL 執行錯誤 (語法、約束)
    error_log('SQL Error: ' . $e->getMessage() . ' | Code: ' . $e->getCode());
}

八、效能優化:Metadata 快取、持久連線、Profiling

  • Metadata 快取:Zend_Db_Table_Abstract::setDefaultMetadataCache($cache) 避免每請求 DESCRIBE TABLE。
  • 持久連線:PDO 選項 PDO::ATTR_PERSISTENT => true (PHP-FPM 下自動複用,慎用,可能導致連線洩漏)。
  • Profiler:$db->getProfiler()->setEnabled(true),開發環境分析慢查詢。

九、常見連線錯誤排查表

錯誤訊息原因解決
SQLSTATE[HY000] [2002] Connection refusedMySQL 服務未啟動/端口錯誤/防火牆service mysql start、檢查 3306、bind-address
SQLSTATE[HY000] [1045] Access denied用戶名/密碼錯誤、宿主不匹配確認 GRANT、FLUSH PRIVILEGES、host 為 % 或具體 IP
SQLSTATE[HY000] [1049] Unknown database資料庫不存在CREATE DATABASE 或檢查拼寫
PDOException: could not find driverPHP 缺 pdo_mysql 擴展apt-get install php-mysql / 編譯 --with-pdo-mysql
MySQL server has gone away長連線超時 (wait_timeout)增加 wait_timeout、使用持久連線、重連邏輯

結語

Zend Framework 資料庫層以 Zend_Db_Adapter 統一介面、Zend_Db_Select 物件化 SQL、Zend_Db_Table 表模型封裝,提供優雅的資料存取體驗。核心要點:**PDO 驅動 + 參數綁定 + Registry 全域適配器 + Table 預設適配器 + Metadata 快取 + 異常分層處理**。遷移至 Laminas\Db、Doctrine DBAL、Laravel Eloquent 時,適配器→Connection、Select→QueryBuilder、Table→Repository/Entity,架構思想一脈相承。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved