<?php class DataObject { private $changedFields = array(); // 更新了的欄位列表 private $data = array(); // 從PDO取得的一條記錄 // 以上幾個欄位都是本類私有的,因此子類即便是定義同名的屬性 // 或者將同名屬性關聯到數據表的某個欄位中,也絲毫不會影響本類的這些變量 function __get($property) { if (isset($this::$_propertyList[$property])) { return $this->data[$this::$_propertyList[$property]]; // 根據PHP屬性名直接訪問欄位 } else { return $this->$property; // 如果沒有對應的屬性,則顯示PHP默認的錯誤信息 } } function __set($property, $value) { if (isset($this::$_propertyList[$property])) { $field = $this::$_propertyList[$property]; $this->data[$field] = $value; // 更新$_data[欄位名]的值 // 記錄更新了的欄位 if (!in_array($field, $this->changedFields)) { array_push($this->changedFields, $field); } } else { $this->data[$property] = $value; // 將不存在的屬性全部統一存入$_data } } public function delete() { } public function insert() { global $dbh; if (empty($this->changedFields)) { $stmt = $dbh->prepare('INSERT INTO ' . $this::$_table['name'] . ' VALUES ()'); $rs = $stmt->execute(); } else { $fields = join(', ', $this->changedFields); $placeholders = str_repeat('?, ', count($this->changedFields) - 1) . '?'; $sql = 'INSERT INTO ' . $this::$_table['name'] . " ($fields) VALUES ($placeholders)"; $stmt = $dbh->prepare($sql); $param = 1; foreach ($this->changedFields as $field) { $stmt->bindValue($param++, $this->data[$field]); } $rs = $stmt->execute(); } if ($rs) { $this->changedFields = array(); // 獲取生成的主鍵欄位 if (is_string($this::$_table['key'])) { $this::$_table['key'] = array($this::$_table['key']); } $sql = 'SELECT ' . join(', ', $this::$_table['key']) . ' FROM ' . $this::$_table['name']; } return $rs; } public function update() { global $dbh; if (empty($this->changedFields) || empty($this::$_table['key'])) { return false; } // 禁止直接更新主鍵欄位,如果必須要更新主鍵欄位,請手動執行SQL語句 if (is_string($this::$_table['key'])) { $this::$_table['key'] = array($this::$_table['key']); } if (array_intersect($this->changedFields, $this::$_table['key'])) { trigger_error("Forbidden to update the primary key of a row", E_USER_WARNING); return false; } $sql = 'UPDATE ' . $this::$_table['name'] . ' SET '; $sql .= join(' = ?, ', $this->changedFields) . ' = ? WHERE '; $sql .= join(' = ? AND ', $this::$_table['key']) . ' = ?'; $stmt = $dbh->prepare($sql); $param = 1; foreach ($this->changedFields as $field) { $stmt->bindValue($param++, $this->data[$field]); } foreach ($this::$_table['key'] as $key) { $stmt->bindValue($param++, $this->data[$key]); } $rs = $stmt->execute(); if ($rs) { $this->changedFields = array(); // 若成功就清空欄位列表 } return $rs; } }
// 相冊類 class Album extends DataObject { protected static $_table = array('name' => 'Albums', 'key' => 'AlbumID'); // 設置PHP類對應的數據表的名稱,以及數據表里所有主鍵的欄位名稱 protected static $_propertyList = array('id' => 'AlbumID', 'artist' => 'AlbumArtist', 'title' => 'AlbumTitle'); // PHP類屬性名與數據表欄位名的對應關係 // 獲取前$num個相冊對象的靜態方法 public static function GetSomeAlbums($num) { global $dbh; // 調用外部變量$dbh $arr = array(); $sql = "SELECT * FROM Albums WHERE AlbumID <= $num"; $stmt = $dbh->query($sql); while ($album = $stmt->fetchObject('Album')) { $arr[] = $album; } return $arr; } // 獲取指定標題的相冊的靜態方法 // 成功時返回Album對象,失敗時返回NULL public static function GetAlbumByTitle($title) { global $dbh; $sql = "SELECT * FROM Albums WHERE AlbumTitle = ?"; $stmt = $dbh->prepare($sql); $stmt->bindValue(1, $title); $stmt->execute(); return $stmt->fetchObject('Album'); } }
$dbh = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'test', DB_PASSWORD);
$some = Album::GetSomeAlbums(6); // 獲取前6個相冊 echo 'Num: ', count($some), '<br>'; echo $some[1]->title, '<br>'; // ->title被魔術方法_get自動重定向到->data['AlbumTitle'] echo $some[2]->artist, '<br>'; // ->artist被魔術方法_get自動重定向到->data['AlbumArtist']
// 請不要直接通過DataObject更新主鍵欄位 $some[1]->id = 100; $some[1]->update(); // 若要更新主鍵欄位,請手動執行SQL語句 // 因為DataObject在更新記錄時依賴於主鍵欄位 $sql = 'UPDATE Albums SET AlbumID = 100 WHERE AlbumID = ' . $some[2]->id; //echo $sql, '<br>';
// 獲取指定標題的相冊 $dream = Album::GetAlbumByTitle('In My Dreams'); echo '<br>', $dream->artist, '<br>'; $abc = Album::GetAlbumByTitle('abc'); // 獲取一個不存在的相冊 if (!$abc) { echo 'No such album!!!<br>'; }
// 添加一個相冊 /*$album = new Album(); $album->title = 'test title'; // 基類DataObject會自動記錄更新了哪些欄位 $album->artist = 'test artist'; if ($album->insert()) { printf('Inserted! ID = %d<br>', $album->id); }*/
/* // 添加空白相冊記錄 $album = new Album(); $album->insert(); */
/*$stmt = $dbh->query('SELECT * FROM Albums WHERE AlbumID = 6'); $album = $stmt->fetchObject('Album'); // 所有的數據都會自動存入data數組中 if ($album) { print_r($album); // 輸出$album對象的結構 echo '<br><b>Title: </b>'; echo $album->title; // 更新欄位 if ($album->title != 'New Title') { $album->title = 'New Title'; if ($album->update($dbh)) { echo '<p>Updated</p>'; } } } else { // 記錄不存在 echo 'No such record!'; }*/ ?>
|