Getting error with prepared statement query
我现在已经面临几天的问题了,我一直盯着它,似乎自己也找不到来源。
我已经建立了一个类来执行查询。实际的查询执行部分如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | <?php public function query( $method, $table, $data, $where_text='', $where_data='' ) { $this->check_db_status(); $method = strtoupper( $method ); $fieldsArray = array(); $valuesArray = array(); $paramsArray = array(); $format = ''; $queryText = ''; switch( $method ) { case 'SELECT' : $queryText = 'SELECT %s FROM ' . $table . ' '; foreach( $data as $field => $value ) { $fieldsArray[] = $value; } break; case 'UPDATE' : $queryText = 'UPDATE ' . $table . ' SET %s '; foreach( $data as $field => $value ) { $fieldsArray[] = $field.'=?'; $format .= $this->get_value_type( $value ); $paramsArray[] = $value; } break; case 'DELETE' : $queryText = 'DELETE FROM ' . $table . ' '; break; case 'INSERT' : $queryText = 'INSERT INTO ' . $table . ' (%s) VALUES (%s) '; foreach( $data as $field => $value ) { $fieldsArray[] = $field; $format .= $this->get_value_type( $value ); $valuesArray[] = '?'; $paramsArray[] = $value; } break; default : $this->get_error( 'Error in method switch' ); break; } if( $where_text ) { $queryText .= $where_text; if( $where_data ) { foreach( $where_data as $value ) { $format .= $this->get_value_type( $value ); $paramsArray[] = $value; } } } $fields = implode( ',', $fieldsArray ); $values = implode( ',', $valuesArray ); $query = sprintf( $queryText, $fields, $values ); // DEBUG echo '[cc lang="php"]'; echo 'query: ' . $query . '<br /> echo 'format: ' .' . $format . '<br />'; print_r( $paramsArray ); echo ' |
';
$ stmt = $ this-> mysqli-> prepare($ query);
if($ stmt === false或$ stmt == NULL){
$ this-> get_error('准备语句时出错');
}
if($ format和$ paramsArray)
call_user_func_array('mysqli_stmt_bind_param',array_merge(array($ stmt,$ format),$ paramsArray));
if($ stmt-> execute()){
$ result = 0;
开关($ method){
案例'INSERT':
$ result =($ stmt-> insert_id)吗? $ stmt-> insert_id:true;
打破;
案例'UPDATE':
案例"删除":
$结果=($ stmt-> affected_rows)? $ stmt-> affected_rows:true;
打破;
案例'SELECT':
$ meta = $ stmt-> result_metadata();
$ fields = $ result = array();
而($ field = $ meta-> fetch_field()){
$ var = $ field-> name;
$$ var = null;
$ fields [$ var] =&$$ var;
}
call_user_func_array(array($ stmt,'bind_result'),$ fields);
$ i = 0;
while($ stmt-> fetch()){
$ result [$ i] = array();
foreach($ fields as $ k => $ v)
$ result [$ i] [$ k] = $ v;
$ i ++;
}
打破;
}
$ stmt-> close();
$ this-> query_cnt ++;
返回$ result;
}
其他{
$ this-> get_error();
}
}
?>
code> pre>
现在,我试图制作另一个类来将会话存储在自己的数据库中。写函数如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php public function write_session( $session_id, $session_data ) { $query = $this->sql->query( 'INSERT', 'sessions', array( 'ses_id'=>$session_id, 'ses_time'=>time(), 'ses_start'=>time(), 'ses_data'=>$session_data, 'ses_check'=>$this->check ), 'ON DUPLICATE KEY UPDATE ses_time=?, ses_data=?', array(time(),$session_data)); if($query) { return true; } else { return false; } } ?> |
我不断收到此错误:
1 | Warning: mysqli::prepare() [mysqli.prepare]: Couldn't fetch mysqli in /.../class.db.php on line 124 |
第124行是带有
如果放在数据库类的调试部分中以显示查询,它将给出以下输出:
1 2 3 4 5 6 7 8 9 10 11 12 | query: INSERT INTO sessions (ses_id,ses_time,ses_start,ses_data,ses_check) VALUES (?,?,?,?,?) ON DUPLICATE KEY UPDATE ses_time=?, ses_data=? format: [siissis] Array ( [0] => a98696a8416fc898f2c07e05f39735dc [1] => 1402201705 [2] => 1402201705 [3] => test|s:11:"someValuess"; [4] => 40b17cb572d9bf5eaadad99b7904e0a4889a31d0 [5] => 1402201705 [6] => test|s:11:"someValuess"; ) |
在我看来,这很好。...我在俯视什么?
编辑
会话表定义:
1 2 3 4 5 6 7 8 | sessions ( ses_id varchar(32) NOT NULL, ses_time int(11) NOT NULL, ses_start int(11) NOT NULL, ses_data text NOT NULL, ses_check varchar(40) NOT NULL, PRIMARY KEY (ses_id) ) |
在评论中提供的链接中指出,您的问题似乎是
4.您混合了对数据库对象的OOP和功能调用。
具体来说,您在此处使用
1 | $stmt = $this->mysqli->prepare( $query ); |
但是然后继续在此处进行功能性
1 2 | if( $format and $paramsArray ) call_user_func_array( 'mysqli_stmt_bind_param', array_merge( array( $stmt, $format ), $paramsArray ) ); |
因此,请尝试使用相应的OOP版本替换上面的代码
1 2 3 | if($format and $paramsArray) { $stmt->bind_param($format,$paramsArray); } |
也更换
1 |
用
1 | $stmt->bind_param($format,$fields); |
http://www.php.net//manual/en/mysqli-stmt.bind-param.php
实现__唤醒
另一种可能性是由于序列化,您的数据库连接可能已关闭。 尝试通过实现
1 2 3 4 | public function __wakeup() { $this->mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db'); } |