各位观众老爷,大家好!我是今天的主讲人,老码农小李。今天咱们来聊聊 WordPress 里面那个神秘又常用的 wpdb
类,特别是它的 query_as_array()
方法。这玩意儿能把数据库查询结果变成咱们熟悉的关联数组,用起来那叫一个顺手。
咱们今天的目标就是:扒开它的底裤,看看它到底是怎么运作的!
一、wpdb
类,你是谁?
在深入 query_as_array()
之前,咱们先简单认识一下 wpdb
类。你可以把它想象成 WordPress 访问数据库的“总代理”。它封装了各种数据库操作,让你不用直接写那些复杂的 SQL 语句(当然,如果你喜欢,也可以直接写)。
wpdb
类提供了很多方法,比如 query()
、get_results()
、get_row()
等等,它们的功能各不相同,但最终目的都是为了从数据库里捞数据。
二、query_as_array()
:化腐朽为神奇
query_as_array()
方法,顾名思义,就是把查询结果转换成数组的。更准确地说,是关联数组,也就是可以用字段名作为键来访问数据的数组。
它的基本用法是这样的:
global $wpdb;
$results = $wpdb->query_as_array("SELECT * FROM wp_posts LIMIT 10");
if ($results) {
foreach ($results as $row) {
echo "Post Title: " . $row['post_title'] . "<br>";
echo "Post Content: " . $row['post_content'] . "<br>";
}
} else {
echo "No posts found.";
}
这段代码会从 wp_posts
表里取出前 10 条记录,然后把每条记录都转换成一个关联数组,方便你直接通过字段名访问数据。
三、源码剖析:一层一层扒开你的心
好了,废话不多说,直接上源码!(以下代码基于 WordPress 6.3.1 版本,不同版本可能会有细微差异):
/**
* Perform a query and return the entire result set as an array of associative arrays.
*
* This is a wrapper around {@see wpdb::get_results()}.
*
* @since 5.5.0
*
* @param string|null $query Optional. The SQL query to execute. Can be null to return the last query results.
* Default null.
* @param int $output Optional. The required return type. One of ARRAY_A, ARRAY_N, or OBJECT.
* Default ARRAY_A.
* @param int $y Optional. Offset of the returned row. Default 0.
* @return array|null An array of associative arrays representing the query result.
* Null if there is an error or no rows were returned.
*/
public function query_as_array( ?string $query = null, int $output = ARRAY_A, int $y = 0 ) {
return $this->get_results( $query, $output, $y );
}
看到没?query_as_array()
实际上只是 get_results()
方法的一个“马甲”!它只是简单地把 output
参数设置成了 ARRAY_A
,然后调用了 get_results()
。
所以,咱们的重点就转移到 get_results()
方法上了。
/**
* Perform a query and return the entire result set as an array.
*
* By default, returns an array of associative arrays, as in
* {@link https://www.php.net/mysqli_fetch_assoc mysqli_fetch_assoc()}.
*
* @since 2.0.0
* @since 3.5.0 The `$output` parameter accepts OBJECT, ARRAY_A, or ARRAY_N.
*
* @global wpdb $wpdb WordPress database abstraction object.
*
* @param string|null $query Optional. The SQL query to execute. Can be null to return the last query results.
* Default null.
* @param string $output Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N.
* Default OBJECT.
* @param int $y Optional. Offset of the returned row. Default 0.
* @return array|object|null An array of results (usually associative arrays), null if there is an error.
*/
public function get_results( ?string $query = null, string $output = OBJECT, int $y = 0 ) {
global $wpdb;
// Bail early if there is no query to execute.
if ( empty( $query ) && empty( $this->last_query ) ) {
return null;
}
// Set the query to execute.
if ( empty( $query ) ) {
$query = $this->last_query;
}
// Clear the last result.
$this->last_result = null;
// Execute the query.
$result = $this->query( $query );
// Bail if there is an error.
if ( ! $result ) {
return null;
}
// Initialize variables to store the results.
$i = 0;
$j = 0;
$num_rows = $this->num_rows;
// If there are rows to return.
if ( $num_rows ) {
$this->last_result = array();
// Move the internal data pointer to the start of the result set.
if ( $y != 0 ) {
mysqli_data_seek( $this->dbh, $y );
}
// Fetch the results.
while ( $i < $num_rows ) {
if ( $output == OBJECT ) {
$this->last_result[ $i ] = mysqli_fetch_object( $this->dbh );
} elseif ( $output == ARRAY_A ) {
$this->last_result[ $i ] = mysqli_fetch_assoc( $this->dbh );
} elseif ( $output == ARRAY_N ) {
$this->last_result[ $i ] = mysqli_fetch_row( $this->dbh );
} else {
$this->last_result[ $i ] = mysqli_fetch_object( $this->dbh );
}
if ( $y != 0 && $i == $y ) {
break;
}
$i++;
}
// If we want a single row, return it.
if ( $i == 1 && ! empty( $this->last_result ) ) {
$this->last_result = $this->last_result[0];
}
mysqli_free_result( $this->dbh );
}
// Return null if there is no result.
if ( empty( $this->last_result ) ) {
return null;
}
// Return the result.
return $this->last_result;
}
好家伙,代码有点长,咱们一点一点分析:
-
参数处理:
$query
:要执行的 SQL 查询语句。如果没有传入,就使用上次执行的查询语句。$output
:指定返回结果的类型。它可以是OBJECT
(对象)、ARRAY_A
(关联数组)或ARRAY_N
(数字索引数组)。 重点是,query_as_array()
调用get_results()
的时候,把这个参数设置成了ARRAY_A
。$y
:结果集的偏移量,表示从哪一行开始获取数据。
-
执行查询:
$result = $this->query( $query );
:这行代码调用wpdb
类的query()
方法来执行 SQL 查询。query()
方法负责连接数据库,发送 SQL 语句,并返回执行结果。- 如果查询失败,
get_results()
会直接返回null
。
-
处理查询结果:
$num_rows = $this->num_rows;
:获取查询结果的行数。- 如果查询结果有数据,
get_results()
会进入一个while
循环,逐行处理结果集。 - 关键就在这里:
mysqli_fetch_assoc( $this->dbh );
。这行代码使用 PHP 的mysqli_fetch_assoc()
函数从结果集中获取一行数据,并将其转换成一个关联数组。$this->dbh
是数据库连接句柄。
参数 说明 $this->dbh
数据库连接句柄,指向当前连接的 MySQLi 资源。 mysqli_fetch_assoc()
从结果集中获取下一行数据,并将其作为关联数组返回。数组的键是列名,值是对应列的值。 如果结果集中没有更多行,则返回 null
。$this->last_result[ $i ] = mysqli_fetch_assoc( $this->dbh );
:将获取到的关联数组存储到$this->last_result
数组中。- 如果
$output
参数是OBJECT
,则使用mysqli_fetch_object()
函数获取对象;如果$output
参数是ARRAY_N
,则使用mysqli_fetch_row()
函数获取数字索引数组。 - 循环结束后,
$this->last_result
数组就包含了所有查询结果,每个元素都是一个关联数组。
-
返回结果:
get_results()
方法最终会返回$this->last_result
数组。
四、mysqli_fetch_assoc()
:幕后英雄
现在,咱们来重点分析一下 mysqli_fetch_assoc()
函数。这个函数是 PHP 内置的,用于从 MySQLi 结果集中获取一行数据,并将其转换为关联数组。
它的工作原理很简单:
- 接收一个 MySQLi 结果集资源作为参数。
- 从结果集中读取下一行数据。
- 将每一列的数据以键值对的形式存储到一个数组中,其中键是列名,值是对应列的值。
- 返回这个数组。
- 如果结果集中没有更多行,则返回
null
。
举个例子,假设你执行了以下 SQL 查询:
SELECT id, name, email FROM users WHERE id = 1;
查询结果如下:
id | name | |
---|---|---|
1 | John Doe | [email protected] |
那么,mysqli_fetch_assoc()
函数会将这行数据转换成以下关联数组:
array(
'id' => '1',
'name' => 'John Doe',
'email' => '[email protected]'
)
五、总结:query_as_array()
的工作流程
现在,咱们可以总结一下 query_as_array()
方法的工作流程了:
query_as_array()
接收一个 SQL 查询语句作为参数。query_as_array()
将output
参数设置为ARRAY_A
,并调用get_results()
方法。get_results()
方法执行 SQL 查询,并获取查询结果。get_results()
方法使用mysqli_fetch_assoc()
函数逐行处理查询结果,将每一行数据转换成一个关联数组。get_results()
方法将所有关联数组存储到一个数组中,并返回该数组。query_as_array()
方法将get_results()
方法返回的数组作为自己的返回值。
简单来说,query_as_array()
就是 get_results()
方法的一个“快捷方式”,它帮你省去了设置 output
参数的麻烦。
六、注意事项:一些坑需要避开
- 性能问题: 如果查询结果集非常大,
query_as_array()
可能会占用大量的内存。在这种情况下,可以考虑使用迭代器或者分页查询来减少内存消耗。 - 安全性问题: 在使用
query_as_array()
方法时,一定要注意 SQL 注入攻击。不要直接将用户输入的数据拼接到 SQL 语句中,而是应该使用wpdb
类的prepare()
方法来对 SQL 语句进行转义。 - 错误处理: 在使用
query_as_array()
方法时,一定要进行错误处理。如果查询失败,query_as_array()
会返回null
,你需要检查返回值是否为null
,并根据情况进行处理。
七、高级用法:更上一层楼
除了基本用法之外,query_as_array()
还有一些高级用法,可以让你更灵活地处理查询结果:
- 指定偏移量: 你可以使用
$y
参数来指定结果集的偏移量,从而只获取部分数据。 - 自定义处理: 你可以自定义一个函数来处理每一行数据,并将处理后的结果存储到数组中。
八、实例演示:代码才是王道
为了更好地理解 query_as_array()
方法,咱们来看几个实例:
实例 1:获取指定 ID 的文章标题
global $wpdb;
$post_id = 123;
$query = $wpdb->prepare("SELECT post_title FROM wp_posts WHERE ID = %d", $post_id);
$results = $wpdb->query_as_array($query);
if ($results) {
echo "Post Title: " . $results[0]['post_title'] . "<br>";
} else {
echo "Post not found.";
}
实例 2:获取所有文章的 ID 和标题,并存储到数组中
global $wpdb;
$query = "SELECT ID, post_title FROM wp_posts";
$results = $wpdb->query_as_array($query);
$posts = array();
if ($results) {
foreach ($results as $row) {
$posts[$row['ID']] = $row['post_title'];
}
}
print_r($posts);
实例 3:使用偏移量获取部分文章
global $wpdb;
$offset = 10;
$limit = 5;
$query = "SELECT ID, post_title FROM wp_posts LIMIT $offset, $limit";
$results = $wpdb->query_as_array($query);
if ($results) {
foreach ($results as $row) {
echo "Post ID: " . $row['ID'] . ", Post Title: " . $row['post_title'] . "<br>";
}
} else {
echo "No posts found.";
}
九、总结:掌握 query_as_array()
,走遍天下都不怕
好了,今天的讲座就到这里。希望通过今天的讲解,你已经对 wpdb
类的 query_as_array()
方法有了更深入的了解。掌握了这个方法,你就可以更轻松地从 WordPress 数据库中获取数据,并将其转换成你需要的格式。
记住,代码才是王道!多写代码,多实践,你才能真正掌握这些知识。
下次有机会,咱们再聊聊 wpdb
类的其他方法。再见!