PHP有用的MYSQL操作类(设计模式解读一)

要用PHP操作一个数据库很简单,相应入门后的PHPER都可以做到,但是在应对大量的表操作时,我们为许多的MYSQL语句感到厌烦,所以我们急切想要把大量数据库操作封装起来。所以就出现了数据库对象映射。

首先我们新建一个接口。

singleton.class.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
/**
 * @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

<?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,以及其他数据库,但是光有这个,我们只能使操作数据库变成这样

$connection = db::factory('mysql');
$sql = "SELECT * FROM table";
$value_array = $connection->get_array($sql);
print_r($value_array);
这样虽然解决了扩展,解决了一些重复的操作,但是还不是很方便,我们应该更进一步,使数据库表用对象表示,即数据库映射

dao.class.php

<?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();
		}
	}
	
	/**
	 * 添加数据
	 */
	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__;
	
}

我们在开发网站的时候,尽量不要使数据操作进入视图,下一节我介绍一个模板类。

你可能感兴趣的:(设计模式,sql,PHP,mysql,function,String)