ホームページ >バックエンド開発 >PHPチュートリアル >これは PDO クラスをカプセル化しています。CSDN の専門家が欠点を指摘してくれることを願っています。

これは PDO クラスをカプセル化しています。CSDN の専門家が欠点を指摘してくれることを願っています。

WBOY
WBOYオリジナル
2016-06-23 13:26:06997ブラウズ

PDO クラスはカプセル化されています。CSDN の専門家が欠点を指摘してくれることを願っています。

マスターの皆さん、さあ!

<?php/** * PDO封装类,目的是为了使用起来更简单方便 * modify Date: 2014-07-01 */class PDOX {	private $pdo 	   = null;		public  $statement = null;		public  $options = array(		PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES ",	);		public function __construct($dsn, $user = '', $pass = '', $persistent = false, $charset = "utf8"){		$this->options[PDO::MYSQL_ATTR_INIT_COMMAND] .= $charset;		if($persistent){			$this->options[PDO::ATTR_PERSISTENT] = true;		}		$this->pdo = new PDO($dsn, $user, $pass, $this->options);	}	/**	全局属性设置,包括:列名格式和错误提示类型    可以使用数字也能直接使用参数	*/	public function setAttr($param, $val = ''){		if(is_array($param)){			foreach($param as $key => $val){				$this->pdo->setAttribute($key, $val);			}		}else{			if($val != '' ){				$this->pdo->setAttribute($param, $val);			}else{				return false;			}		}	}	/**	生成一个编译好的sql语句模版 你可以使用 ? :name 的形式	返回一个statement对象	*/	public function prepare($sql){		if(empty($sql)){			return false;		}		$this->statement = $this->pdo->prepare($sql);		return $this->statement;	}	/**	执行Sql语句,一般用于 增、删、更新或者设置  返回影响的行数	*/	public function exec($sql){		if(empty($sql)){			return false;		}		try{			return $this->pdo->exec($sql);		}catch(Exception $e){			return $e->getMessage();		}	}	/**	执行有返回值的查询,返回PDOStatement  可以通过链式操作,可以通过这个类封装的操作获取数据	*/	public function query($sql){		if(empty($sql)){			return false;		}		$this->statement = $this->pdo->query($sql);		return $this->statement;	}	/**	开启事务	*/	public function beginTransaction(){		return $this->pdo->beginTransaction();	}	/**	提交事务	*/	public function commit(){		return $this->pdo->commit();	}	/**	事务回滚	*/	public function rollBack(){		return $this->pdo->rollBack();	}		public function lastInertId(){		return $this->pdo->lastInsertId();	}			//**   PDOStatement 类操作封装    **//		/**	让模版执行SQL语句,1、执行编译好的 2、在执行时编译	*/	public function execute($param = ""){		if(is_array($param)){			try{				return $this->statement->execute($param);			}catch (Exception $e){				//return $this->errorInfo();				return $e->getMessage();			}		}else{			try{				return $this->statement->execute();			}catch(Exception $e){				/* 返回的错误信息格式				[0] => 42S22    			[1] => 1054    			[2] => Unknown column 'col' in 'field list'    			return $this->errorInfo();    			*/				return $e->getMessage();			}		}	}		/**	参数1说明:	PDO::FETCH_BOTH		也是默认的,两者都有(索引,关联)	PDO::FETCH_ASSOC	关联数组	PDO::FETCH_NUM		索引	PDO::FETCH_OBJ			对象	PDO::FETCH_LAZY		对象 会附带queryString查询SQL语句	PDO::FETCH_BOUND	如果设置了bindColumn,则使用该参数	*/	public function fetch($fetch_type = PDO::FETCH_ASSOC){		if(is_object($this->statement)){			return $this->statement->fetch($fetch_type);		}		return false;	}	/**	参数1说明:	PDO::FETCH_BOTH		也是默认的,两者都有(索引,关联)	PDO::FETCH_ASSOC	关联数组	PDO::FETCH_NUM		索引	PDO::FETCH_OBJ		对象	PDO::FETCH_COLUMN	指定列 参数2可以指定要获取的列	PDO::FETCH_CLASS	指定自己定义的类	PDO::FETCH_FUNC		自定义类 处理返回的数据	PDO_FETCH_BOUND	如果你需要设置bindColumn,则使用该参数	参数2说明:	给定要处理这个结果的类或函数	*/	public function fetchAll($fetch_type = PDO::FETCH_ASSOC, $handle = ''){		if(empty($handle)){			return $this->statement->fetchAll($fetch_type);		}		return $this->statement->fetchAll($fetch_type, $handle);	}	/**	以对象形式返回 结果 跟fetch(PDO::FETCH_OBJ)一样	*/	public function fetchObject($class_name){		if(empty($clss_name)){			return $this->statement->fetchObject();		}		return $this->statement->fetchObject($class_name);	}		public function fetchColumn($intColumn = 0){		return $this->statement->fetchColumn($intColumn);	}		/**	public function bindColumn($array=array(),$type=EXTR_OVERWRITE){		if(count($array)>0){			extract($array,$type);		}		//$this->statement->bindColumn()	}	*/		/**	以引用的方式绑定变量到占位符(可以只执行一次prepare,执行多次bindParam达到重复使用的效果)	*/	public function bindParam($parameter, $variable, $data_type = 'STR', $length = 0){		switch ($data_type){			case  'STR':				$data_type = PDO::PARAM_STR;				break;			case 'INT':				$data_type = PDO::PARAM_INT;				break;			default :				$data_type = '';				break;		}		return $this->statement->bindParam($parameter, $variable, $data_type, $length);	}		/**	返回statement记录集的行数	*/	public function rowCount(){		return $this->statement->rowCount();	}	public function count(){		return $this->statement->rowCount();	}	public function columnCount(){		$this->statement->execute();		return $this->statement->columnCount();	}	public function getColumnMeta($intColumn){		return $this->statement->getColumnMeta($intColumn);	}			/**	关闭	*/	public function close(){		return $this->statement->closeCursor();	}		public function closeCursor(){		return $this->statement->closeCursor();	}	/**	返回错误信息也包括错误号	*/	private function errorInfo(){		return $this->statement->errorInfo();	}	/**	返回错误号	*/	private function errorCode(){		return $this->statement->errorCode();	}				//简化操作	public function insert($table, $data){		if(!is_array($data)){			return false;		}		$cols = array();		$vals = array();		foreach($data as $key => $val){			$cols[] = $key;			$vals[] = "'" . $val . "'";		}		$sql  = "INSERT INTO {$table} (";		$sql .= implode(",", $cols) . ") VALUES (";				$sql .= implode(",", $vals) . ")";		return $this->exec($sql);	}	public function insertBind($table, $arrayData){		if(!is_array($arrayData)){			return false;		}		$vals = array_keys($arrayData);		$cols = array();		/*		$arrayobject  = new  ArrayObject( $arrayData );		$iterator  	  =  $arrayobject->getIterator();		while($iterator->valid()) {			$vals[] =  ':' . $iterator->key() . '';			$iterator->next();		}		*/		$c	  = implode('', $vals);		$cols = array_filter(explode(':', $c));		$sql  = "INSERT INTO {$table} (";		$sql .= implode(",", $cols) . ") VALUES (";				$sql .= implode(",", $vals) . ")";				$this->statement = $this->pdo->prepare($sql);		$this->statement->execute($arrayData);		return  $this->statement->rowCount();	}		public function update($table, $data, $where){		if(!is_array($data)){			return false;		}		$set = array();		foreach($data as $key => $val){			$set[] = $key . "='" . $val  . "'";		}		$sql = "UPDATE {$table} SET ";		$sql .= implode(",", $set);		$sql .= " WHERE " . $where;		return $this->exec($sql);	}	public function updateBind($sql, $arrayWhere){		if(empty($sql) || !is_array($arrayWhere)){			return false;		}		$this->statement = $this->pdo->prepare($sql);		$this->statement->execute($arrayWhere);		return $this->statement->rowCount();	}		public function delete($table, $where){		if(empty($table) || empty($where)){			return false;		} 		$sql = "DELETE FROM {$table} WHERE " . $where;		return $this->exec($sql);	}	public function deleteBind($sql, $arrayWhere){		if(empty($sql) || !is_array($arrayWhere)){			return false;		}		$this->statement = $this->pdo->prepare($sql);		$this->statement->execute($arrayWhere);		return $this->statement->rowCount();	}}?>




結局のところ、プロジェクトでは、どこにでも PDO 自体について何かを書くことは不可能です。 PDO はカプセル化されているので、再度カプセル化する必要はないとは言わないでください。


ディスカッションへの返信 (解決策)

いくつかの提案:

1. 次の場合
$db = new PDOX
$a = $db->query($sql1);
$b = $db ->query($sql2);
print_r($a->fetchall());
大丈夫ですか?
$this->statement = $this->pdo->query($sql);
前のクエリ結果は次のクエリ結果によって上書きされるため、明らかに不可能です
2. トランザクション操作 カプセル化する必要があります全体として、一連の SQL を渡し、関連する操作を非表示にするだけです
3. ストアド プロシージャの使用は考慮されていません
4. PDO の既存のメソッドをコピーせずに、PDOX を PDO から直接継承できます




全体的にはかなり良いですただし、一部のメソッドは詳細すぎるため、必要に応じて統合できるように感じます

いくつかの提案: 1. 次の場合

$db = new PDOX;

$a = $db->query($sql1) ; $b = $db->query($sql2);
print_r($a->fetchall());
いいですか?
$this->statement = $this->pdo->query($sql);
前のクエリ結果は次のクエリ結果によって上書きされるため、明らかに不可能です
2. トランザクション操作 カプセル化する必要があります全体として、一連の SQL を渡し、関連する操作を非表示にするだけです
3. ストアド プロシージャの使用を考慮していません
4. PDO の既存のメソッドをコピーせずに、PDOX を PDO から直接継承できます

貴重なご意見をありがとうございます、私は操作をもっと簡単にしたいだけです。
1. あなたが挙げた例について、解決策はありますか?
2. トランザクションをほとんど使用しないため、トランザクションをカプセル化する方法がわかりません。アドバイスを頂ければより良いです。
3. ストアド プロシージャはほとんど使用されません。

4. PDO をコピーする方法は、PDO と同じように使用するだけなので、PDO を直接作成する友人はこのタイプのコードを直接使用できます。あまり勉強する必要はありません。他のデータベースクラスとは異なり、ネイティブのデータベース操作を学習した後、新しいデータベース操作を再度学習する必要があります。非常に単純ですが、学習には時間がかかります。




全体的にはかなり良いですが、一部のメソッドが詳細すぎるように感じられ、必要に応じて統合できる可能性があります

統合をより簡潔にするにはどうすればよいでしょうか? ?

カプセル化の目的は、操作を簡素化することです。
class PDOX extends PDO {  //执行各种 sql 指令,并可通过参数 $param 进行扩展  function query($sql, $param=null) {}  //查询并返回单条记录  function fetch($sql) {};  //查询并以数组方式返回多条记录  function fetchall($sql) {}}
データベース クラスは、PDO から継承されているため、ほとんどのアプリケーションのニーズを満たすことができます。なので、PDO の独自のメソッドが不足することはありません


@xuzuning


$db = new PDOX;
$a = $db->query($sql1);
$b = $db->query( $sql2);
print_r($a->fetchall());

このように書くプログラマーは多くないはずです。この場合は、まずこの運用サポートを放棄することを検討してください。私のクラスに効率や同時実行性に問題がある場合、これは大きな問題です。

このクラス内にエラーや不適切な点はありますか? ?

専門家の皆様、もっとお話しください。

分類ツリーを読み取るときに、入れ子になったクエリや再帰的なクエリがよく使用されます。なぜ、それほど多くないと言えますか?
掲示板を作成する必要はありません

データを挿入するだけです:
$data = array(':title'=>$title, ':content'=>$content);
$pdo = new PDOX;
$lastID = $pdo->insertBind('article', $data);


データを変更します:

$data = array(':title'=>$title, ':id'=> $id);

$sql = 'id=:id の記事セットを更新します';
$yesorno = $pdo->updateBind($sql, $data);
$data = array(':id'=>$id);
$sql = 'id=:id の記事を削除';
$yesorno = $pdo->deleteBind($sql, $data);この方法で書くと、多くのコードを節約できます。これが私がこの種のことを書く上での鍵です。

嵌套甚至递归的查询在读取分类树时是经常用到的,怎么能说不多呢?
嗯,做个留言板是不需要的



你说的这个还真是,在递归中需要使用。想使用此类的朋友要注意了。

我会尽量优化PHP代码或者使用其它方法替代递归,因为递归有些耗资源。

谢谢你提醒。

表示看的挺纠结的

表示看的挺纠结的



杂纠结了???

我觉得在操作数据时挺方便的呀

大牛们,继续呀。。

封装的目的是为了简化操作,不常用的就没有不要封装了

class PDOX extends PDO {  //执行各种 sql 指令,并可通过参数 $param 进行扩展  function query($sql, $param=null) {}  //查询并返回单条记录  function fetch($sql) {};  //查询并以数组方式返回多条记录  function fetchall($sql) {}}
数据库类只要有这三个方法就可满足绝大多数应用的需要了
由于是继承于 PDO,所以 PDO 原有的方法一个也不会少



不知道版主可有更好的PDO操作类???
可否贡献一个。

不怎么样!
另外预处理部分没有封装

	/**	 * 将数组转换为SQL语句	 * @param array $where 要生成的数组	 * @param string $font 连接串。	 */	final public function sqls($where, $font = ' AND ') {				# 先将bindColumn存起来				$this->bindColumn = array();		if (is_array($where)) {			$sql = '';			foreach ($where as $key=>$val) {				$sql .= $sql ? " $font `$key` = :$key " : " `$key` = :$key";				$this->bindColumn = array($key, $val);			}			return ;		} else {			return $where;		}	}

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。