/** * 执行 */ public function execute() { //参数重载 if (func_num_args() == 1) { return $this->_executeParam1(func_get_arg(0)); } switch (trim($this->action)) { case 'SELECT': $databaseObject = CDatabase::getDatabase($this->configName, false); $sql = $this->_sql = $this->_createSelectSQL(); $rsReult = array(); $btime = $etime = 0; //检查缓存 if (!empty($this->_cache)) { //尝试直接从缓存获取 $cacheData = Cache::getInstance()->get($this->_cache); if (null != $cacheData) { //查询结果对象 $resultObject = new CResult(); $resultObject->setIsMaster(false); $resultObject->setSql($sql); $resultObject->setIsCache(true); $resultObject->setValue($cacheData->asArray()); $resultObject->setCastTime($etime > $btime ? round($etime - $btime, 6) : 0); //执行查询后钩子函数 CHooks::callHooks(HOOKS_EXECUTE_END, $resultObject); $this->_clearSelf(); return $cacheData; } } try { //执行查询前钩子函数 CHooks::callHooks(HOOKS_EXECUTE_BEFORE, $this); $btime = microtime(true); $rs = $databaseObject->prepare($this->_sql); if (!$rs) { $errorData = $databaseObject->errorInfo(); //发生SQL错误时 触发钩子 $dbError = new CDBError(); $dbError->setSQLErrorCode($errorData[0]); $dbError->setDriverErrorCode($errorData[1]); $dbError->setErrorMessage($errorData[2]); $dbError->setSql($this->_sql); CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError); throw new PDOException('[' . $errorData[1] . '] ' . $errorData[2] . ' with SQL [' . $this->_sql . ']'); } $rs->execute($this->whereValue); $rs->setFetchMode(PDO::FETCH_OBJ); $rsReult = $rs->fetchAll(); $etime = microtime(true); } catch (PDOException $pdoException) { throw new CDbException($pdoException->getMessage()); } //查询结果对象 $resultObject = new CResult(); $resultObject->setIsMaster(false); $resultObject->setSql($sql); $resultObject->setWhereValue($this->whereValue); $resultObject->setValue($rsReult); $resultObject->setCastTime($etime > $btime ? round($etime - $btime, 6) : 0); //执行查询后钩子函数 CHooks::callHooks(HOOKS_EXECUTE_END, $resultObject); //缓存结果 if (!empty($this->_cache)) { $cacheData = Cache::getInstance()->set($this->_cache, $resultObject, $this->_cacheTime); } //清理 $this->_clearSelf(); return $resultObject; break; case 'INSERT INTO': // 强制主库操作新增 $this->isMaster = true; $databaseObject = CDatabase::getDatabase($this->configName, $this->isMaster); $sql = $this->_sql = $this->_createInsertSQL(); //执行查询前钩子函数 CHooks::callHooks(HOOKS_EXECUTE_BEFORE, $this); $insertStatus = $databaseObject->exec($this->_sql); if ($insertStatus > 0) { //执行操作 $execObject = new CExec(); $execObject->setSql($sql); $execObject->setRow($insertStatus); $execObject->setStatus(true); $execObject->setLastInsertId($databaseObject->lastInsertId()); //执行查询后钩子函数 CHooks::callHooks(HOOKS_EXECUTE_END, $execObject); //清理 $this->_clearSelf(); return $execObject; } else { //发生错误 $errorData = $databaseObject->errorInfo(); //发生SQL错误时 触发钩子 $dbError = new CDBError(); $dbError->setSQLErrorCode($errorData[0]); $dbError->setDriverErrorCode($errorData[1]); $dbError->setErrorMessage($errorData[2]); $dbError->setSql($this->_sql); CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError); throw new CDbException('[' . $errorData[1] . '] ' . $errorData[2] . ' with SQL [' . $this->_sql . ']'); } //清理 $this->_clearSelf(); break; case 'UPDATE': // 强制主库操作更新 $this->isMaster = true; $databaseObject = CDatabase::getDatabase($this->configName, $this->isMaster); $sql = $this->_sql = $this->_createUpdateSQL(); //执行查询前钩子函数 CHooks::callHooks(HOOKS_EXECUTE_BEFORE, $this); $rs = $databaseObject->prepare($this->_sql); $updateStatus = $rs->execute($this->whereValue); if (false === $updateStatus) { $errorData = $databaseObject->errorInfo(); //发生SQL错误时 触发钩子 $dbError = new CDBError(); $dbError->setSQLErrorCode($errorData[0]); $dbError->setDriverErrorCode($errorData[1]); $dbError->setErrorMessage($errorData[2]); $dbError->setSql($this->_sql); CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError); throw new CDbException('[' . $errorData[1] . '] ' . $errorData[2] . ' with SQL [' . $this->_sql . ']'); } else { $execObject = new CExec(); $execObject->setSql($sql); $execObject->setRow($updateStatus); $execObject->setWhereValue($this->whereValue); $execObject->setStatus(true); //执行查询后钩子函数 CHooks::callHooks(HOOKS_EXECUTE_END, $execObject); $this->_clearSelf(); return $execObject; } $this->_clearSelf(); break; case 'DELETE': // 强制主库操作删除 $this->isMaster = true; $databaseObject = CDatabase::getDatabase($this->configName, $this->isMaster); $sql = $this->_sql = $this->_createDeleteSQL(); //执行查询前钩子函数 CHooks::callHooks(HOOKS_EXECUTE_BEFORE, $this); //echo '<pre>';print_r($this->whereValue);exit; $rs = $databaseObject->prepare($this->_sql); $deleteStatus = $rs->execute($this->whereValue); if (false === $deleteStatus) { $errorData = $databaseObject->errorInfo(); //发生SQL错误时 触发钩子 $dbError = new CDBError(); $dbError->setSQLErrorCode($errorData[0]); $dbError->setDriverErrorCode($errorData[1]); $dbError->setErrorMessage($errorData[2]); $dbError->setSql($this->_sql); CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError); throw new CDbException('[' . $errorData[1] . '] ' . $errorData[2] . ' with SQL [' . $this->_sql . ']'); } else { $execObject = new CExec(); $execObject->setSql($sql); $execObject->setWhereValue($this->whereValue); $execObject->setRow($deleteStatus); $execObject->setStatus(true); //执行查询后钩子函数 CHooks::callHooks(HOOKS_EXECUTE_END, $execObject); $this->_clearSelf(); return $execObject; } $this->_clearSelf(); break; default: if (!empty($this->prepare)) { } throw new CDbException('[查询错误]未指定操作方法'); break; } $this->_clearSelf(); }
/** * 获取PDO对象 */ public static function getDatabase($configName = 'main', $isMaster = true) { if (empty($configName)) { $configName = 'main'; } if (isset(self::$objectPdo[intval($isMaster) . $configName])) { return self::$objectPdo[intval($isMaster) . $configName]; } $dbConfig = CConfig::getInstance()->load('DB.' . $configName); if (!isset($dbConfig['master'])) { throw new CDbException('[配置错误]getDataBase方法尝试获取不存在的配置项:[Config->DB->master]'); } if (true == $isMaster) { $thisConfigData = $dbConfig['master']; self::$configData[intval($isMaster) . $configName] = $thisConfigData; self::$configData[intval(!$isMaster) . $configName] = $dbConfig['slaves']; } if (false == $isMaster) { $thisConfigData = !isset($dbConfig['slaves']) ? $dbConfig['master'] : $dbConfig['slaves']; self::$configData[intval($isMaster) . $configName] = $thisConfigData; self::$configData[intval(!$isMaster) . $configName] = $dbConfig['master']; } try { $pdoObject = new PDO($thisConfigData['connectionString'], $thisConfigData['username'], $thisConfigData['password']); $pdoObject->query('set names ' . $thisConfigData['charset']); } catch (PDOException $pdoException) { //尝试启用备用库 if (true == $isMaster) { //是否允许启用备库 $writeConf = self::$configData[intval($isMaster) . $configName]; if (isset($writeConf['slavesWrite']) && true == $writeConf['slavesWrite']) { //尝试连接备库 try { //从库配置 $slaverConf = self::$configData[intval(!$isMaster) . $configName]; $pdoObject = new PDO($slaverConf['connectionString'], $slaverConf['username'], $slaverConf['password']); $pdoObject->query('set names ' . $slaverConf['charset']); } catch (PDOException $pdoExceptionAgain) { $dbError = new CDBError(); $dbError->setSQLErrorCode('CMyFrame'); $dbError->setDriverErrorCode('CMyFrame'); $dbError->setErrorMessage('主库连接失败后,尝试连接从库,连接从库依旧失败'); CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError); //切换数据依旧无法连接 throw new CDbException('[数据库错误]主库连接失败后,尝试连接从库依旧失败:' . $pdoExceptionAgain->getMessage()); } } else { //不允许使用备库 $dbError = new CDBError(); $dbError->setSQLErrorCode('CMyFrame'); $dbError->setDriverErrorCode('CMyFrame'); $dbError->setErrorMessage('主库连接失败后,不允许尝试连接从库'); CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError); throw new CDbException('[数据库错误]连接主数据库失败,且不允许尝试使用从库:' . $pdoException->getMessage()); } } else { //是否使用主库进行读取 $readConf = self::$configData[intval($isMaster) . $configName]; if (isset($readConf['masterRead']) && true == $readConf['masterRead']) { $errorMessage = '从库连接失败后,尝试连接主库,主库连接成功'; try { //主库配置 $masterConf = self::$configData[intval(!$isMaster) . $configName]; $pdoObject = new PDO($masterConf['connectionString'], $masterConf['username'], $masterConf['password']); $pdoObject->query('set names ' . $masterConf['charset']); } catch (PDOException $pdoExceptionAgain) { $dbError = new CDBError(); $dbError->setSQLErrorCode('CMyFrame'); $dbError->setDriverErrorCode('CMyFrame'); $dbError->setErrorMessage('从库连接失败后,尝试连接主库,连接主库依旧失败'); CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError); //切换数据依旧无法连接 throw new CDbException('[数据库错误]从库连接失败后,尝试连接主库依旧失败:' . $pdoExceptionAgain->getMessage()); } } else { //发生SQL错误时 触发钩子 $dbError = new CDBError(); $dbError->setSQLErrorCode('CMyFrame'); $dbError->setDriverErrorCode('CMyFrame'); $dbError->setErrorMessage('从库连接失败后,不允许尝试连接主库'); CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError); throw new CDbException('[数据库错误]连接从数据库失败,且不允许尝试使用主库:' . $pdoException->getMessage()); } //发生SQL错误时 触发钩子 $dbError = new CDBError(); $dbError->setSQLErrorCode('CMyFrame'); $dbError->setDriverErrorCode('CMyFrame'); $dbError->setErrorMessage($errorMessage); CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError); } } self::$objectPdo[intval($isMaster) . $configName] = $pdoObject; return $pdoObject; }