语句可以使用 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 库将检查结果集元数据列类型,并将数字 SQL 列转换为 PHP 数字,前提是 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)
参见