【问题标题】:php mysqli::$insert_id -> not working properlyphp mysqli::$insert_id -> 无法正常工作
【发布时间】:2021-04-13 12:29:12
【问题描述】:

我想插入一行,同时获取该查询生成的 id。

我只是先对其进行测试,到目前为止,这就是我得到的。

我创建了一个具有这样的数据库配置的类

class Database{

     private $host;
     ...
     ...

     protected function connect(){
        $this->host = 'localhost';
        ...
        ... 

        $conn = new mysqli($this->host, ...,);

        if ($conn->connect_errno){ 
           echo 'error'; 
        };
        
        return $conn;         
     }
}

一个用于实际查询的用户类以及我扩展数据库类的位置。

class User extends Database{

    function createUser(...,){
        $sql = "INSERT INTO t (field) VALUES ('value');";
        $this->connect()->query($sql);
        return $this->connect()->insert_id;
    }
}

我的表中已经插入了数据,但函数返回 0。

注意: 我在 AUTO_INCREMENT 属性的用户表上有我的列 ID。

查询成功但没有返回正确的ID。

我尝试在没有 Database 类的情况下执行此操作,它工作正常,返回查询生成的 ID。

$mysqli = new mysqli('host', ...,);
if(result = $mysqli->query("INSERT INTO t (field) VALUES ('value');")){
    return $mysqli->insert_id;
}

【问题讨论】:

  • createUser 方法在哪里以及如何使用?你在哪里关闭连接?它返回的是哪个 id(前一个,前两个查询...)?
  • 当你第二次调用connect() 时,这不是创建一个新的数据库连接吗?如果是这样,那么它不会返回 last-insert-id,因为没有一个 用于该数据库连接
  • 直到你提到它,我才注意到伙计们。这段代码写得不好,也许我会用其他方式。

标签: php mysqli


【解决方案1】:

不要这样做!您的 Datebase 类没有用,并且没有遵循 OOP 的最佳实践。

您的问题是每次调用$this->connect() 时都会创建一个新连接。连接之间不共享状态,因此您无法使用不同的连接访问最后插入的 ID。它必须是相同的连接!

不要写像Database这样的类,除非你真的要写抽象库,并且永远不要从Database类继承。

mysqli 本身就是一个类。使用 mysqli 打开数据库连接只需要 3 行代码。

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

然后您可以将实例传递给任何需要它的类。

class User {
    private mysqli $db;

    public function __construct(mysqli $mysqli) {
        $this->db = $mysqli;
    }

    function createUser(/* ... */) {
        $stmt = $this->db->prepare("INSERT INTO t (field) VALUES (?)");
        $stmt->bind_param('s', $value);
        $stmt->execute();
        return $this->db->insert_id;
    }
}

$user = new User($mysqli);

您必须始终使用准备好的语句,因为它允许您对查询进行参数化。永远不要将数据直接连接到 SQL 中。

最后,不要单独使用 mysqli。它不适合初学者,也不适合单独使用。如果您只是开始学习 PHP,那么您应该学习 PDO 而不是 mysqli。 PDO 更容易,更适合初学者。从这里开始https://phpdelusions.net/pdo

【讨论】:

  • 只传递 db 配置的实例而不是创建类的想法更有意义,也会尝试一下。谢谢!
【解决方案2】:

问题出在您的 Database 类中。 你需要一个 $conn 字段。 调用connect() 会导致每次都创建新连接。

class Database{

 private $host;
 private $conn;
 ...
 ...

 protected function connect(){
    $this->host = 'localhost';
    ...
    ... 

    $this->conn = new mysqli($this->host, ...,);

    if ($this->conn->connect_errno){ 
       echo 'error'; 
    };        
 }
}
class User extends Database{

    function createUser(...,){
        $sql = "INSERT INTO t (field) VALUES ('value');";
        $this->conn->query($sql);
        return $this->conn->insert_id;
    }
}

【讨论】:

  • 谢谢!没有意识到我在第二次调用 connect 函数时正在创建一个新的数据库连接。
猜你喜欢
  • 2016-01-18
  • 2023-04-07
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 2011-08-16
  • 2011-07-27
  • 2015-11-15
  • 1970-01-01
相关资源
最近更新 更多