分析 WordPress `WP_Network` 类的源码:它如何封装网络信息,如域名和路径。

各位代码界的探险家们,晚上好!今天咱们来聊聊 WordPress 多站点网络背后的那位默默耕耘的英雄——WP_Network 类。它就像一个精密的地图,指引着我们在 WordPress 多站点这片浩瀚的海洋中航行。

一、初识 WP_Network:网络的身份证

在 WordPress 多站点环境中,每个站点都属于一个网络。WP_Network 类就是用来封装这些网络信息的。你可以把它想象成网络的身份证,上面记录着网络的各种关键信息,例如域名、路径等等。

我们先来看看 WP_Network 类的基本结构:

/**
 * Core class used to implement the WP_Network object.
 *
 * @since 4.5.0
 *
 * @property string $domain
 * @property string $path
 */
class WP_Network {

    /**
     * Network ID.
     *
     * @since 4.5.0
     * @var int
     */
    public $id = 0;

    /**
     * Network domain.
     *
     * @since 4.5.0
     * @var string
     */
    public $domain = '';

    /**
     * Network path.
     *
     * @since 4.5.0
     * @var string
     */
    public $path = '';

    /**
     * Site ID of the main site in this network.
     *
     * @since 4.5.0
     * @var int
     */
    public $site_id = 0;

    /**
     * Network name.
     *
     * @since 4.5.0
     * @var string
     */
    public $name = '';

    /**
     * Whether or not the network is archived.
     *
     * @since 4.5.0
     * @var string
     */
    public $archived = '';

    /**
     * Whether or not the network is spam.
     *
     * @since 4.5.0
     * @var string
     */
    public $spam = '';

    /**
     * Whether or not the network is deleted.
     *
     * @since 4.5.0
     * @var string
     */
    public $deleted = '';

    /**
     * Network status.
     *
     * @since 5.1.0
     * @var int
     */
    public $status = 1;

    // ... (省略部分代码)
}

可以看到,WP_Network 类主要包含以下属性:

属性 类型 描述
$id int 网络 ID,唯一标识一个网络。
$domain string 网络域名,例如 example.com
$path string 网络路径,例如 //site1/
$site_id int 网络中主站点的 ID。
$name string 网络名称,用于后台管理。
$archived string 是否已存档,取值为 '1'''
$spam string 是否为垃圾网络,取值为 '1'''
$deleted string 是否已删除,取值为 '1'''
$status int 网络状态,例如 1 表示启用。

这些属性就像网络的名片,记录着网络的各种信息。 其中,$domain$path 是核心属性,决定了网络的访问地址。

二、WP_Network 的构造函数:创建网络的基石

WP_Network 类的构造函数负责初始化对象。 让我们深入了解它的工作原理:

    /**
     * Constructor.
     *
     * Will populate member properties from the database when called with
     * a network ID.
     *
     * @since 4.5.0
     *
     * @param int|object|array $network Optional. Network ID, network object, or network array. Default null.
     */
    public function __construct( $network = null ) {
        if ( is_object( $network ) ) {
            $network = (array) $network;
        } elseif ( is_numeric( $network ) ) {
            $network = (array) get_network( (int) $network );
        }

        if ( is_array( $network ) && ! empty( $network ) ) {
            foreach ( $network as $key => $value ) {
                $this->$key = $value;
            }
        }
    }

构造函数接收一个可选参数 $network,它可以是:

  1. null:创建一个空的 WP_Network 对象。
  2. int:网络 ID,构造函数会根据 ID 从数据库中获取网络信息并填充对象属性。
  3. object:包含网络信息的对象,会被转换为数组并填充对象属性。
  4. array:包含网络信息的数组,直接填充对象属性。

构造函数首先检查 $network 的类型,然后根据类型进行相应的处理。如果是数字,则调用 get_network() 函数从数据库中获取网络信息。最后,遍历 $network 数组,将数组中的键值对赋值给对象的属性。

举个例子,假设我们有一个网络 ID 为 2,我们可以这样创建一个 WP_Network 对象:

$network_id = 2;
$network = new WP_Network( $network_id );

echo "Network Domain: " . $network->domain . "n";
echo "Network Path: " . $network->path . "n";

这段代码会创建一个 WP_Network 对象,并从数据库中获取 ID 为 2 的网络信息,然后输出网络的域名和路径。

三、WP_Network 如何封装域名和路径

WP_Network 类通过 $domain$path 属性来封装网络的域名和路径。这两个属性决定了网络的访问地址。

  • $domain:网络域名

    $domain 属性存储网络的域名,例如 example.com。它是网络地址的基础,所有站点都基于这个域名。

  • $path:网络路径

    $path 属性存储网络的路径,例如 //site1/。它决定了网络在域名下的位置。如果 $path/,则网络位于域名的根目录。如果 $path/site1/,则网络位于域名的 /site1/ 目录下。

域名和路径的组合就构成了网络的根 URL。例如,如果 $domainexample.com$path/site1/,则网络的根 URL 为 http://example.com/site1/

在多站点环境中,每个站点都属于一个网络。站点 URL 是基于网络 URL 构建的。例如,如果一个站点在网络 example.com/site1/ 下,其路径为 /blog/,则站点的 URL 为 http://example.com/site1/blog/

四、WP_Network 的方法:操作网络的工具箱

WP_Network 类还提供了一些方法,用于操作网络信息。虽然不像属性那样直接存储数据,但这些方法就像工具箱,帮助我们更方便地管理网络。

  • get_site_ids(): 获取网络下的所有站点ID.
  • delete(): 删除网络。
  • update(): 更新网络信息。

我们重点看下 update() 方法:

    /**
     * Updates a network.
     *
     * @since 4.5.0
     *
     * @return bool True on success, false on failure.
     */
    public function update() {
        /**
         * Fires immediately before a network is updated.
         *
         * @since 4.5.0
         *
         * @param WP_Network $this WP_Network object.
         */
        do_action( 'pre_network_update', $this );

        $data = wp_unslash( get_object_vars( $this ) );
        $data = sanitize_network( $data, 'db' );

        $result = wp_update_network( $data );

        if ( ! $result ) {
            return false;
        }

        $this->id = $result;

        clean_network_cache( $this );

        /**
         * Fires immediately after a network is updated.
         *
         * @since 4.5.0
         *
         * @param WP_Network $this WP_Network object.
         */
        do_action( 'network_update', $this );

        return true;
    }

update() 方法用于更新网络信息。它首先触发 pre_network_update action,允许我们在更新之前执行一些操作。然后,它获取对象的所有属性,对数据进行清理和转义,并调用 wp_update_network() 函数将数据更新到数据库中。如果更新成功,则清理网络缓存,并触发 network_update action。

使用示例:

$network_id = 2;
$network = new WP_Network( $network_id );

$network->name = 'My Updated Network';
$network->domain = 'updated-example.com';

$network->update();

echo "Updated Network Name: " . $network->name . "n";
echo "Updated Network Domain: " . $network->domain . "n";

这段代码会更新 ID 为 2 的网络的名称和域名。

五、get_network() 函数:获取网络信息的入口

get_network() 函数是获取网络信息的主要入口点。它接收一个网络 ID,并返回一个 WP_Network 对象。

/**
 * Retrieve network object.
 *
 * @since 4.5.0
 *
 * @param int|WP_Network $network Network ID or WP_Network object.
 * @param string         $output  Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which correspond to
 *                                a WP_Network object, an associative array, or a numeric array, respectively. Default OBJECT.
 *
 * @return WP_Network|object|array|null WP_Network object, array, or null. Null if network is not found.
 */
function get_network( $network, $output = OBJECT ) {
    global $wpdb, $_wp_networks;

    if ( empty( $network ) ) {
        return null;
    }

    if ( $network instanceof WP_Network ) {
        return $network;
    }

    $id = (int) $network;

    if ( isset( $_wp_networks[ $id ] ) ) {
        return $_wp_networks[ $id ];
    }

    $network = wp_cache_get( $id, 'networks' );

    if ( false === $network ) {
        $network = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->networks} WHERE id = %d", $id ) );

        if ( empty( $network ) ) {
            return null;
        }

        wp_cache_add( $id, $network, 'networks' );
    }

    $_wp_networks[ $id ] = $network;

    if ( OBJECT == $output ) {
        return new WP_Network( $network );
    } elseif ( ARRAY_A == $output ) {
        return (array) $network;
    } elseif ( ARRAY_N == $output ) {
        return array_values( (array) $network );
    } else {
        return $network;
    }
}

get_network() 函数首先检查 $network 是否为空,或者是否已经是一个 WP_Network 对象。如果是,则直接返回。然后,它尝试从缓存中获取网络信息。如果缓存中没有,则从数据库中查询,并将结果添加到缓存中。最后,根据 $output 参数返回 WP_Network 对象、关联数组或数字数组。

六、wp_get_network() 函数:兼容性wrapper

wp_get_network() 是一个简单的 wrapper 函数,用于向前兼容。它调用 get_network() 函数并返回 WP_Network 对象。

/**
 * Retrieve a network object.
 *
 * @since 4.6.0
 *
 * @param int|WP_Network $network Network ID or network object.
 * @return WP_Network|null WP_Network object, or null if not found.
 */
function wp_get_network( $network ) {
    return get_network( $network );
}

七、总结:WP_Network 的重要性

WP_Network 类是 WordPress 多站点网络的核心组件。它封装了网络信息,提供了操作网络信息的工具,并为多站点环境的站点管理提供了基础。

功能 说明
信息封装 将网络的 ID、域名、路径、名称等信息封装在一个对象中,方便管理和访问。
数据访问 提供了访问网络信息的接口,例如 get_network() 函数。
数据操作 提供了更新网络信息的接口,例如 update() 方法。
多站点基础 是多站点环境的基础,站点 URL 的构建依赖于网络 URL。

理解 WP_Network 类的工作原理,可以帮助我们更好地理解 WordPress 多站点的架构,并能更有效地管理多站点环境。

好了,今天的讲座就到这里。希望大家对 WP_Network 类有了更深入的了解。下次再见!

发表回复

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