剖析 WordPress `wpdb` 类的 `get_results()` 方法源码:如何将查询结果转换为对象数组,并解释 `ARRAY_A` 参数的作用。

各位观众,晚上好!今晚咱们来聊聊 WordPress wpdb 类的 get_results() 方法!

嘿嘿,别被这名字吓到,其实它就是个超级给力的“数据库结果搬运工”。它负责把数据库里辛辛苦苦查出来的数据,按照你想要的格式,给你装到数组里。今天我们就来扒一扒它的皮,看看它是怎么把结果变成对象数组的,特别是那个神秘兮兮的 ARRAY_A 参数,到底在搞什么鬼。

咱们先来热个身,简单了解一下 wpdb 类。

wpdb 类:WordPress 的数据库“管家”

wpdb 类是 WordPress 核心里负责和数据库打交道的“大管家”。它封装了各种数据库操作,比如连接数据库、执行查询、获取结果等等。你不用直接写那些复杂的 SQL 语句,直接调用 wpdb 类的函数就行,方便又快捷。

get_results() 方法就是 wpdb 类里一个非常常用的方法,用来执行 SQL 查询并获取结果。它的基本用法如下:

global $wpdb;

$query = "SELECT * FROM {$wpdb->prefix}posts WHERE post_status = 'publish' LIMIT 10";
$results = $wpdb->get_results( $query );

// $results 里面就装满了查询结果

这段代码的意思是:从 wp_posts 表($wpdb->prefix 会自动替换成你的数据库表前缀,比如 wp_)里,选取 post_statuspublish 的前 10 篇文章,然后把结果放到 $results 变量里。

那么,问题来了,$results 里面到底装的是什么东西?这就涉及到 get_results() 方法的返回值类型了。

get_results() 的返回值类型:三种可能性

get_results() 方法可以返回三种不同类型的数组:

  • 对象数组 (OBJECT):默认类型,数组里的每个元素都是一个 PHP 对象。
  • 关联数组数组 (ARRAY_A):数组里的每个元素都是一个关联数组,键值对形式。
  • 数字索引数组数组 (ARRAY_N):数组里的每个元素都是一个数字索引数组,只有值,没有键。

这三种类型的区别,咱们用一个表格来总结一下:

返回值类型 描述 访问方式
OBJECT 数组里的每个元素都是一个 PHP 对象。 $result->column_name
ARRAY_A 数组里的每个元素都是一个关联数组,使用列名作为键。 $result['column_name']
ARRAY_N 数组里的每个元素都是一个数字索引数组,只能通过数字索引访问,不建议使用,可读性差。 $result[0], $result[1] (对应查询结果的第一列,第二列,以此类推)

默认情况下,get_results() 返回的是对象数组。也就是说,上面的 $results 变量里的每个元素都是一个 PHP 对象,你可以通过 -> 符号来访问对象的属性,比如:

global $wpdb;

$query = "SELECT ID, post_title FROM {$wpdb->prefix}posts WHERE post_status = 'publish' LIMIT 1";
$results = $wpdb->get_results( $query );

if ( $results ) {
    $first_post = $results[0];
    echo "文章 ID: " . $first_post->ID . "<br>";
    echo "文章标题: " . $first_post->post_title . "<br>";
}

这段代码会输出第一篇文章的 ID 和标题。

但是,如果你想用关联数组的方式来访问结果,就可以使用 ARRAY_A 参数。

ARRAY_A 参数:把对象变成关联数组

ARRAY_A 参数告诉 get_results() 方法,把查询结果转换成关联数组数组。使用方法很简单,只需要把 ARRAY_A 作为第二个参数传递给 get_results() 方法即可:

global $wpdb;

$query = "SELECT ID, post_title FROM {$wpdb->prefix}posts WHERE post_status = 'publish' LIMIT 1";
$results = $wpdb->get_results( $query, ARRAY_A );

if ( $results ) {
    $first_post = $results[0];
    echo "文章 ID: " . $first_post['ID'] . "<br>";
    echo "文章标题: " . $first_post['post_title'] . "<br>";
}

注意,这里的访问方式变成了 $first_post['ID']$first_post['post_title'],而不是 $first_post->ID$first_post->post_title

那么,为什么要有 ARRAY_A 这个参数呢?它有什么好处?

ARRAY_A 参数的好处:更灵活的数据处理

使用 ARRAY_A 参数,可以让你更灵活地处理查询结果。

  • 方便循环处理: 关联数组更容易用 foreach 循环来处理,因为你可以直接访问键名。

    global $wpdb;
    
    $query = "SELECT ID, post_title FROM {$wpdb->prefix}posts WHERE post_status = 'publish' LIMIT 5";
    $results = $wpdb->get_results( $query, ARRAY_A );
    
    if ( $results ) {
        foreach ( $results as $post ) {
            echo "文章 ID: " . $post['ID'] . "<br>";
            echo "文章标题: " . $post['post_title'] . "<br>";
            echo "<hr>";
        }
    }
  • 方便数组操作: 关联数组可以更容易地使用 PHP 的各种数组函数,比如 array_key_exists()array_values() 等。

  • 更容易与其他数组合并: 如果你需要把查询结果和其他数组合并,关联数组会更方便。

总而言之,ARRAY_A 参数提供了一种更灵活、更易于操作的查询结果格式。

深入 get_results() 源码:ARRAY_A 参数背后的秘密

现在,让我们深入 get_results() 方法的源码,看看它是如何处理 ARRAY_A 参数的。

(友情提示:以下代码是简化版的,只保留了关键部分,并且为了方便理解,加了一些注释。)

public function get_results( $query = null, $output = OBJECT ) {
    // ...省略一些代码...

    $return_val = null;

    if ( $query ) {
        $this->query( $query ); // 执行查询
    } else {
        return null;
    }

    // 处理查询结果
    if ( $this->num_rows ) {
        $i = 0;

        while ( $row = $this->fetch_array( $this->result ) ) {
            if ( OBJECT == $output ) {
                $return_val[$i] = (object) $row; // 转换为对象
            } elseif ( ARRAY_A == $output ) {
                $return_val[$i] = $row; // 直接使用关联数组
            } elseif ( ARRAY_N == $output ) {
                $return_val[$i] = array_values( $row ); // 转换为数字索引数组
            } else {
                $return_val[$i] = $row; // 默认使用关联数组,兼容旧版本
            }
            $i++;
        }
    }

    return $return_val;
}

public function fetch_array( $result = false ) {
    if ( ! $result ) {
        return false;
    }

    return @mysqli_fetch_assoc( $result ); // 从数据库结果集中获取一行作为关联数组
}

这段代码的关键在于 while 循环里的判断:

  • 如果 $output 等于 OBJECT,就把 $row 强制转换为对象 (object) $row
  • 如果 $output 等于 ARRAY_A,就直接把 $row 赋值给 $return_val[$i]
  • 如果 $output 等于 ARRAY_N,就把 $row 的值提取出来,放到一个数字索引数组里。

fetch_array() 方法实际上调用的是 mysqli_fetch_assoc() 函数,这个函数会从数据库结果集中获取一行数据,并返回一个关联数组。

所以,ARRAY_A 参数的作用就是告诉 get_results() 方法,不要把关联数组转换成对象,直接使用关联数组作为结果。

案例分析:选择合适的返回值类型

在实际开发中,应该根据具体的需求来选择合适的返回值类型。

  • 如果只需要访问几个特定的列,并且对性能要求比较高,可以选择对象数组。 因为对象属性的访问速度比关联数组的键名访问速度稍微快一些。

  • 如果需要循环处理结果,或者需要使用 PHP 的数组函数,可以选择关联数组。 关联数组更灵活,更易于操作。

  • 如果只是需要快速地获取数据,并且不关心数据的结构,可以选择数字索引数组。 但不建议使用,可读性太差。

举个例子,假设你需要获取所有文章的 ID 和标题,并把它们放到一个数组里,键是文章 ID,值是文章标题。使用关联数组会更方便:

global $wpdb;

$query = "SELECT ID, post_title FROM {$wpdb->prefix}posts WHERE post_status = 'publish'";
$results = $wpdb->get_results( $query, ARRAY_A );

$posts = array();
if ( $results ) {
    foreach ( $results as $post ) {
        $posts[$post['ID']] = $post['post_title'];
    }
}

// $posts 里面就装满了文章 ID 和标题

这段代码可以很方便地把查询结果转换成你想要的格式。

总结:ARRAY_A 参数,让 get_results() 更上一层楼

wpdb 类的 get_results() 方法是一个非常强大的工具,它可以让你轻松地从数据库里获取数据。而 ARRAY_A 参数则让这个工具变得更加灵活、更加易于使用。

掌握了 ARRAY_A 参数的用法,你就可以根据自己的需求,选择合适的返回值类型,更高效地处理数据库查询结果。

希望今天的讲座能帮助你更好地理解 wpdb 类的 get_results() 方法,以及 ARRAY_A 参数的作用。记住,编程就像做菜,掌握了各种调料的用法,才能做出美味佳肴!

谢谢大家!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注