要用PHP操作一個數據庫很簡單,相應入門後的PHPER都可以做到,但是在應對大量的表操作時,我們為許多的MYSQL語句感到厭煩,所以我們急切想要把大量數據庫操作封裝起來。所以就出現了數據庫對象映射。
首先我們新建一個接口。
singleton.class.php
[php]
<?php
/**
* @author tomyjohn
* @link
* @license
* @version 1.0
* @copyright Copyright 2010 tomyjohn - tomyjohn.gicp.net
* @package singleton
*/
/**
* 數據庫對象
*/
interface singleton{
/**
* 生成數據庫對象
* @returns object data object;
* @access public
*/
public static function getInstance();
}
再新建一個抽象類,這個抽象類把所有的數據庫都簡明地用5個方法來抽象。
db.class.php
[php]
<?php
/**
* @author tomyjohn
* @link
* @license
* @version 1.0
* @copyright Copyright 2010 tomyjohn - tomyjohn.gicp.net
* @package db
*/
/**
*抽象DB類
*/
abstract class db{
/**
* 工廠模式
* @param string $type sql type
* @returns object
* @access public
*/
public static function factory($type){
return call_user_func(array($type,'getInstance'));
}
/**
* 執行SQL語句
* @param string $query sql 語句
* @return object resource or false;
* @access public
*/
abstract public function execute($query);
/**
* 獲取SQL語句返回的數組
* @param string $query sql 語句
* @return object resource or false;
* @access public
*/
abstract public function get_array($query);
/**
* 獲取上一條語句的執行ID
* @param string $query sql 語句
* @return integer number or false;
* @access public
*/
abstract public function insert_get_id($query);
/**
* 轉化特殊字符
* @param string $string
* @return string 處理後的字符串
* @access public
*/
abstract public function clean($string);
}
相信看到這裡,都會想到那個call_user_func方法該如何使用,別急,往下看
mysql.class.php
[html]
<?php
/**
* @author tomyjohn
* @link
* @license
* @version 1.0
* @copyright Copyright 2010 tomyjohn - tomyjohn.gicp.net
* @package db
*/
/**
*MYSQL數據庫對象
*/
class mysql extends db implements singleton{
/**
* @var $instance object
* @access current class
*/
protected static $instance = null;
/**
* @var $link resource
* @access current class
*/
protected $link;
/**
* 數據庫實例
* @return $self::instance object
*/
public static function getInstance(){
if(is_null(self::$instance)){
self::$instance = new self();
}
return self::$instance;
}
/**
* 構造器
*/
protected function __construct(){
global $current_conf;
$user = $current_conf['DBUSER'];
$pass = $current_conf['DBPWD'];
$host = $current_conf['DBHOST'];
$db = $current_conf['DBNAME'];
$this->link = mysql_connect($host,$user,$pass);
mysql_set_charset($current_conf['DBCHARSET'] , $this->link);
mysql_select_db($db);
}
/**
* 轉化特殊字符
* @param string $string
* @return string 處理後的字符串
* @access public
*/
public function clean($string){
return mysql_real_escape_string($string,$this->link);
}
/**
* 執行SQL語句
* @param string $query sql 語句
* @return object resource or false;
* @access public
*/
public function execute($query){
return mysql_query($query,$this->link);
}
/**
* 獲取上一條語句的執行ID
* @param string $query sql 語句
* @return integer number or false;
* @access public
*/
public function insert_get_id($query){
$this->execute($query);
return mysql_insert_id($this->link);
}
/**
* 獲取SQL語句返回的數組
* @param string $query sql 語句
* @return object resource or false;
* @access public
*/
public function get_array($query){
$result = $this->execute($query);
$return = array();
if($result){
while($row = mysql_fetch_array($result , MYSQL_ASSOC)){
$return[] =$row;
}
}
return $return;
}
}
current_conf 這個數組是我項目裡的,其實也可以用你數據庫的用戶名和密碼代替,看完這個我想你們也應該清楚了,繼承DB然後實現singleton接口後的這個類,其實也可用到MSSQL,ORACL,以及其他數據庫,但是光有這個,我們只能使操作數據庫變成這樣
[html] view plaincopy
$connection = db::factory('mysql');
$sql = "SELECT * FROM table";
$value_array = $connection->get_array($sql);
[html] view plaincopy
print_r($value_array);
這樣雖然解決了擴展,解決了一些重復的操作,但是還不是很方便,我們應該更進一步,使數據庫表用對象表示,即數據庫映射
dao.class.php
[html]
<?php
class dao{
/**
* @var $values array 存放數據庫對象
* @access current class
*/
protected $values = array();
/**
* @var $suffix array 存放數據庫對象
* @access public
*/
public $suffix = '';
/**
* 構造器
*/
public function __construct($qualifier = null){
global $current_conf;
$this->suffix = $current_conf['DBSUFFIX'];
if(!is_null($qualifier)){
$conditional = array();
if(is_numeric($qualifier)){
$conditional = array('id'=>$qualifier);
}
else if(is_array($qualifier)){
$conditional = $qualifier;
}
else{
throw new Exception('Invalid type of qualifier given!');
}
$this->populate($conditional);
}
}
public function __set($name , $value){
$this->values[$name] = $value;
}
public function __get($name){
if(isset($this->values[$name])){
return $this->values[$name];
}
else{
return null;
}
}
/**
* 解析實例的參數
* @param $conditional obj
*/
protected function populate($conditional){
$connection = db::factory('mysql');
$sql = "SELECT * FROM {$this->suffix}{$this->table} WHERE ";
$qualifier = '';
foreach($conditional as $column => $value){
if(!empty($qualifier)){
$qualifier .= ' AND ';
}
$qualifier .= "`{$column}`='" . $connection->clean($value) . "' ";
}
$sql .= $qualifier;
$value_array = $connection->get_array($sql);
if(!isset($value_array[0])){
$value_array[0] = array();
}
foreach($value_array[0] as $key => $value){
$this->values[$key] = $value;
}
}
/**
* 保存數據
*/
public function save(){
if(!$this->id){
$this->create();
}
else{
return $this->update();
}
}
/**
* 添加數據 www.2cto.com
*/
public function create(){
$connection = db::factory('mysql');
$sql = "INSERT INTO {$this->suffix}{$this->table}(`";
$sql .= implode('`, `' , array_keys($this->values));
$sql .="`) VALUES('";
$clean = array();
foreach($this->values as $value){
$clean[] = $connection->clean($value);
}
$sql .= implode("', '" , $clean);
$sql .="')";
$this->id = $connection->insert_get_id($sql);
}
/**
* 更新數據
* @return 返回執行操作的結果
*/
public function update(){
$connection = db::factory('mysql');
$sql = "UPDATE {$this->suffix}{$this->table} set ";
$updates = array();
foreach($this->values as $key=>$value){
if($key!='id'){
$updates[] = "`{$key}`='" . $connection->clean($value) . "'";
}
}
$sql .= implode(',' , $updates);
$sql .= " WHERE id={$this->id}";
return $connection->execute($sql);
}
/**
* 刪除數據
* @return 返回執行操作的結果
*/
public function delete(){
$connection = db::factory('mysql');
$sql = "DELETE FROM {$this->suffix}{$this->table} WHERE ";
$qualifier = 'id='.$this->id;
$sql .= $qualifier;
return $connection->execute($sql);
}
/**
* 對象轉成數組
* @return array
*/
public function object_to_array(){
return $this->values;
}
}
如果看到這裡,我相信大家都會想去繼承這個類。 是的,如果繼承了這個類,那麼每條記錄就可以變成對象,就可以用面向對象的方式去處理了。
我寫一個
news.dao.class
<?php
class news extends dao{
protected $table = __CLASS__;
}