PHP Conference Japan 2024

mysqli_stmt::execute

mysqli_stmt_execute

(PHP 5, PHP 7, PHP 8)

mysqli_stmt::execute -- mysqli_stmt_execute执行预处理语句

描述

面向对象风格

public mysqli_stmt::execute(?array $params = null): bool

过程化风格

mysqli_stmt_execute(mysqli_stmt $statement, ?array $params = null): bool

执行之前准备好的语句。在执行之前,必须使用 mysqli_prepare()mysqli_stmt_prepare() 函数成功准备语句,或者通过将第二个参数传递给 mysqli_stmt::__construct() 来准备。

如果语句是 UPDATEDELETEINSERT,则可以使用 mysqli_stmt_affected_rows() 函数确定受影响的行总数。如果查询产生结果集,则可以使用 mysqli_stmt_get_result() 函数获取结果集,或者使用 mysqli_stmt_fetch() 函数逐行直接从语句中获取结果集。

参数

statement

仅过程化风格:由 mysqli_stmt_init() 返回的 mysqli_stmt 对象。

params

一个可选的 array 列表,其元素数量与正在执行的 SQL 语句中绑定的参数数量相同。每个值都被视为 string

返回值

成功时返回 true,失败时返回 false

错误/异常

如果启用了 mysqli 错误报告 (MYSQLI_REPORT_ERROR) 并且请求的操作失败,则会生成警告。此外,如果模式设置为 MYSQLI_REPORT_STRICT,则会抛出 mysqli_sql_exception

变更日志

版本 描述
8.1.0 添加了可选的 params 参数。

示例

示例 #1 使用绑定变量执行预处理语句

面向对象风格

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

$mysqli->query("CREATE TEMPORARY TABLE myCity LIKE City");

/* 准备插入语句 */
$stmt = $mysqli->prepare("INSERT INTO myCity (Name, CountryCode, District) VALUES (?,?,?)");

/* 将变量绑定到参数 */
$stmt->bind_param("sss", $val1, $val2, $val3);

$val1 = 'Stuttgart';
$val2 = 'DEU';
$val3 = 'Baden-Wuerttemberg';

/* 执行语句 */
$stmt->execute();

$val1 = 'Bordeaux';
$val2 = 'FRA';
$val3 = 'Aquitaine';

/* 执行语句 */
$stmt->execute();

/* 从 myCity 中检索所有行 */
$query = "SELECT Name, CountryCode, District FROM myCity";
$result = $mysqli->query($query);
while (
$row = $result->fetch_row()) {
printf("%s (%s,%s)\n", $row[0], $row[1], $row[2]);
}

过程化风格

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

mysqli_query($link, "CREATE TEMPORARY TABLE myCity LIKE City");

/* 准备插入语句 */
$stmt = mysqli_prepare($link, "INSERT INTO myCity (Name, CountryCode, District) VALUES (?,?,?)");

/* 将变量绑定到参数 */
mysqli_stmt_bind_param($stmt, "sss", $val1, $val2, $val3);

$val1 = 'Stuttgart';
$val2 = 'DEU';
$val3 = 'Baden-Wuerttemberg';

/* 执行语句 */
mysqli_stmt_execute($stmt);

$val1 = 'Bordeaux';
$val2 = 'FRA';
$val3 = 'Aquitaine';

/* 执行语句 */
mysqli_stmt_execute($stmt);

/* 从 myCity 中检索所有行 */
$query = "SELECT Name, CountryCode, District FROM myCity";
$result = mysqli_query($link, $query);
while (
$row = mysqli_fetch_row($result)) {
printf("%s (%s,%s)\n", $row[0], $row[1], $row[2]);
}

以上示例将输出

Stuttgart (DEU,Baden-Wuerttemberg)
Bordeaux (FRA,Aquitaine)

示例 #2 使用值数组执行预处理语句

面向对象风格

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'world');

$mysqli->query('CREATE TEMPORARY TABLE myCity LIKE City');

/* 准备插入语句 */
$stmt = $mysqli->prepare('INSERT INTO myCity (Name, CountryCode, District) VALUES (?,?,?)');

/* 执行语句 */
$stmt->execute(['Stuttgart', 'DEU', 'Baden-Wuerttemberg']);

/* 从 myCity 中检索所有行 */
$query = 'SELECT Name, CountryCode, District FROM myCity';
$result = $mysqli->query($query);
while (
$row = $result->fetch_row()) {
printf("%s (%s,%s)\n", $row[0], $row[1], $row[2]);
}

过程化风格

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = mysqli_connect('localhost', 'my_user', 'my_password', 'world');

mysqli_query($link, 'CREATE TEMPORARY TABLE myCity LIKE City');

/* 准备插入语句 */
$stmt = mysqli_prepare($link, 'INSERT INTO myCity (Name, CountryCode, District) VALUES (?,?,?)');

/* 执行语句 */
mysqli_stmt_execute($stmt, ['Stuttgart', 'DEU', 'Baden-Wuerttemberg']);

/* 从 myCity 中检索所有行 */
$query = 'SELECT Name, CountryCode, District FROM myCity';
$result = mysqli_query($link, $query);
while (
$row = mysqli_fetch_row($result)) {
printf("%s (%s,%s)\n", $row[0], $row[1], $row[2]);
}

以上示例将输出

Stuttgart (DEU,Baden-Wuerttemberg)

参见

添加注释

用户贡献的注释 1 条注释

Typer85 at gmail dot com
17 年前
仅澄清手册中关于此函数的此注释

"注意:使用 mysqli_stmt_execute() 时,必须在执行任何其他查询之前使用 mysqli_stmt_fetch() 函数来获取数据。"

这是因为此函数不会在客户端存储结果集,因此您必须获取结果集中的所有内容,否则您将面临重大错误。

但是,如果您在使用此函数后立即使用 mysqli_stmt_store_result 函数,则强制将结果集存储在客户端,因此在获取所有数据之前发出额外的查询是安全的。

这正是您必须在应用程序的优先级方面做出选择的地方。如果您知道您的结果集内存占用量很大,那么最好不要将其存储在客户端,这样您就不会遇到服务器上可用内存不足的任何错误。但这同时也意味着您不会对结果集进行大量计算,否则您将阻止对结果集来自的表的任何其他使用,直到您获取所有数据为止。

如果您要进行大量计算或您的结果集内存占用量不大,最好将其存储在客户端。

如果您在服务器上有大量可用内存,大多数这些问题都可以轻松解决,但这对于共享主机上的用户通常并非如此。

如果您在共享主机上,解决此问题的明智方法是巧妙地设计您的查询。如果您知道将获取内存占用量大的结果集,请尝试限制结果集。

测试应用程序的不同替代方案,并查看在不同条件下哪些最适合您。

祝您好运,
To Top