【问题标题】:mysqli prepare statement error "MySQL server has gone away"mysqli 准备语句错误“MySQL 服务器已消失”
【发布时间】:2019-03-16 17:47:27
【问题描述】:

我正在努力将程序式跳转到面向对象的样式,所以如果我的代码不整洁或有缺陷,请注意 - 在这里我通过 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;

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

【问题讨论】:

  • 您的错误消息表明 MySQL 正在超时,虽然它似乎是本地的,但我会确认 PHP 可以与数据库通信。
  • 我可以通过 PHP 运行 SELECT 语句,并且 UPDATE 查询作为标准查询运行,其中变量写入 SQL 字符串(根据注释代码) - 仅在 prepare 语句中失败。

标签: php mysql mysqli sql-update prepared-statement


【解决方案1】:

我查看了您的代码并找到了这个。

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

我写的几乎一样。但是我看到你将连接与准备函数分开了。

$db = $this->conn();

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

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

【讨论】:

    【解决方案2】:

    看来问题出在与数据库的连接上。这是(相关的)更新代码:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2018-01-30
        • 1970-01-01
        • 2014-06-11
        • 1970-01-01
        • 2015-11-25
        • 2012-06-28
        • 2011-12-18
        相关资源
        最近更新 更多