在我的服务器上我收到此错误
Fatal error: Call to undefined method mysqli_stmt::get_result() in /var/www/virtual/fcb/htdocs/library/mysqlidbclass.php on line 144
我有一个这样的包装:
<?php
/* https://github.com/aaron-lord/mysqli */
class mysqlidb {
/**
* Set up the database connection
*/
public function __construct($server,$user,$password,$db){
$this->connection = $this->connect($server, $user, $password, $db, true);
}
/**
* Connect to the database, with or without a persistant connection
* @param String $host Mysql server hostname
* @param String $user Mysql username
* @param String $pass Mysql password
* @param String $db Database to use
* @param boolean $persistant Create a persistant connection
* @return Object Mysqli
*/
private function connect($host, $user, $pass, $db, $persistant = true){
$host = $persistant === true ? 'p:'.$host : $host;
$mysqli = new mysqli($host, $user, $pass, $db);
if($mysqli->connect_error)
throw new Exception('Connection Error: '.$mysqli->connect_error);
$mysqli->set_charset('utf8');
return $mysqli;
}
/**
* Execute an SQL statement for execution.
* @param String $sql An SQL query
* @return Object $this
*/
public function query($sql){
$this->num_rows = 0;
$this->affected_rows = -1;
if(is_object($this->connection)){
$stmt = $this->connection->query($sql);
# Affected rows has to go here for query :o
$this->affected_rows = $this->connection->affected_rows;
$this->stmt = $stmt;
return $this;
}
else {
throw new Exception;
}
}
/**
* Prepare an SQL statement
* @param String $sql An SQL query
* @return Object $this
*/
public function prepare($sql){
unset($this->stmt);
$this->num_rows = 0;
$this->affected_rows = -1;
if(is_object($this->connection)){
# Ready the stmt
$this->stmt = $this->connection->prepare($sql);
if (false===$this->stmt)
{
print('prepare failed: ' . htmlspecialchars($this->connection->error)."<br />");
}
return $this;
}
else {
throw new Exception();
}
}
public function multi_query(){ }
/**
* Escapes the arguments passed in and executes a prepared Query.
* @param Mixed $var The value to be bound to the first SQL ?
* @param Mixed $... Each subsequent value to be bound to ?
* @return Object $this
*/
public function execute(){
if(is_object($this->connection) && is_object($this->stmt)){
# Ready the params
if(count($args = func_get_args()) > 0){
$types = array();
$params = array();
foreach($args as $arg){
$types[] = is_int($arg) ? 'i' : (is_float($arg) ? 'd' : 's');
$params[] = $arg;
}
# Stick the types at the start of the params
array_unshift($params, implode($types));
# Call bind_param (avoiding the pass_by_reference crap)
call_user_func_array(
array($this->stmt, 'bind_param'),
$this->_pass_by_reference($params)
);
}
if($this->stmt->execute()){
# Affected rows to be run after execute for prepares
$this->affected_rows = $this->stmt->affected_rows;
return $this;
}
else {
throw new Exception($this->connection->error);
}
}
else {
throw new Exception;
}
}
/**
* Fetch all results as an array, the type of array depend on the $method passed through.
* @param string $method Optional perameter to indicate what type of array to return.'assoc' is the default and returns an accociative array, 'row' returns a numeric array and 'array' returns an array of both.
* @param boolean $close_stmt Optional perameter to indicate if the statement should be destroyed after execution.
* @return Array Array of database results
*/
public function results($method = 'assoc', $close_stmt = false){
if(is_object($this->stmt)){
$stmt_type = get_class($this->stmt);
# Grab the result prepare() & query()
switch($stmt_type){
case 'mysqli_stmt':
$result = $this->stmt->get_result();
$close_result = 'close';
break;
case 'mysqli_result':
$result = $this->stmt;
$close_result = 'free';
break;
default:
throw new Exception;
}
$this->num_rows = $result->num_rows;
# Set the results type
switch($method) {
case 'assoc':
$method = 'fetch_assoc';
break;
case 'row':
//return 'fetch_row';
$method = 'fetch_row';
break;
default:
$method = 'fetch_array';
break;
}
$results = array();
while($row = $result->$method()){
$results[] = $row;
}
$result->$close_result();
return $results;
}
else {
throw new Exception;
}
}
/**
* Turns off auto-committing database modifications, starting a new transaction.
* @return bool Dependant on the how successful the autocommit() call was
*/
public function start_transaction(){
if(is_object($this->connection)){
return $this->connection->autocommit(false);
}
}
/**
* Commits the current transaction and turns auto-committing database modifications on, ending transactions.
* @return bool Dependant on the how successful the autocommit() call was
*/
public function commit(){
if(is_object($this->connection)){
# Commit!
if($this->connection->commit()){
return $this->connection->autocommit(true);
}
else {
$this->connection->autocommit(true);
throw new Exception;
}
}
}
/**
* Rolls back current transaction and turns auto-committing database modifications on, ending transactions.
* @return bool Dependant on the how successful the autocommit() call was
*/
public function rollback(){
if(is_object($this->connection)){
# Commit!
if($this->connection->rollback()){
return $this->connection->autocommit(true);
}
else {
$this->connection->autocommit(true);
throw new Exception;
}
}
}
/**
* Return the number of rows in statements result set.
* @return integer The number of rows
*/
public function num_rows(){
return $this->num_rows;
}
/**
* Gets the number of affected rows in a previous MySQL operation.
* @return integer The affected rows
*/
public function affected_rows(){
return $this->affected_rows;
}
/**
* Returns the auto generated id used in the last query.
* @return integer The last auto generated id
*/
public function insert_id(){
if(is_object($this->connection)){
return $this->connection->insert_id;
}
}
/**
* Fixes the call_user_func_array & bind_param pass by reference crap.
* @param array $arr The array to be referenced
* @return array A referenced array
*/
private function _pass_by_reference(&$arr){
$refs = array();
foreach($arr as $key => $value){
$refs[$key] = &$arr[$key];
}
return $refs;
}
}
?>
有没有办法使用其他功能,以便我不必重写整个应用程序?请告诉我是否有。
答案 0 :(得分:1)
请阅读此方法的用户说明:
http://php.net/manual/en/mysqli-stmt.get-result.php
它需要mysqlnd驱动程序。如果您的网站空间没有安装,则必须使用BIND_RESULT
&amp; FETCH
http://www.php.net/manual/en/mysqli-stmt.bind-result.php
http://www.php.net/manual/en/mysqli-stmt.fetch.php
摘自here
答案 1 :(得分:0)
此错误的原因是您的服务器没有安装mysqlnd驱动程序驱动程序。 (请参阅here。)如果您拥有管理员权限,则可以自行安装,但也有更简单的方法:
我编写了两个简单的函数,它们提供与$stmt->get_result();
相同的功能,但它们不需要mysqlnd驱动程序。
您只需替换
$result = $stmt->get_result();
$fields = bindAll($stmt);
和
$row= $stmt->get_result();
$row = fetchRowAssoc($stmt, $fields);
。
(要获取返回的行数,可以使用$stmt->num_rows
。)
你只需要放置这两个函数我已经在PHP脚本的某处编写了。 (例如在底部)
function bindAll($stmt) {
$meta = $stmt->result_metadata();
$fields = array();
$fieldRefs = array();
while ($field = $meta->fetch_field())
{
$fields[$field->name] = "";
$fieldRefs[] = &$fields[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $fieldRefs);
$stmt->store_result();
//var_dump($fields);
return $fields;
}
function fetchRowAssoc($stmt, &$fields) {
if ($stmt->fetch()) {
return $fields;
}
return false;
}
工作原理:
我的代码使用$stmt->result_metadata();
函数来确定返回了多少和哪些字段,然后自动将获取的结果绑定到预先创建的引用。像魅力一样工作!
同时发布了here。