最近因为一个小项目需要扩展功能,实现了一个简单的插件扩展;
使用方法:
1、将下面文件放在项目文件夹中
2、在合适的位置引用插件文件,根据需要修改代码中插件的目录位置 $pluginsDirectory = dirname(__FILE__) . '/../plugins';
3、在系统中各个位置设置钩子,例如 <?php Hook::event('execute','a');?>
其中“execute” 是钩子名称,也是调用的插件中的方法名,a是参数
4、在plugins目录中创建一个类 文件名正常写,例如:“header.php” 类名称前必须加“Plugin_”前缀;例如:
<?php
class Plugin_Header implements PluginInterface
{
public function execute($val = '1')
{
echo "你好,这是插件{$val};";
}
}
5、刷新页面看看是否可以调用了呀
插件文件代码如下:
<?php
// 钩子类
class Hook
{
static public $plugins = array();
static public function register(PluginInterface $plugin)
{
static::$plugins[] = $plugin;
}
static public function event($hookName = '',...$val)
{
if ($hookName == '') {
return false;
}
foreach (static::$plugins as $plugin) {
if (method_exists($plugin, $hookName)) {
call_user_func(array($plugin, $hookName),...$val);
}
}
}
}
/**
* 插件接口
*/
interface PluginInterface
{
}
$pluginsDirectory = dirname(__FILE__) . '/../plugins';
// 自动加载插件类
spl_autoload_register(function ($className) use ($pluginsDirectory) {
if (strpos($className, 'Plugin_') === 0) {
$fileName = str_replace('_', '/', substr($className, 7)) . '.php';
$fileName = $pluginsDirectory . DIRECTORY_SEPARATOR . $fileName;
// var_dump(file_exists($fileName));
require_once $fileName;
}
});
// 注册plugins目录内的所有 PHP 文件为插件
function registerPlugins($directory)
{
if (!is_dir($directory)) {
return false;
}
$files = scandir($directory);
foreach ($files as $file) {
$filePath = $directory . '/' . $file;
if (is_file($filePath) && pathinfo($filePath, PATHINFO_EXTENSION) === 'php') {
$className = 'Plugin_' . pathinfo($file, PATHINFO_FILENAME);
if (class_exists($className)) {
$plugin = new $className();
if ($plugin instanceof PluginInterface) {
Hook::register($plugin);
} else {
var_dump($className . '不存在!');
die;
}
} else {
var_dump($className . '不存在');
die;
}
}
}
}
//注册插件
registerPlugins($pluginsDirectory);