-
-
/** - * データベース PDO 操作
- */
- class MysqlPdo {
- public static $PDOStatement = null;
- /**
- * データベース接続パラメータの設定
- * @var array
- * @access public
- */
- public static $config = array();
- /**
- * 永続接続を使用するかどうか
- * @var bool
- * @access public
- */
- public static $pconnect = false;
- /**
- * エラーメッセージ
- * @var string
- * @access public
- */
- public static $error = '';
- /**
- * シングルトン モード、Pdo クラスの唯一のインスタンスとデータベースの接続リソースを保存します
- * @var object
- * @access public
- */
- protected static $link;
- /**
- * データベースが接続されているかどうか
- * @var bool
- * @access public
- */
- public static $connected = false;
- /**
- * データベースのバージョン
- * @var string
- * @access public
- */
- public static $dbVersion = null;
- /**
- * 現在の SQL ステートメント
- * @var string
- * @access public
- */
- public static $queryStr = '';
- /**
- * 最後に挿入されたレコードの ID
- * @var integer
- * @access public
- */
- public static $lastInsertId = null;
- /**
- * 影響を受けるレコードの数を返します
- * @var integer
- * @access public
- */
- public static $numRows = 0;
- // トランザクション命令の数
- public static $ transTimes = 0;
- /**
- * コンストラクター、
- * @param $dbconfig データベース接続関連情報、array('ServerName', 'UserName', 'Password', 'DefaultDb', 'DB_Port', 'DB_TYPE')
- */
- public function __construct($dbConfig=''){
- if (!class_exists('PDO')) self::throw_Exception("サポートされていません: PDO");
- //パラメータが送信されない場合、デフォルトのデータ定義が使用されます
- if (!is_array($dbConfig)) {
- $dbConfig = array(
- 'hostname' => DB_HOST,
- 'username' => DB_USER,
- 'パスワード' =>
- 'データベース' => DB_PORT,
- 'dbms' => . DB_HOST.";dbname=".DB_NAME
- );
- }
- if(empty($dbConfig['hostname'])) self::throw_Exception("データベース構成が定義されていません");
- self::$config = $ dbConfig ;
- if(empty(self::$config['params'])) self::$config['params'] = array();
- /***************************************ゴージャスな仕切り************ *****************************/
- if (!isset(self) : :$link) ) {
- $configs = self::$config;
- if(self::$pconnect) {
- $configs['params'][constant('PDO::ATTR_PERSISTENT')] = true;
-
- try {
- self::$link = new PDO( $configs['dsn'], $configs['username'], $configs['password'],$configs['params']);
- } catch ( PDOException $e) {
- self::throw_Exception($e->getMessage());
- }
- if(!self::$link) {
- self::throw_Exception('PDO CONNECT ERROR');
- return false ;
- }
- self::$link->exec('SET NAMES '.DB_CHARSET);
- self::$dbVersion = self::$link->getAttribute(constant("PDO::ATTR_SERVER_INFO")) ;
- // 接続に成功をマークします
- self::$connected = true;
- // データベース接続構成情報をログアウトします
- unset($configs);
- }
- return self::$link;
- }
- /**
- * クエリ結果を公開
- * @access関数
- * /
- static function free() {
- self::$PDOStatement = null;
- }
- /************************/
- /* データベース操作*/
- /************************/
- / **
- * すべてのクエリデータを取得します
- * @access 関数
- * @return 配列
- */
- static function getAll($sql=null) {
- if($sql != null)
- {
- self::query($sql);
- }
- //データセットを返す
- $ result = self:: $PDOStatement->fetchAll(constant('PDO::FETCH_ASSOC'));
- return $result;
- }
- /**
- * クエリ結果の取得
- * @access 関数
- * @param string $sql SQL コマンド
- * @param integer $seek ポインタ位置
- * @return array
- */
- static function getRow($sql=null) {
- if($sql != null)
- {
- self::query($sql);
- }
- // 配列セットを返す
- $result = self::$PDOStatement->fetch(constant('PDO::FETCH_ASSOC) '),constant( 'PDO::FETCH_ORI_NEXT'));
- return $result;
- }
- /**
- * SQL ステートメントを実行し、クエリまたは操作を自動的に判断します
- * @access 関数
- * @param string $sql SQL コマンド
- * @return 混合
- */
- 静的関数 doSql($sql='') {
- if(self::isMainIps( $sql)) {
- return self::execute($sql);
- }else {
- return self::getAll($sql);
- }
- }
- /**
- * 指定された ID に基づいてテーブル内のレコードを検索します (単一テーブル操作の場合のみ)
- * @access 関数
- * @param integer $priId 主キー ID
- * @param string $tables データテーブル名
- * @param string $フィールド フィールド名
- * @return ArrayObject テーブル レコード
- */
- static function findById($ tabName,$priId, $fields='*'){
- $sql = 'SELECT %s FROM %s WHERE id=%d';
- return self::getRow(sprintf($sql, self::parseFields($fields) )、$tabName、$priId));
- }
- /**
- * レコード検索
- * @access関数
- * @param string $tables データテーブル名
- * @parammixed $where クエリ条件
- * @param string $fields フィールド名
- * @param string $order Sort
- * @param string $limit 取得するデータの個数
- * @param string $group グループ化
- * @param string $having
- * @param boolean $lock ロックするか否か
- * @return ArrayObject
- */
- 静的関数 find($tables,$where="",$fields='*',$order=null,$limit=null,$group=null,$having=null) {
- $sql = 'SELECT '.self::parseFields($fields)
- .' FROM '.$tables
- .self::parseWhere($where)
- .self::parseGroup($group)
- .self::parseHaving($having)
- .self::parseOrder($order)
- .self:: parseLimit($limit);
- $dataAll = self::getAll($sql);
- if(count($dataAll)==1){$rlt=$dataAll[0];}else{$rlt=$dataAll; }
- return $rlt;
- }
- /**
- * (単一) レコードを挿入します
- * @access 関数
- * @param 混合 $data データ
- * @param string $table データ テーブル名
- * @return false |*/
- function add($data,$table) {
- //过滤提交数据
- $data=self::filterPost($table,$data);
- foreach ($data as $key=>$val){
- if(is_array($val) && strto lower($val[0]) == 'exp') {
- $val = $val[1]; // 表达式を使用します ???
- }elseif (is_scalar($val)){
- $val = self::fieldFormat($val);
- }else{
- // 去掉复合对象
- continue;
- }
- $data [$key] = $val;
- }
- $fields = array_keys($data);
- array_walk($fields, array($this, 'addSpecialChar'));
- $fieldsStr = implode(',', $fields);
- $values = array_values($data);
- $valuesStr = implode(',', $values);
- $sql = 'INSERT INTO '.$table.' ('.$fieldsStr.') VALUES ('.$valuesStr.')';
- return self::execute($sql);
- }
- /**
- * レコード更新
- * @access関数
- * @parammixed $sets data
- * @param string $table データテーブル名
- * @param string $where更新条件
- * @param string $limit
- * @param string $order
- * @return false
- */
- static function update($sets,$ table,$where,$limit=0,$order='') {
- $sets = self::filterPost($table,$sets);
- $sql = 'UPDATE '.$table.' SET '.self::parseSets($sets).self::parseWhere($where).self::parseOrder($order).self::parseLimit($limit);
- return self::execute($sql);
- }
- /**
- * 特定のフィールドの値を保存します
- * @access関数
- * @param string $field 保存するフィールドの名前
- * @param string $value フィールドの値
- * @param string $table データテーブル
- * @ param string $where 保存条件
- * @param boolean $asString フィールド値が文字列かどうか
- * @return void
- */
- static function setField($field, $value, $table, $condition="", $asString=false) {
- // 如果有'(' 参照 SQL命令更新if(false === strpos($value,'(') || $asString) $value = '"'.$value.'"';
- $sql = 'UPDATE ' .$table.' SET '.$field.'='.$value.self::parseWhere($condition);
- return self::execute($sql);
- }
- /**
- * レコードを削除します
- * @access 関数
- * @parammixed $where は条件付きマップ、配列、または文字列です
- * @param string $table データテーブル名
- * @param string $limit
- * @param string $order
- * @ false を返します |*/
- 静的関数の削除($where,$table,$limit='',$order='') {
- $sql = 'DELETE FROM '.$table.self::parseWhere($where).self::parseOrder($ order).self::parseLimit($limit);
- return self::execute($sql);
- }
- /**
- +------------------------------------------------ ----------
- * データの変更または保存(単一テーブル操作のみ)
- * 主キーIDがある場合は変更、主キーIDがない場合は追加
- *修正記録:
- +---- -------------------------------------- --------- ----
- * @アクセス機能
- +---------------------------- --------- -------------------
- * @param $tabName テーブル名
- * @param $aPost $_POST でフォームを送信
- * @param $priId 主キー ID
- * @param $aNot 除外されるフィールドまたは配列
- * @param $aCustom データベースに追加され、保存されるカスタマイズされた配列
- * @param $isExits すでに存在するかどうか: true、存在しません: false
- +----- -------------------------------------- ------------ ---
- * @return Boolean 変更または保存が成功したかどうか
- +--------------------- ------------------------------------------
- */
- function saveOrUpdate($tabName, $aPost, $priId="", $aNot="", $aCustom="", $isExits=false) {
- if(empty($tabName) || !is_array($aPost) || is_int($aNot)) return false;
- if(is_string( $aNot) && !empty($aNot)) $aNot = array($aNot);
- if(is_array($aNot) && is_int(key($aNot))) $aPost = array_diff_key($aPost, array_flip($aNot) ));
- if(is_array($aCustom) && is_string(key($aCustom))) $aPost = array_merge($aPost,$aCustom);
- if (empty($priId) && !$isExits) { //新增
- $aPost = array_filter($aPost, array($this, 'removeEmpty'));
- return self::add($aPost, $tabName);
- }else { //修改
- return self::update($aPost, $tabName, "id=".$priId);
- }
- }
- /**
- * 最新のクエリの SQL ステートメントを取得します
- * @access function
- * @param
- * @return String 実行された SQL
- */
- static function getLastSql() {
- $link = self::$link;
- if ( !$link ) return false;
- return self::$queryStr;
- }
- /**
- * 最後に挿入された ID を取得します
- * @access function
- * @param
- * @return integer 最後に挿入されたデータ ID
- */
- static function getLastInsId(){
- $link = self:: $link;
- if ( !$link ) return false;
- return self::$lastInsertId;
- }
- /**
- * DB バージョンの取得
- * @access 関数
- * @param
- * @return string
- */
- static function getDbVersion(){
- $link = self::$link;
- if ( !$link ) return false;
- return self::$dbVersion;
- }
- /**
- * データベーステーブル情報を取得します
- * @access関数
- * @return array
- */
- static function getTables() {
- $info = array();
- if(self::query ("SHOW TABLES")) {
- $result = self::getAll();
- foreach ($result as $key => $val) {
- $info[$key] = current($val);
- }
- }
- return $info;
- }
- /**
- * データテーブルのフィールド情報を取得
- * @access関数
- * @return array
- */
- static function getFields($tableName) {
- // 获取数据库联接
- $link = self::$link;
- $sql = "SELECT
- ORDINAL_POSITION 、COLUMN_NAME、COLUMN_TYPE、DATA_TYPE、
- IF(ISNULL(CHARACTER_MAXIMUM_LENGTH)、(NUMERIC_PRECISION + NUMERIC_SCALE)、CHARACTER_MAXIMUM_LENGTH) AS MAXCHAR、
- IS_NULLABLE、COLUMN_DEFAULT、COLUMN_KEY、EXTRA、 _COMMENT
- FROM
- INFORMATION_SCHEMA.COLUMNS
- WHERE
- TABLE_NAME = :tabName AND TABLE_SCHEMA='".DB_NAME."'";
- self::$queryStr = sprintf($sql, $tableName);
- $sth = $link->prepare($sql);
- $sth->bindParam (':tabName', $tableName);
- $sth->execute();
- $result = $sth->fetchAll(constant('PDO::FETCH_ASSOC'));
- $info = array();
- foreach ($result as $key => $val) {
- $info[$val['COLUMN_NAME']] = array(
- 'postion' => $val['ORDINAL_POSITION'],
- 'name' => $val['COLUMN_NAME'],
- 'type' => $val['COLUMN_TYPE'],
- 'd_type' => $val['DATA_TYPE'],
- 'length' => $val['MAXCHAR'],
- 'notnull' => ; (strto lower($val['IS_NULLABLE']) == "いいえ"),
- 'default' => $val['COLUMN_DEFAULT'],
- 'primary' => ]) == 'pri'),
- 'autoInc' => (strto lower($val['EXTRA']) == 'auto_increment'),
- 'comment' => $val['COLUMN_COMMENT']
- ) ;
- }
- // 有错误则抛出异常
- self::haveErrorThrowException();
- return $info;
- }
- /**
- * データベースを閉じる
- * @access 関数
- */
- static function close() {
- self::$link = null;
- }
- /**
- * SQL コマンドのセキュリティ フィルタリング
- * @access 関数
- * @param string $str SQL コマンド
- * @return string
- */
- static functionscape_string($str) {
- returnaddslashes($str);
- }
- /************************/
- /* 内部操作方法 */
- /************************/
- /**
- * エラーがある場合は例外がスローされます
- * @access 関数
- * @return
- */
- 静的関数 haveErrorThrowException() {
- $obj = empty(self::$PDOStatement) ? self::$link : self::$PDOStatement;
- $arrError = $obj->errorInfo();
- if($arrError[0] !== '00000') { // 有错误情報
- self:: $error = $arrError[0]."|".$arrError[2]。 "
[ SQL ] : ".self::$queryStr." ";
- self::throw_Exception(self::$error);
- return false;
- }
- //主要针对execute() メソッド抛出异常
- if(self::$queryStr=='')self::throw_Exception('クエリは空でした
[ SQL语句 ] :');
- }
- /**
- * where 分析
- * @access 関数
- * @param 混合 $where クエリ条件
- * @return string
- */
- 静的関数 parseWhere($where) {
- $whereStr = '';
- if(is_string($where) || is_null($where)) {
- $whereStr = $where ;
- }
- return empty($whereStr)?'':' WHERE '.$whereStr;
- }
- /**
- * 順序分析
- * @access 関数
- * @param 混合 $order ソート
- * @return string
- */
- 静的関数 parseOrder($order) {
- $orderStr = '';
- if (is_array($order))
- $orderStr .= ' ORDER BY '.implode(',', $order);
- else if(is_string($order) && !empty($order))
- $orderStr .= ' ORDER BY '.$order;
- return $orderStr;
- }
- /**
- * 制限分析
- * @access 関数
- * @param string $limit
- * @return string
- */
- 静的関数 parseLimit($limit) {
- $limitStr = '';
- if(is_array($limit)) {
- if(count($limit)>1)
- $limitStr .= ' LIMIT '.$limit[0].' 、「.$limit[1].」 ';
- else
- $limitStr .= ' LIMIT '.$limit[0].' ';
- } else if(is_string($limit) && !empty($limit)) {
- $limitStr .= ' LIMIT '.$limit.' ';
- }
- $limitStr;
- を返す
- /**
- * グループ分析
- * @access 関数
- * @parammixed $group
- * @return string
- */
- 静的関数 parseGroup($group) {
- $groupStr = '';
- if(is_array($group))
- $groupStr .= ' GROUP BY '.implode(',', $group);
- else if(is_string($group) && !empty($group))
- $groupStr .= ' GROUP BY '.$group;
- return empty($groupStr)?'':$groupStr;
- }
- /**
- * 分析を持っています
- * @access 関数
- * @param string $having
- * @return string
- */
- 静的関数 parseHaving($having) {
- $havingStr = '';
- if(is_string($having) && !empty($having))
- $havingStr .= ' HAVING '。 $having;
- return $havingStr;
- }
- /**
- * フィールド分析
- * @access 関数
- * @parammixed $fields
- * @return string
- */
- function parseFields($fields) {
- if(is_array($fields)) {
- array_walk($fields, array($this, 'addSpecialChar) '));
- $fieldsStr = implode(',', $fields);
- }else if(is_string($fields) && !empty($fields)) {
- if( false === strpos($fields,' `') ) {
- $fields =explode(',',$fields);
- array_walk($fields, array($this, 'addSpecialChar'));
- $fieldsStr = implode(',', $fields);
- }else {
- $fieldsStr = $fields;
- }
- }else $fieldsStr = '*';
- return $fieldsStr;
- }
- /**
- * データ更新時に呼び出される分析を設定します
- * @access 関数
- * @parammixed $values
- * @return string
- */
- プライベート関数 parseSets($sets) {
- $ setStr = '';
- if(is_array($sets)){
- foreach ($sets as $key=>$val){
- $key = self::addSpecialChar($key);
- $val = self:: fieldFormat($val);
- $setsStr .= "$key = ".$val.",";
- }
- $setsStr = substr($setsStr,0,-1);
- }else if(is_string($sets) )) {
- $setsStr = $sets;
- }
- return $setsStr;
- }
- /**
- * フィールドの書式設定
- * @access 関数
- * @parammixed $value
- * @returnmixed
- */
- 静的関数 fieldFormat(&$value) {
- if(is_int($value)) {
- $ value = intval($value);
- } else if(is_float($value)) {
- $value = floatval($value);
- } elseif(preg_match('/^(w*(+|-|*|/ )?w*)$/i',$value)){
- // 在字段の值里面直接使用をサポート
- // 例 (score+1) (name) 必须包含号
- $value = $value;
- }else if(is_string($value)) {
- $value = '''.self::escape_string($value).''';
- }
- return $value;
- }
- /**
- * フィールド名とテーブル名に ` を追加すると、命令内でキーワードを使用するときにエラーが発生しないようにするための
- * に準拠します。
- * @access 関数
- * @parammixed $value
- * @returnmixed
- * /
- 静的関数 addSpecialChar(&$value) {
- if( '*' == $value || false !== strpos($value,'(') || false !== strpos($value,'.') || false !== strpos($value,'`')) {
- //如果包含* または使用了sqlメソッド则不作处理
- } elseif(false === strpos($value,'`') ) {
- $value = '`'.trim($value).'`';
- }
- return $value;
- }
- /**
- +------------------------------------------------ ----------
- * 空の要素を削除します
- +--------------------------------- -----------------------------
- * @アクセス機能
- +-------------- ---- --------------------------------------
- * @param 混合$値
- +- ---------------------------------------------- ---- -------
- * @return 混合
- +-------------------------------- ---- -----------------------
- */
- static function RemoveEmpty($value){
- return !empty($value);
- }
- /**
- * SELECT、SHOWなどの命令を中心にクエリを実行
- * @access関数
- * @param string $sql SQL命令
- * @returnmixed
- */
- static function query($sql ='') {
- // 获取数据库联接
- $link = self::$link;
- if ( !$link ) return false;
- self::$queryStr = $sql;
- //释放前回の查询結果
- if ( !empty(self::$PDOStatement) ) self::free();
- self::$PDOStatement = $link->prepare(self::$queryStr);
- $bol = self::$PDOStatement ->execute();
- // 有错误则抛出异常
- self::haveErrorThrowException();
- return $bol;
- }
- /**
- * データベース操作方法
- * @access関数
- * @param string $sql実行文
- * @param boolean $lock ロックするかどうか(デフォルトはロックなし)
- * @return void
- public functionexecute($sql='') ,$ lock=false) {
- if(empty($sql)) $sql = $this->queryStr;
- return $this->execute($sql);*/
- /**
- * INSERT、UPDATE、DELETE の実行ステートメント
- * @access 関数
- * @param string $sql SQL コマンド
- * @return integer
- */
- static functionexecute($sql='') {
- // 获取数据库联接
- $link = self::$link;
- if ( !$link ) return false;
- self::$queryStr = $sql;
- //释放前次的查询結果
- if ( !empty(self::$PDOStatement) ) self::free();
- $result = $link->exec(self::$queryStr);
- // 有错误则抛出异常
- self::haveErrorThrowException();
- if ( false === $result) {
- return false;
- } else {
- self::$numRows = $result;
- self::$lastInsertId = $link- >lastInsertId();
- return self::$numRows;
- }
- }
- /**
- * データベース変更操作かどうか
- * @access private
- * @param string $query SQL コマンド
- * @return boolen クエリ操作の場合は false を返す
- */
- 静的関数 isMainIps($query) {
- $queryIps = 'INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|LOAD DATA|SELECT .* INTO|COPY|ALTER|GRANT|REVOKE |LOCK|UNLOCK';
- if (preg_match('/^s*"?(' . $queryIps . ')s+/i', $query)) {
- return true;
- }
- return false;
- }
- / **
- * POST 送信データをフィルターします
- * @access private
- * @parammixed $data POST 送信データ
- * @param string $table データテーブル名
- * @returnmixed$newdata
- */
- 静的関数 filterPost($table,$data) {
- $table_column = self::getFields($table);
- $newdata=array();
- foreach ($table_column as $key=>) ;$val){
- if(array_key_exists($key,$data) && ($data[$key])!==''){
- $newdata[$key] = $data[$key];
- }
- }
- return $newdata;
- }
- /**
- * トランザクションを開始します
- * @access 関数
- * @return void
- */
- static function startTrans() {
- //データロールバックサポート
- $link = self::$link;
- if ( !$link ) return false;
- if (self::$transTimes == 0) {
- $link->beginTransaction();
- }
- self::$transTimes++;
- return ;
- }
- /**
- * 非自動送信ステータスでのクエリの送信に使用されます
- * @access 関数
- * @return boolen
- */
- 静的関数コミット() {
- $link = self::$link;
- if ( !$link ) return false;
- if (self::$transTimes > 0) {
- $result = $link->commit();
- self::$transTimes = 0;
- if(!$result){
- self::throw_Exception(self::$error());
- return false;
- }
- }
- return true;
- }
- /**
- * トランザクションのロールバック
- * @access 関数
- * @return boolen
- */
- public function rollback() {
- $link = self::$link;
- if ( !$link ) return false;
- if (self::$transTimes > 0) {
- $result = $link->rollback();
- self::$transTimes = 0;
- if(!$result){
- self::throw_Exception(self::$error());
- return false;
- }
- }
- return true;
- }
/**
- * エラー処理
- * @access 関数
- * @return void
- */
- static function throw_Exception($err){
- echo '
エラー:'.$err.'
- }
- }
-
复制代
|