如何制作出色的 WP 插件二(架构篇)
PHP 程序从来不缺好的架构,WP 从来都没有好的架构,无论是从安全性上或效率上,WP 都称不上优秀。但这并不能成为制作出九流插件的理由,人不能自暴自弃。
在上篇文章《如何制作出色的 WP 插件一(注释篇)》已讲述了插件的注释格式,接下来继续讲述插件应有怎样的基础架构,才能成为一款优秀的插件。
读前须知
本章节涉及到 PHP7 相关知识,以及基本的面向对象概念,您可以在读前去了解一下这些知识,否则理解的难度可能有所提高。
文件命名
在编写之前,先将插件文件名命名为为:MyPlugin.php
,并放在 MyPlugin
的插件目录里面。如不知道如何命名,请查阅上一篇《如何制作出色的 WP 插件一(注释篇)》。
严格模式
从 PHP 7.1 开始,PHP 支持严格模式,意味一旦开启了这个模式,插件的所有变量、参数和返回值都需要符合预期的类型,例如 md5
函数,其参数必须为字符串,md5(123)
这种写法是错误的,因为 123
是数字而不是字符串。需改为 md5('123')
才是正确的。
至于为什么要启用严格模式,因为一是可以让编辑器更好无需推导就能提示类型,二是不容易发生类型转换的漏洞,三是可为未来的 PHP (PHP8 JIT)标准做好铺垫,减少维护成本。
所以,在写插件的时候,您应在上篇文章《注释篇》中的注释下面,加入如下代码:
declare(strict_types = 1);
命名空间
WP 的插件是原生 PHP 代码构成,故此里面的函数或变量都是全局注册的,如果有两个插件都有一样名称的函数名,这将会导致发生致命错误,PHP 无法继续工作。为了解决这个问题,一律应在插件里使用命名空间,例如紧接上述代码,在此加入下列命名空间代码:
namespace InnStudio\Plugin\MyPlugin;
禁止非法访问
因为 WP 插件是 PHP 文件,而且插件路径可以从 URL 直接访问,如没有做防御处理,将会导致一些异常错误发生,暴露服务器的信息。因此您应该增加这类的判断,防止非法访问,紧接上述代码,再次加入如下代码:
\defined('\\AUTH_KEY') || \http_response_code(500) && die;
上述代码意思为:检测 AUTH_KEY
这个全局 WP 常量,如果没有则输出 500 错误并终止脚本执行。AUTH_KEY
全局常量是在 wp-config.php
配置文件中定义的,因为直接访问插件文件,AUTH_KEY
全局常量是无效的,故能阻止非法访问。
类
一般情况下,如果插件复杂度不高,功能数量不超过 5 个,可以使用一个类来实现。例如我们要制作一款功能仅能在前台页面(WP 默认主题)弹出警告框的插件,类代码基本结构可为下(继续在上述代码添加):
// 定义插件执行类
final class MyPlugin
{
// 定义构造函数
public function __construct()
{
// 定义一个在 'wp_head' 钩子的匿名函数
\add_action('wp_head', function():void{
// 输出警告框
echo '<script>alert();</script>';
});
}
}
在上述代码中,我们构建了一个功能非常简单的类,仅能在前台页面中弹出一个空内容的警告框,其中 wp_head
即在前台页面的 <head>
区域输出 JS 警告框代码。但在这段代码中,只是定义了一个类,并没有对其实例化(调用)。
调用
定义了上述类后,我们需要对其进行实例化,可继续编写(在上述代码继续添加):
new MyPlugin();
在上述代码中,我们已经对类进行了实例化,当加载插件的时候,就会生效了。
完成
到目前位置,这个插件的所有代码应该类似如下:
<?php
// Plugin Name: 我的插件
// Plugin URI: https://inn-studio.com
// Description: 这是我的插件描述
// Author: 小明
// Author URI: https://inn-studio.com/how-to-code-good
// Version: 1.0.0
// PHP Required: 7.3
declare(strict_types = 1);
namespace InnStudio\Plugin\MyPlugin;
\defined('\\AUTH_KEY') || \http_response_code(500) && die;
// 定义插件执行类
final class MyPlugin
{
// 定义构造函数
public function __construct()
{
// 定义一个在 'wp_head' 钩子的匿名函数
\add_action('wp_head', function (): void {
// 输出警告框
echo '<script>alert();</script>';
});
}
}
new MyPlugin();
至此,本插件所在位置应该为 wp-content/plugins/MyPlugin/MyPlugin.php
,这时候我们可以在后台看见此插件存在于列表中。
点击启用,查看网站首页,即可看到弹出警告框。
进阶
在上述代码中,我们在函数前面用到了一个反斜杠\
,这是什么意思呢?这是因为我们用到 PHP 的命名空间,所有全局的用户(WP)函数,都需要加上全局符号\
来表示这个函数是全局的。
其中如果函数是 PHP 内置函数,也最好加上,因为这可以加快函数的解析,而不是先从本命名空间中查找,然后在查找 PHP 内存函数。
结语
在学习了本系列后,您应该可以能写出一个弹出警告框的插件了,虽然没什么作用,但任何事情都会有第一步的。
接下来,将会有更多的篇章等着我们,共同期待吧!