Yii 가 만나면 pdo 지원 하지 않 음mysql 서버
이것 은 정말 답답 한 일이 다. 프로젝트 의 하위 프로젝트 (cms) 에서 위 정적 을 실현 하고 신속하게 완성 하기 위해 Yii 를 선택 했다.
모든 면 에서 준비 되 어 있 습 니 다. 경로 규칙, nginx rewrite, my sql slave... 하지만 서버 에 Pdo 가 없습니다.my sql 구동, 그때 놀 랐 어!프로젝트 가 이미 출시 되 었 고 재 컴 파일 은 그다지 현실 적 이지 않 아서 파일 을 해결 하 는 것 을 생각 할 수 밖 에 없다. 즉, 이때 서 야 Yii 가 PDO 연결 방식 만 제공 한 것 을 발견 했다.시간 이 급 해서 그때 생각 한 해결 방법:
첫 번 째 방식 은 가장 간단 하지만 이렇게 하지 않 았 습 니 다. phop - fpm 를 다시 시작 해 야 하기 때문에 성공 과 안정성 을 보장 하기 어렵 습 니 다.
두 번 째 는 동료 가 추천 한 것 입 니 다. 코드 의 양 이 많 고 이렇게 하면 돌 이 키 기 어렵 고 다시 테스트 해 야 합 니 다.
세 번 째 는 좋 은 해결 방안 입 니 다. 그리고 Yii 는 PdoClass 를 지정 하 는 것 을 지원 합 니 다. 프레임 워 크 와 기 존 코드 에 대한 침입 성 이 없고 짧 은 시간 안에 실현 할 수 있 기 때문에 이것 입 니 다.
데이터 베 이 스 를 읽 기만 하기 때문에 많은 고려 도 하지 않 았 고 모든 방법 을 실현 할 생각 도 없 었 기 때문에 Yii 의 DAO 처리 부분 을 읽 고 이 두 class 를 간단하게 썼 습 니 다.
<?php
/**
* mysqli PDO PDO_mysql -_-||
* @author xl
* create on 2014-3-26
*/
class PDO_Mysql{//extends PDO
private $handle = NULL;
private $tmpParams = array();
const MYSQL_ATTR_USE_BUFFERED_QUERY = 1000;
const MYSQL_ATTR_LOCAL_INFILE = 1001;
const MYSQL_ATTR_INIT_COMMAND = 1002;
const MYSQL_ATTR_READ_DEFAULT_FILE = 1003;
const MYSQL_ATTR_READ_DEFAULT_GROUP = 1004;
const MYSQL_ATTR_MAX_BUFFER_SIZE = 1005;
const MYSQL_ATTR_DIRECT_QUERY = 1006;
public function __construct($connectionString,$username,$password,$options=array()){
//
preg_match('/host=([\w\.]+);dbname=(\w+)/i', $connectionString,$matches);
if(count($matches)<3){
throw new PDOException('connectionString is invalid');
}
$this->handle = new mysqli($matches[1],$username,$password,$matches[2]);
//$options
}
public function beginTransaction(){
return $this->handle->autocommit(FALSE);
}
public function commit(){
return $this->handle->commit();
}
public function rollBack(){
return $this->handle->rollback();
}
public function errorCode(){
return $this->handle->errno;
}
public function errorInfo(){
return array_values($this->handle->error_list);
}
public function setAttribute($attribute, $value, &$source = null)
{
switch($attribute)
{
case PDO::ATTR_AUTOCOMMIT:
$value = $value ? 1 : 0;
if(!$this->handle->autocommit($value))
{
throw new PDOException('set autocommit faild');
}
return true;
case PDO::ATTR_TIMEOUT:
$value = intval($value);
if($value > 1 && $this->handle->options( MYSQLI_OPT_CONNECT_TIMEOUT, $value))
{
$source[PDO::ATTR_TIMEOUT] = $value;
return true;
}
break;
case self::MYSQL_ATTR_LOCAL_INFILE:
$value = $value ? true : false;
if($this->handle->options(MYSQLI_OPT_LOCAL_INFILE, $value))
{
$source[self::MYSQL_ATTR_LOCAL_INFILE] = $value;
return true;
}
break;
case self::MYSQL_ATTR_INIT_COMMAND:
if($value && $this->handle->options( MYSQLI_INIT_COMMAND, $value))
{
$source[self::MYSQL_ATTR_INIT_COMMAND] = $value;
return true;
}
break;
case self::MYSQL_ATTR_READ_DEFAULT_FILE:
$value = $value ? true : false;
if($this->handle->options(MYSQLI_READ_DEFAULT_FILE, $value))
{
$source[self::MYSQL_ATTR_READ_DEFAULT_FILE] = $value;
return true;
}
break;
case self::MYSQL_ATTR_READ_DEFAULT_GROUP:
$value = $value ? true : false;
if($this->handle->options(MYSQLI_READ_DEFAULT_GROUP, $value))
{
$source[self::MYSQL_ATTR_READ_DEFAULT_GROUP] = $value;
return true;
}
break;
}
return false;
}
public function getAttribute($attribute){
if(PDO::ATTR_DRIVER_NAME == $attribute){
return 'mysql';
}
}
public function exec($statement){
$result = $this->handle->query($statement);
if(is_object($result)){
mysqli_free_result($result);
return 0;
}
return $this->handle->affected_rows;
}
public static function getAvailableDrivers(){
return array('mysql');
}
public function prepare($statement){
$this->tmpParams = array();
$newstatement = preg_replace_callback('/(:\w+)/i', function($matches){
$this->tmpParams[] = $matches[1];
return '?';
}, $statement);
$s = $this->handle->prepare($newstatement);
if($s==false) {
throw new PDOException($this->handle->error);
}
$ostatement = new PDO_Mysql_Statement($s, $this);
$ostatement->setPrepareParams($this->tmpParams);
$ostatement->setStateSql($statement);
return $ostatement;
}
public function lastInsertId(){
return $this->handle->insert_id;
}
public function quote($param,$parameter_type=-1){
switch($parameter_type)
{
case PDO::PARAM_BOOL:return $param ? 1 : 0;
case PDO::PARAM_NULL:return 'NULL';
case PDO::PARAM_INT: return is_null($param) ? 'NULL' : (is_int($param) ? $param : (float)$param);
default:return '\'' . $this->handle->real_escape_string($param) . '\'';
}
}
public function close(){
$this->handle->close();
}
public function disconnect(){
$this->close();
}
public function __destruct() {
$this->close();
}
}
class PDO_Mysql_Statement {
private $_statement = NULL;
private $_connnection = NULL;
private $_pql = 'unknow';
private $_typeMap = array(
'i'=>PDO::PARAM_INT,
's'=>PDO::PARAM_STR,
'd'=>PDO::PARAM_STR
);
private $prepareParams =array();//
private $readyTypes = array();
private $readyValues = array();
private $_result = NULL;
private $_mode = MYSQL_BOTH;
public function __construct($_statement,$connnection){
$this->_statement = $_statement;
$this->_connnection = $connnection;
}
public function bindParam($parameter,$value,$type){
$type = array_search($type, $this->_typeMap);
$key = array_search($parameter, $this->prepareParams);
if($key!==false and $type!==false){
$this->readyTypes[$key] = $type;
$this->readyValues[$key] = $value;
return true;
}else{
return false;
}
}
public function bindValue($parameter,$value,$type){
return $this->bindParam($parameter, $value, $type);
}
public function setStateSql($sql){
$this->_pql = $sql;
}
public function execute($options=array()){
if(!empty($this->readyTypes)){
$params =$this->readyValues;
ksort($params);
array_unshift($params,implode($this->readyTypes));
$tempstatement = $this->_statement;
call_user_func_array(array($tempstatement,'bind_param'),$this->refValues($params));
}
$this->_statement->execute();
}
public function rowCount(){
return $this->_statement->num_rows();
}
public function setFetchMode($mode){
$mode = $this->transformFetchMode($mode);
if($mode === false){
return false;
}
$this->_mode = $mode;
return true;
}
public function closeCursor(){
//$this->_result = NULL;
$this->prepareParams =array();
$this->readyTypes = array();
$this->readyValues = array();
$this->_pql = 'unknow';
$this->_mode = MYSQL_BOTH;
if(!empty($this->_result)){
$this->_result->free();
}
$this->_result = NULL;
//$this->_connnection->close();
return $this->_statement->reset();
}
public function columnCount(){
return $this->_statement->field_count;
}
public function debugDumpParams(){
echo $this->_pql;
}
public function errorCode(){
return $this->_statement->errno;
}
public function errorInfo(){
return array_values($this->_statement->error_list);
}
public function setPrepareParams($params){
$this->prepareParams = $params;
}
public function fetch($mode=NULL){
if($this->_result==NULL){
$this->_result = $this->_statement->get_result();
}
if(empty($this->_result)){
throw new PDOException($this->_statement->error);
}
$_mode = $this->_mode;
if(!empty($mode) and ($mode = $this->transformFetchMode($mode))!=false){
$_mode = $mode;
}
$result = $this->_result->fetch_array($_mode);
return $result === NULL ? false : $result;
}
public function fetchColumn($column_number=0){
$column = $this->fetch(PDO::FETCH_NUM);
return $column[$column_number];
}
public function fetchAll($mode=NULL){
if($this->_result==NULL){
$this->_result = $this->_statement->get_result();
}
if(empty($this->_result)){
throw new PDOException($this->_statement->error);
}
$_mode = $this->_mode;
if(!empty($mode) and ($mode = $this->transformFetchMode($mode))!=false){
$_mode = $mode;
}
$result = $this->_result->fetch_all($_mode);
return $result === NULL ? false : $result;
}
public function fetchObject(){
throw new PDOException('Not supported yet');
}
private function transformFetchMode($mode){
switch ($mode){
case PDO::FETCH_ASSOC : return MYSQLI_ASSOC;
case PDO::FETCH_BOTH : return MYSQLI_BOTH;
case PDO::FETCH_NUM : return MYSQLI_NUM;
default : return false;
}
}
private function refValues($arr){
$refs = array();
foreach($arr as $key => $value){
if($key!=0){
$refs[$key] = &$arr[$key];
}else{
$refs[$key] = $value;
}
}
return $refs;
}
public function __destruct(){
if(!empty($this->_result)) {
$this->_result->free();
}
if(!empty($this->_statement)){
$this->_statement->close();
}
}
}
모두 PDO 의 방법 입 니 다. 주석 을 달 지 않 고 index. php 에 두 줄 을 추 가 했 습 니 다.
/**
* pdo_mysql , , , components ;
* PDO_Mysql ,
*/
if(!in_array('mysql', PDO::getAvailableDrivers())){
$config = require($config);
$config['components']['db']['pdoClass'] = 'PDO_Mysql';
}
중간 에 할 수 없 는 질문 이 하나 더 있 습 니 다. Yii 의 CDbdataReader 는 Iterator 인 터 페 이 스 를 실 현 했 습 니 다. foreach 를 사용 하여 반복 할 때 PDOStatement: fetch () 는 줄 을 얻 지 못 할 때 boolean 으로 돌아 가 야 합 니 다. NULL 로 돌아 가 는 것 은 순환 입 니 다.
마지막 으로 위 정적 인 문 제 를 제기 합 니 다. 프레임 경로 의 방식 에 대해 nginx 설정 pathinfo 지원 은 번 거 로 울 뿐만 아니 라 일정한 위험 도 있 습 니 다. 사실은 크게 필요 하지 않 습 니 다. rewrite 하면 됩 니 다.
rewrite ^/html/(.*)$ /html/index.php?r=$1;
다른 관련 코드 와 설정 은 공유 하기 가 불편 합 니 다.
PS: stackoverflow 는 정말 좋 은 곳 입 니 다. 저 에 게 많은 문 제 를 해결 해 주 었 습 니 다. 예 를 들 어 이 refValues 방법 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
LimeSurvey HelloWorld 플러그인LimeSurvey 내의 명령줄에서 간단한 명령을 실행하려면 다음 코드가 필요합니다.upload/plugins 아래의 폴더 구조는 다음과 같아야 합니다. 헬로월드 config.xml HelloWorld.php Lim...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.