mysqli准备语句错误 "MySQL server has gone away"

3

我正在努力从过程式编程跳转到面向对象的编程风格,如果我的代码不整洁或有缺陷,请多多包涵 - 这里我通过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服务器已断开连接”。

您的错误信息表明MySQL超时了,尽管它似乎是本地的,但我会确认PHP能否与数据库通信。 - Absorbing
我可以通过PHP运行SELECT语句,并且UPDATE查询作为标准查询运行,变量写入SQL字符串中(如注释代码所示)- 只有准备语句会出现问题。 - Tricky
3个回答

4
我看了你的代码,发现了这个问题。
$stmt = $this->conn()->prepare("UPDATE tblorderhdr SET completed = ? WHERE orderid = ?");

我写的几乎一样。但我看到你将连接从准备函数中分离出来了。

$db = $this->conn();

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

我也不知道为什么,但现在它可以工作了。


1
似乎问题出在连接数据库上。这是更新后(相关的)代码:
$db = $this->conn();

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

$stmt->execute();

0
当您调用$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) {
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接