简体   繁体   English

mysqli 准备语句错误“MySQL 服务器已消失”

[英]mysqli prepare statement error "MySQL server has gone away"

I'm struggling to make the jump form Procedural to Object Orientated style so if my code is untidy or flawed please be nice - here I'm passing a couple of posts via jQuery to a class to update a record when the user checks a checkbox:我正在努力使程序跳转到面向对象的样式,所以如果我的代码不整洁或有缺陷,请保持良好状态 - 在这里,我通过 jQuery 将一些帖子传递给一个类,以便在用户选中复选框时更新记录:

Here is the database connection这是数据库连接

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;
    
    }
            
}

Here is the update class这是更新类

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;

When I comment out the prepare statement and run the query directly (commented out) it updates, when I try and run it as a prepare statement it returns an error "MySQL server has gone away".当我注释掉准备语句并直接运行查询(注释掉)时,它会更新,当我尝试将它作为准备语句运行时,它返回错误“MySQL 服务器已消失”。

I have looked at your code and I found this.我看过你的代码,我找到了这个。

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

I wrote nearly the same.我写的几乎一样。 But I saw you separated the connection from the prepare function.但是我看到您将连接与准备功能分开了。

$db = $this->conn();

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

I don't know either why, but it works now.我也不知道为什么,但它现在有效。

It would appear that the problem lies within the connection to the database.问题似乎出在与数据库的连接中。 Here is the (relevant bit of the) updated code:这是(相关部分)更新的代码:

$db = $this->conn();

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

$stmt->execute();

When you call $this->conn() , you are creating a new connection object of class mysqli .当您调用$this->conn() ,您正在创建类mysqli的新连接对象。 When no more variables point to the object, PHP will trigger its destructor.当没有更多变量指向该对象时,PHP 将触发其析构函数。 The destructor for mysqli will close the connection. mysqli的析构函数将关闭连接。 This means that if you do not save the return value of this method into a variable, there will be no more references pointing to the object and the connection will be closed.这意味着如果你不将这个方法的返回值保存到一个变量中,将不会有更多指向该对象的引用,并且连接将被关闭。

To fix this, simply save the object and reuse it.要解决此问题,只需保存对象并重复使用即可。 Don't connect each time.不要每次都连接。

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

On a side note, creating a class like the one you have db is absolutely pointless.附带说明一下,创建一个像你有db是绝对没有意义的。 This class doesn't do anything useful.这个类没有做任何有用的事情。 You haven't added any extra functionality to mysqli.您尚未向 mysqli 添加任何额外功能。 You never need to save the credentials in properties.您永远不需要在属性中保存凭据。 The whole class can be replaced with this code:整个类可以用以下代码替换:

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

Then your classes will expect the mysqli object as a dependency.然后您的类将期望 mysqli 对象作为依赖项。

class updOrders {

public $pid;
public $proc;

public function __construct(mysqli $conn) {
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM