mysqli prepare 语句错误"MySQL 服务器已消失"



我正在努力使跳转形式从程序到面向对象的样式,所以如果我的代码不整洁或有缺陷,请很好 - 在这里,我通过jQuery将几个帖子传递给一个类,以便在用户选中复选框时更新记录:

这是数据库连接

class db {

private $host ;      
private $username;
private $password;
private $dbname;

protected function conn()
{
$this->host = "localhost";
$this->username = "root";
$this->password = "";
$this->dbname = "mytest";

$db = new mysqli($this->host, $this->username,  $this->password, $this->dbname);

if($db->connect_errno > 0){
die('Unable to connect to database [' . $db->connect_error . ']');
}

return $db;

}

}

这是更新类

class updOrders extends db {
public $pid;
public $proc;
public function __construct()
{
$this->pid = isset($_POST['pid']) ? $_POST['pid'] : 0;
$this->proc = isset($_POST['proc']) ? $_POST['proc'] : 1;

// $stmt = $this->conn()->query("UPDATE tblorderhdr SET completed = ".$this->proc." WHERE orderid = ".$this->pid);
$stmt = $this->conn()->prepare("UPDATE tblorderhdr SET completed = ? WHERE orderid = ?");
$stmt->bind_param('ii', $this->proc, $this->pid);
$stmt->execute();
if($stmt->error)
{
$err = $stmt->error ;
} else {
$err = 'ok';
}

/* close statement */
$stmt->close();
echo json_encode($err);   
}

}
$test = new  updOrders;

当我注释掉 prepare 语句并直接运行查询(注释掉(时,它会更新,当我尝试将其作为 prepare 语句运行时,它会返回错误"MySQL 服务器已消失"。

我看过你的代码,我找到了这个。

$stmt = $this->conn()->prepare("UPDATE tblorderhdr SET completed = ? WHERE orderid = ?");

我写的几乎一样。但是我看到您将连接与准备功能分开。

$db = $this->conn();
$stmt = $db->prepare("UPDATE tblorderhdr SET completed = ? WHERE orderid = ?");

我也不知道为什么,但它现在有效。

问题似乎出在与数据库的连接中。这是(相关位(更新的代码:

$db = $this->conn();
$stmt = $db->prepare("UPDATE tblorderhdr SET completed = ? WHERE orderid = ?");
$stmt->bind_param('ii', $this->proc, $this->pid);
$stmt->execute();

当你调用$this->conn()时,你正在创建一个类mysqli的新连接对象。当没有更多的变量指向该对象时,PHP 将触发其析构函数。mysqli的析构函数将关闭连接。这意味着,如果不将此方法的返回值保存到变量中,则不再有指向该对象的引用,并且连接将被关闭。

要解决此问题,只需保存对象并重复使用它。不要每次都连接。

$conn = $this->conn();
$stmt = $conn->prepare("UPDATE tblorderhdr SET completed = ? WHERE orderid = ?");

附带说明一下,创建一个像你db的类是绝对没有意义的。此类不执行任何有用的操作。您尚未向 mysqli 添加任何额外的功能。永远不需要在属性中保存凭据。整个类可以替换为以下代码:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'user', 'password', 'test');
$mysqli->set_charset('utf8mb4'); // always set the charset

然后你的类将期望 mysqli 对象作为依赖项。

class updOrders {
public $pid;
public $proc;
public function __construct(mysqli $conn) {
}