gpt4 book ai didi

php - Insert_id 在下一个准备好的语句中直接使用时为 null

转载 作者:行者123 更新时间:2023-12-05 05:27:31 32 4
gpt4 key购买 nike

终于开始学习准备好的语句了。尝试运行一对简单的插入时,我遇到了一个令人抓狂的错误:

$p_stmt = $mysqli->prepare("INSERT INTO ww_pages (page_key) VALUES (?)");
$p_stmt->bind_param('s', $page_key);
$p_stmt->execute();

$pv_stmt = $mysqli->prepare("INSERT INTO ww_page_versions (page_id, page_title, page_content, version_notes, version_timestamp) VALUES (?, ?, ?, ?, ?)");
$pv_stmt->bind_param('issss', $p_stmt->insert_id, $page_title, trim($_POST["page_content"]), trim($_POST["version_notes"]), date("Y-m-d H:i:s"));
$pv_stmt->execute();
echo $pv_stmt->error;

echo $pv_stmt->error; 给出了这个错误:Column 'page_id' cannot be null

我相信您可以理解,我正在尝试将 page_id 分配给第一条语句的 insert_id。我 100% 确定这个值是非空的,并返回一个整数值。我直接用这个测试了它:

echo "NEW ID: ".$p_stmt->insert_id."::".is_int($p_stmt->insert_id);

输出? 新 ID:13::1

我做错了什么?当列不为空时,为什么我会收到“列不能为空”?我能在网上找到的唯一解决方案涉及意外的空值。

最佳答案

此问题的解决方案是将属性 $p_stmt->insert_id 的值保存在一个变量中,然后绑定(bind)该变量。无论如何,您必须对 trim()date() 执行相同的操作,尽管出于不同的原因。

$insert_id = $p_stmt->insert_id;
$page_content = trim($_POST["page_content"]);
$version_notes = trim($_POST["version_notes"]);
$date = date("Y-m-d H:i:s");
$pv_stmt->bind_param('issss', $insert_id, $page_title, $page_content, $version_notes, $date);

从 PHP 8.1 开始,当您将所有值作为数组传递给 execute() 时,您还可以按值绑定(bind)。不需要临时变量。

$pv_stmt = $mysqli->prepare("INSERT INTO ww_page_versions (page_id, page_title, page_content, version_notes, version_timestamp) VALUES (?, ?, ?, ?, ?)");
$pv_stmt->execute([$p_stmt->insert_id, $page_title, trim($_POST["page_content"]), trim($_POST["version_notes"]), date("Y-m-d H:i:s")]);

为什么绑定(bind) insert_id 不起作用的解释

绑定(bind) mysqli_stmt::insert_id 导致值 NULL 的原因在 PHP 8.1 上变得更加清晰。从这个版本开始,PHP 已经为大多数内置类添加了属性类型,即使是那些不是真正的属性而是 __get() 调用的属性也是如此。使用 PHP 8.1 时会出现以下错误:

Fatal error: Uncaught Error: Cannot access uninitialized non-nullable property mysqli_stmt::$insert_id by reference

PHP 声明该属性未初始化,您不能引用未初始化的属性。您可以使用此代码模仿相同的行为:

class A {
public int $insert_id;
}

$a = new A();

$stmt = $mysqli->prepare('SELECT ?');
$stmt->bind_param('s', $a->insert_id);
$stmt->execute();

出于同样的原因,通过对变量的引用赋值是行不通的:

$foo =& $p_stmt->insert_id;

但是您可能会问,当您可以毫无问题地读取其值时,该属性怎么可能未初始化。答案是因为在内部这些属性是使用 PHP 中的函数调用实现的,类似于 __get() 魔术方法。该值是从 mysqlnd 的内部内存中读取的,而不是从属性本身读取的。 mysqli 的属性只是底层客户端库 mysqlnd 的外观。

关于php - Insert_id 在下一个准备好的语句中直接使用时为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19250042/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com