01 – 最核心的开发基础

重点提醒:本文的配套视频可在这里观看。而本文的内容会比较精炼,其作用是为了观看视频后的观众复盘整理而用。如果直接阅读,可能会有不明白之处。

希望大家以观看视频为主、文章为辅。如果有帮助,请在视频处点点关注、一键三连!

本文将系统性介绍 WordPress 开发中最重要的底层机制。
理解这些内容,并不意味着你要“背源码”,而是帮助你建立正确的心智模型,从而在后续开发中——尤其是与 AI 协同开发时——知道代码该写在哪里、什么时候执行、为什么这样写

本文重点包括:

  1. WordPress 的启动与执行流程
  2. WordPress 的钩子(Hooks)机制
  3. WP_Query 的作用
  4. 条件标签在程序执行流程中的意义

一、WordPress 的启动流程(Load Sequence)

1. 所有前端请求的统一入口

无论用户访问的是:

  • 首页
  • 分类页
  • 单篇文章
  • 普通页面
  • 404 页面

所有前端请求,最终都会通过同一个入口文件:

index.phpCode language: Bash (bash)

这是 WordPress 的核心设计之一:统一入口,后续再行判断具体请求页面


2. 启动流程核心文件链路

前端请求的核心执行路径如下:

index.php 
└─ wp-blog-header.php 
   ├─ wp-load.php
   │  └─ wp-config.php 
   │     └─ wp-settings.php 
   ├─ wp() // 构建查询对象 
   └─ template-loader.php Code language: JavaScript (javascript)

其中:

  • wp-settings.php 是整个系统最关键的文件
  • 插件、主题函数、核心类、全局变量,几乎都在这里被加载

3. wp-config.php 的角色

wp-config.php 是 WordPress 的配置中心

  • 数据库连接信息
  • 调试配置
  • 自定义全局常量

重要特性:

WordPress 升级时,不会覆盖 wp-config.php

因此,任何需要长期存在、且与环境相关的配置,都应该写在这里。


4. wp-settings.php 做了什么?

wp-settings.php 中发生的关键事情包括:

(1)加载大量核心文件

这意味着:每一次页面访问都会执行大量 PHP 文件。这也是 WordPress 常被认为“臃肿”的原因之一。

实际优化手段包括:

  • 开启 PHP Opcache
  • 使用页面静态缓存

(2)加载所有已启用的插件

wp-settings.php 中,WordPress 会:

  • 获取所有已启用插件
  • 依次 require 插件主文件

值得注意的是,仅仅只有插件的主文件被包含进了执行流程当中。如果你的插件是由多个文件组成的,那么其他文件只有在被插件主文件包含时,才会加入到执行流程当中。


(3)加载主题的 functions.php 文件

主题中的 functions.php 的大概执行位置是:

  • 插件之后
  • initwp_loaded模板文件之前

它是被 wp-settings.php 主动加载的,其作用是:

让主题作者在模板渲染前,向 WordPress 注入功能逻辑

这也是为什么很多教程会说:

“把代码放进 functions.php”


(4)创建大量全局变量

例如:

$wp_query
$wp_the_query
$wp_rewrite
$wp_roles
... Code language: PHP (php)

这些变量都是在 wp-settings.php 中创建的。

这也是为什么在 WordPress 开发中,经常需要使用:

global $wp_query;Code language: PHP (php)

5. wp() 与 Template Loader

wp-settings.php 执行完毕后:

  1. 调用 wp()
    • 构建 WP_Query
    • 确定当前请求的类型(首页 / 分类 / 单页等)
  2. 加载 template-loader.php
    • 根据条件标签,决定使用哪个主题模板文件

最终,WordPress 输出 HTML / CSS / JS 给浏览器。


二、WordPress 的钩子机制(Hooks)

1. 为什么需要钩子?

插件加载时:

  • 很多 WordPress 函数 尚未定义
  • 直接调用会导致致命错误

例如:

is_user_logged_in();
wp_get_current_user();Code language: PHP (php)

这些函数定义在 更靠后 的阶段。另外,使用钩子可以让我们把自定义代码插入到各个预留的插槽位置(见后文)。


2. 钩子的本质

钩子 = 系统预留的执行插槽

WordPress 在运行过程中,会在关键节点执行:

do_action('hook_name');Code language: JavaScript (javascript)

第三方开发者可以通过:

add_action('hook_name', 'your_function');Code language: JavaScript (javascript)

把自己的代码“挂”上去。


3. 插件示例:延迟执行任务

错误示例(直接执行):

if ( is_user_logged_in() ) { 
    $user = wp_get_current_user(); 
    error_log( $user->display_name . ' 访问' );
} else { 
    error_log('访客访问'); 
} Code language: PHP (php)

正确方式(使用钩子):

function log_user_task() { 
    if ( is_user_logged_in() ) { 
        $user = wp_get_current_user(); 
        error_log( $user->display_name . ' 访问' ); 
    } else { 
        error_log('访客访问'); 
    } 
}
add_action( 'wp_loaded', 'log_user_task' ); Code language: PHP (php)

4. 常见钩子执行顺序概念

  • init
  • wp_loaded
  • template_redirect
  • wp_head 等模板文件内部的钩子

经验建议:

  • 优先使用 wp_loaded
  • init 更偏向 WordPress 内核使用
  • 只有在需要“极早介入”时才使用 init

5. 为什么推荐“所有功能都挂钩子”?

即便是可以直接调用的函数(如短码):add_shortcode('bobs_plugin', 'shortcode_func');

依然推荐改成:

function add_shortcode_task() { 
    add_shortcode('bobs_plugin', 'shortcode_func'); 
}
add_action('wp_loaded', 'add_shortcode_task');Code language: JavaScript (javascript)

原因是:

  • 钩子里的任务 可被 remove
  • 可被其他插件控制,更灵活

三、WP_Query 的角色(核心但不展开)

需要记住的是:

  • WP_Query 对象是用来向数据库请求数据的
  • 在 WordPress 中,区分 主查询辅助查询 。主查询由当前请求的 URL 决定、辅助查询由第三方开发者自行创建(或由普通用户通过相关模块创建)。

我们可以通过使用 pre_get_posts 钩子在 WP_Query 对象正式执行数据库查询之前调整它,但一般情况下,都要配合条件标签使用。


四、条件标签(Conditional Tags)

由于 WordPress 插件的机制,在没有使用条件标签的情况下,你的自定义代码会在处理任意页面请求时均被执行。这显然不是我们想要的。因此,我们需要通过条件标签来确保我们的代码只有在我们希望它执行的时候执行。条件标签有:

is_home() 
is_front_page() 
is_single() 
is_page() 
is_category() 
is_404()
等等……

条件标签的本质是基于 WP_Query 的状态判断。


五、本课小结

通过本课,你应该已经建立起以下认知:

  • WordPress 是 流程驱动 的系统
  • 插件 ≠ 立即执行代码
  • 开发本质是:定义任务 → 挂载到合适的钩子
  • 理解启动流程,是理解 Hooks、Query、模板系统的前提
  • 使用条件标签,可帮助我们确保在合适的位置、执行对应的代码