之前我已经看过这个问题,但所有的解决方案对我都不起作用。主要解决方案是存储我已经完成的结果。大多数人说我正在运行2个同时发生的查询,我不明白。我可能不止一次使用过这个函数,但我总是自由地关闭语句,所以不确定为什么会发生这种情况。
您很可能忽略函数的上半部分,它只生成一个字符串来表示类型。这是我制作的完整数据库类:
(自从我最初发布以来,我编辑了它并用self :: $ db替换了self :: $ connection)
class DB {
private static $dbhost = "localhost";
private static $dbuser = "some_user"; // placeholder
private static $dbpass = "some_assword"; // placeholder
private static $dbname = "database_name"; // placeholder
private static $db;
public static function connect() {
self::$db = new mysqli(self::$dbhost, self::$dbuser, self::$dbpass, self::$dbname);
if (self::$db->connect_errno) {
die("Database mysqli failed: " .
self::$db->connect_error . " (" .
self::$db->connect_errno . ")"
);
}
}
// IGNORE THIS! It just formats the parameters for the
// call_user_func_array function to work correctly.
private static function getBindings(&$params) {
$types = "";
$bindings = array();
foreach ($params as $value) {
switch (gettype($value)) {
case "integer":
$types .= "i";
break;
case "double":
$types .= "d";
break;
case "string":
$types .= "s";
break;
default:
$types .= "s";
break;
}
}
foreach($params as $key => $value)
$bindings[$key] = &$params[$key]; // assign to references (because bind_param requires references)
// to add a string of variable types to the start of the $bindings array (such as 'sss')
array_unshift($bindings, $types);
return $bindings;
}
public static function query($query, $params) {
if (!isset(self::$db)) { self::connect(); }
if (empty($params)) {
// prepared statement not needed
return self::$db->query($query);
}
$successful = false;
$bindings = self::getBindings($params);
// MySQL prepared statement execution:
$statement = self::$db->prepare($query);
call_user_func_array(array($statement, 'bind_param'), $bindings);
$statement->execute();
$statement->store_result();
if ($statement->num_rows > 0) {
// for select queries
$successful = $statement->get_result(); // does not work! (returns boolean)
echo self::$db->errno; // 2014
echo "<br />";
echo self::$db->error; // Commands out of sync; you can't run this command now
echo "<br />";
// this method works fine (but I need to return the result set!):
/*$name = false; $link = false;
$statement->bind_result($name, $link);
while ($statement->fetch()) {
echo 'name: '.$name.'<br>';
echo 'link: '.$link.'<br>';
}*/
} else if ($statement->affected_rows > 0) {
// for insert queries
$successful = true;
}
$statement->free_result();
$statement->close();
return $successful;
}
public static function close() {
if (isset(self::$db)) self::$db->close();
}
}
编辑:这是我的一个请求看起来(我使用我的DB类和DB :: query(...)函数在同一页面上查询了2个请求):
$result = DB::query("SELECT * FROM table_name;");
if ($result) {
while ($row = $result->fetch_assoc()) {
// do stuff
}
$result->close();
}
答案 0 :(得分:2)
为了热爱理智,将驱动程序更改为PDO并将所有代码转换为
public static function query($query, $params = NULL)
{
if (!$params) {
return self::$connection->query($query);
}
$statement = self::$connection->prepare($query);
$statement->execute($params);
return $statement;
}
像这样使用
$result = DB::query("SELECT * FROM table_name");
foreach($result as $row) {
// do stuff
}
答案 1 :(得分:-1)
关于Commands out of sync的MySQL文档提出了两种可能性:
代码中的逻辑显示了当不需要预准备语句时,您没有释放结果的唯一情况。你的问题的答案可能是处理这个特定的结果,并免费或存储它。
我可以从您的代码中看到self::$connection
是一个静态引用,因此在该范围内执行的任何查询都可能使用相同的连接。如果没有能够看到你的全班,很难分辨。