在本文中,我将指出,在我们的WordPress插件中使用名称空间的原因是什么?我们将了解到,名称空间对于本系列的即将到来的主题很重要。
WordPress插件中命名常数,功能和类的问题
Avoiding name collisions在插件开发中至关重要。如果您直接在插件文件中使用常数,功能和类,则将在全局名称空间中注册。因此,您有可能从其他插件(或WordPress本身)覆盖常数,函数或类,反之亦然。结果,您的插件(或其他插件)可能无法正常运行,或者可能会丢弃PHP错误。
所以,让我们假设我们的系统上安装了两个插件,每个插件都声明一个称为plugin_init()
的函数:
插件文件 plugin-01/plugin-01.php :
<?php
/*
* Plugin Name: Plugin #1
*/
function plugin_init() {
// some code
}
插件文件 plugin-02/plugin-02.php :
<?php
/*
* Plugin Name: Plugin #2
*/
function plugin_init() {
// some code
}
这将导致以下错误:PHP Fatal error: Cannot redeclare plugin_init() (previously declared in /../plugin-01/plugin-01.php)
。其背后的原因是,PHP不允许声明具有相同名称的两个函数。
使用前缀解决此问题
现在,我们可以为插件提供一个前缀,然后我们将在整个插件中始终使用。前缀只是我们在功能和班级名称前放置的字符串,通常是下划线。
请记住,前缀必须尽可能独特。如果我们仅使用插件名称,则可能还有另一个插件具有该名称,然后再次导致命名冲突。您的名字的简短组合和插件的名称通常应该是安全的。
示例:
<?php
/*
* Plugin Name: Prefixed plugin
*/
function mk_pp_plugin_init() {
// some code
}
function mk_pp_get_data() {
// some code
}
// ...
在此示例中,我们选择了 mk_pp 作为前缀(Marcus Kober的短形式和插件的缩写),现在将其用于我们所有常数和功能。如您所见,这导致了长名,并且肯定不会促进清晰度和可读性。但是,这样的前缀相对安全。但是我们可以更优雅地做吗?
什么是名称空间?
Namespaces提供了封装代码元素的能力,以免引起名称碰撞。本质上,名称空间是组织功能,类和常数的机制。名称空间定义了一个唯一的区域,其中函数和类的名称被封装。这使得在不同名称空间中使用相同名称是可能的。
您还可以想象名称空间,例如文件夹系统。子文件夹与后斜切(/
)分开。
对于根名称空间,我建议使用您的姓名或公司的姓名或缩写。就我而言,那将是MK
。然后遵循插件的名称(或其缩写):MK\MyPlugin
。
我们使用名称空间
在插件中每个PHP文件的开头定义了名称空间。当然,您应该再次确保不使用太简单插件(例如插件),因为这也可能导致名称碰撞命名空间。
示例:
<?php
/*
* Plugin Name: Namespaced plugin
*/
namespace MK\NamespacePlugin;
function plugin_init() {
// some code
}
function get_data() {
// some code
}
// ...
函数plugin_init()
的fully qualified name现在:MK\NamespacePlugin\plugin_init()
。这可以解决潜在的名称冲突与另一个插件中可能存在的函数plugin_init()
的冲突。
WordPress插件中的名称空间
现在,让我们尝试在名称空间中注册一个函数作为挂钩的回调:
<?php
/*
* Plugin Name: Namespaced plugin
*/
namespace MK\NamespacePlugin;
function plugin_init() {
// some code
}
add_action('init', 'plugin_init');
这将导致致命错误:
Fatal error: Uncaught TypeError: call_user_func_array(): Argument #1 ($callback) must be a valid callback, function "plugin_init" not found or invalid function name
为什么出现此错误消息?毕竟,我们的插件确实存在函数plugin_init()
。要理解,让我们看看发生错误的文件。在PHP错误描述中,我们在下面看到:
thrown in /.../wp-includes/class-wp-hook.php on line 308
因此,该错误发生在WordPress Core File class-wp-hook.php 中,其中定义了core函数apply_filters()
,该函数称为我们在add_action()
中定义的回调。但是,文件 class-wp-hook.php 不在我们定义的命名空间MK\NamespacePlugin
之外,这就是为什么我们需要给函数add_action()
函数的完全合格的名称:
<?php
/*
* Plugin Name: Namespaced plugin
*/
namespace MK\NamespacePlugin;
function plugin_init() {
// some code
}
add_action('init', 'MK\NamespacePlugin\plugin_init');
,我们不必在任何地方手动输入全名,我们还可以使用magic constant __NAMESPACE__
提供呼叫,该呼叫包含当前名称空间的名称为字符串:
add_action('init', __NAMESPACE__ . 'plugin_init');
结论
使用名称空间是一种清洁有效的方法,可以从全局名称空间中封装我们的常数,功能和类,从而防止名称碰撞。
在本系列的下一篇文章中,我们还将看到我们需要自动加载的名称空间和插件的文件夹结构。