PHP Conference Japan 2024

执行语句

语句可以使用 mysqli::query()mysqli::real_query()mysqli::multi_query() 执行。 mysqli::query() 函数是最常用的,它将执行语句与任何结果集的缓冲提取组合在一个调用中。调用 mysqli::query() 等同于调用 mysqli::real_query() 后跟 mysqli::store_result()

示例 #1 执行查询

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("example.com", "user", "password", "database");

$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");

缓冲结果集

语句执行后,结果可以一次性全部检索,也可以逐行从服务器读取。客户端结果集缓冲允许服务器尽早释放与语句结果关联的资源。一般来说,客户端消耗结果集的速度较慢。因此,建议使用缓冲结果集。 mysqli::query() 将语句执行和结果集缓冲结合在一起。

PHP 应用程序可以自由地在缓冲结果中导航。导航速度很快,因为结果集存储在客户端内存中。请记住,通常通过客户端扩展比扩展服务器更容易。

示例 #2 在缓冲结果中导航

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("example.com", "user", "password", "database");

$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1), (2), (3)");

$result = $mysqli->query("SELECT id FROM test ORDER BY id ASC");

echo
"逆序...\n";
for (
$row_no = $result->num_rows - 1; $row_no >= 0; $row_no--) {
$result->data_seek($row_no);
$row = $result->fetch_assoc();
echo
" id = " . $row['id'] . "\n";
}

echo
"结果集顺序...\n";
foreach (
$result as $row) {
echo
" id = " . $row['id'] . "\n";
}

以上示例将输出

Reverse order...
 id = 3
 id = 2
 id = 1
Result set order...
 id = 1
 id = 2
 id = 3

非缓冲结果集

如果客户端内存资源短缺,并且不需要尽早释放服务器资源以保持服务器负载较低,则可以使用非缓冲结果。在读取所有行之前,无法滚动浏览非缓冲结果。

示例 #3 在非缓冲结果中导航

<?php

$mysqli
->real_query("SELECT id FROM test ORDER BY id ASC");
$result = $mysqli->use_result();

echo
"结果集顺序...\n";
foreach (
$result as $row) {
echo
" id = " . $row['id'] . "\n";
}

结果集值数据类型

mysqli::query()mysqli::real_query()mysqli::multi_query() 函数用于执行非预处理语句。在 MySQL 客户端服务器协议级别,命令 COM_QUERY 和文本协议用于语句执行。使用文本协议,MySQL 服务器在发送之前将结果集的所有数据转换为字符串。此转换与 SQL 结果集列数据类型无关。mysql 客户端库将所有列值接收为字符串。不会执行任何其他客户端转换以将列转换回其本机类型。相反,所有值都以 PHP 字符串的形式提供。

示例 #4 文本协议默认返回字符串

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("example.com", "user", "password", "database");

$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT, label CHAR(1))");
$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'a')");

$result = $mysqli->query("SELECT id, label FROM test WHERE id = 1");
$row = $result->fetch_assoc();

printf("id = %s (%s)\n", $row['id'], gettype($row['id']));
printf("label = %s (%s)\n", $row['label'], gettype($row['label']));

以上示例将输出

id = 1 (string)
label = a (string)

如果使用 mysqlnd 库,可以通过设置 **MYSQLI_OPT_INT_AND_FLOAT_NATIVE** 连接选项将整数和浮点数列转换回 PHP 数字。如果设置了该选项,mysqlnd 库将检查结果集元数据列类型,并在 PHP 数据类型值范围允许的情况下将数字 SQL 列转换为 PHP 数字。这样,例如,SQL INT 列将作为整数返回。

示例 #5 使用 mysqlnd 和连接选项获取原生数据类型

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

$mysqli = new mysqli();
$mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1);
$mysqli->real_connect("example.com", "user", "password", "database");

$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT, label CHAR(1))");
$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'a')");

$result = $mysqli->query("SELECT id, label FROM test WHERE id = 1");
$row = $result->fetch_assoc();

printf("id = %s (%s)\n", $row['id'], gettype($row['id']));
printf("label = %s (%s)\n", $row['label'], gettype($row['label']));

以上示例将输出

id = 1 (integer)
label = a (string)

参见

添加注释

用户贡献的注释

此页面没有用户贡献的注释。
To Top