从零开始搭插件骨架:我把目录结构、入口文件和本地环境揉进了一份「最小可运行模板」

小助手
小助手 版主圣羽星庭 勋望元宿志愿先锋
社区管理
插件开发 90 浏览 0 回复

刚开始写插件那会儿,我的目录是乱的——index.phpmain.phpplugin.php 全塞根目录,WordPress 后台能认出来,但自动加载一塌糊涂,调试时找文件像翻垃圾堆。后来逼自己定了一套规矩,现在新项目都是复制粘贴改个名字就能跑。

我的目录长这样,不多不少:

my-plugin/
├── my-plugin.php          ← 唯一入口,只做一件事:启动
├── composer.json          ← 自动加载 + 依赖管理
├── src/
│   ├── Plugin.php         ← 核心类,单例,管生命周期
│   ├── Admin/             ← 后台相关:菜单、设置页、AJAX
│   ├── Frontend/          ← 前台:短代码、脚本注入、模板覆盖
│   ├── Core/              ← 跨层工具:数据库抽象、通用钩子、常量
│   └── Integrations/      ← 第三方对接:WooCommerce、REST、块编辑器
├── assets/
│   ├── css/
│   ├── js/
│   └── images/
├── languages/
├── tests/                 ← PHPUnit + Brain\Monkey
└── .vscode/               ← launch.json 预配置,新人clone即用

关键认知转变:入口文件不是"主程序",是"施工指示牌"。以前我把业务逻辑全堆 my-plugin.php,现在它只干四件事——

<?php
/**
 * Plugin Name: My Plugin
 * ...
 */

// 1. 防直接访问
if (!defined('ABSPATH')) exit;

// 2. 定义常量(路径、版本,不用硬编码)
define('MY_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('MY_PLUGIN_URL', plugin_dir_url(__FILE__));
define('MY_PLUGIN_VERSION', '1.0.0');

// 3. Composer 自动加载(没有 Composer 就用 spl_autoload_register 手写)
require_once MY_PLUGIN_DIR . 'vendor/autoload.php';

// 4. 启动,且只启动一次
add_action('plugins_loaded', function () {
    \MyPlugin\Plugin::instance()->boot();
});

Plugin::boot() 里面才做具体的事:注册服务容器、加载文本域、判断前台/后台分别初始化哪个模块。这样 plugins_loaded 之前,我的代码完全"静音",不会跟别的插件抢钩子。

本地环境我用的是"轻量三件套",不是全套 Docker:

1. wp-env(@wordpress/env)—— 项目里丢个 .wp-env.json

{
  "core": "WordPress/WordPress#6.5",
  "plugins": [ "." ],
  "port": 2000,
  "testsPort": 2001,
  "config": {
    "WP_DEBUG": true,
    "WP_DEBUG_LOG": true,
    "SCRIPT_DEBUG": true
  }
}

npx wp-env start,当前插件自动挂载进容器,改代码宿主机实时同步。调试日志直接落 wp-content/debug.logtail -f 盯着看。

2. Xdebug 走 VS Code 的 launch.json,但端口改成 9003,pathMappings 配到容器里的 /var/www/html/wp-content/plugins/my-plugin。断点打在 src/Admin/Settings.php 里,保存设置页表单时直接停住,比 var_dump 后刷新页面快十倍。

3. 一个偷懒的调试入口:我在 tests/ 旁边放了 _playground.php,不在版本控制里,纯本地用——

<?php
// 直接 php _playground.php 跑,绕过 WordPress 全局依赖
require __DIR__ . '/../vendor/autoload.php';

$service = new \MyPlugin\Core\SomeService();
$result = $service->calculate(['foo' => 'bar']);

var_dump($result);

想快速验证一个类的逻辑,不用开浏览器、不用等 WordPress 加载,CLI 里秒出结果。写顺手了,有些单元测试都是先在 _playground.php 里跑通再搬过去。

踩过的一个坑:wp-env 时,插件在宿主机改完代码,容器里偶尔不生效。不是缓存,是文件挂载的 inode 问题。解决方式是改完 touch 一下入口文件,或者给 wp-env start--update 强制刷新挂载点。这毛病耗了我半小时,后来写进项目 README 的"本地开发注意事项"里。

你们本地调插件是全套 Docker 还是也走这种轻量路线?有没有更顺手的"单文件快速验证"技巧?

评论0
回复 · 0
还没有回复
微信客服 微信客服