面向對象編程(OOP)是現代 PHP 開發的基石。PHP 4 起已提供良好 OOP 支持,善用封裝、繼承、多態能讓代碼更模組化、可復用、易維護。本文通過構建一個跨資料庫的抽象層實例,演示 OOP 在實戰中的威力。
PHP 原生提供 mysql_*、pgsql_*、oci_* 等專用函數族,雖效率高但耦合嚴重。更換資料庫意味著全站代碼重寫,移植性極差。
定義統一介面 SQL 類,具體資料庫操作委託給驅動子類實現:
class SQL {
var $Driver; // 具體驅動實例
var $connection; // 連接資源
function DriverRegister($d) { /* 動態載入驅動文件並實例化 */ }
function Connect($host,$user,$passwd,$database) { /* 統一連接入口 */ }
function Close() { /* 統一關閉 */ }
function Query($queryStr) { /* 統一查詢 */ }
function getRows($res) { /* 統一取結果集 */ }
function getRowsNum($res) { /* 統一取行數 */ }
}
文件名 MySQL.php,類名 MySQL,放置於 include_path 目錄:
class MySQL {
var $host, $user, $passwd, $database;
function MySQL() { /* 構造函數初始化屬性 */ }
function Connect() {
$conn = mysql_connect($this->host, $this->user, $this->passwd)
or die("Could not connect to {$this->host}");
mysql_select_db($this->database, $conn)
or die("Could not switch to database {$this->database}");
return $conn;
}
function Close($conn) { mysql_close($conn); }
function Query($queryStr, $conn) {
$res = mysql_query($queryStr, $conn)
or die("Could not query database");
return $res;
}
function getRows($res) { /* 封裝 mysql_fetch_row 循環 */ }
function getRowsNum($res) { return mysql_num_rows($res); }
}
include("SQL.php");
$sql = new SQL();
if ($sql->DriverRegister("MySQL")) {
$sql->Connect("localhost", "root", "", "test");
$res = $sql->Query("select * from test");
$rowsnum = $sql->getRowsNum($res);
if ($rowsnum > 0) {
$rows = $sql->getRows($res);
foreach ($rows as $row) {
foreach ($row as $field) print $field;
}
}
$sql->Close();
}
新增 PostgreSQL 支持只需編寫 PostgreSQL.php 實現同名介面,業務代碼 零修改 即可切換。同理可擴展 SQLite、Oracle 等任意資料庫。
實戰中可進一步運用:
掌握 OOP 精髓,靈活組合設計模式,你的 PHP 專案將具備企業級的架構彈性與維護優勢。