本文目录导读:

在 PHP 中预留扩展点通常指以下几种场景,我分别给出实现方案:
面向对象设计中的扩展点(最常用)
抽象类 + 模板方法模式
<?php
abstract class PaymentProcessor
{
// 模板方法 - 定义算法骨架
final public function process()
{
$this->validate();
$this->beforePayment();
$result = $this->executePayment();
$this->afterPayment($result);
return $result;
}
// 预留扩展点(必须实现)
abstract protected function executePayment();
// 钩子方法(可选覆盖)
protected function beforePayment() {}
protected function afterPayment($result) {}
protected function validate() {}
}
接口 + 策略模式
<?php
interface SortStrategy
{
public function sort(array $data): array;
}
class QuickSort implements SortStrategy
{
public function sort(array $data): array
{
// 实现
return $data;
}
}
class DataManager
{
private $strategy;
// 通过构造器注入扩展点
public function __construct(SortStrategy $strategy = null)
{
$this->strategy = $strategy ?? new DefaultSort();
}
// 运行时可替换
public function setStrategy(SortStrategy $strategy)
{
$this->strategy = $strategy;
}
}
事件系统/回调机制
<?php
class EventEmitter
{
private $listeners = [];
// 注册事件监听器
public function on($event, callable $callback)
{
$this->listeners[$event][] = $callback;
}
// 触发事件
public function emit($event, ...$args)
{
foreach ($this->listeners[$event] ?? [] as $callback) {
call_user_func_array($callback, $args);
}
}
}
// 使用示例
$emitter = new EventEmitter();
$emitter->on('user.created', function($user) {
// 扩展点:发送欢迎邮件
});
$emitter->emit('user.created', $user);
通过容器和服务提供者(Laravel 风格)
<?php
class Container
{
protected $bindings = [];
protected $instances = [];
// 注册扩展点
public function bind($abstract, $concrete = null)
{
$this->bindings[$abstract] = $concrete;
}
// 解析服务
public function make($abstract)
{
if (isset($this->instances[$abstract])) {
return $this->instances[$abstract];
}
$concrete = $this->bindings[$abstract] ?? $abstract;
$instance = new $concrete();
// 允许对象通过宏扩展
$this->instances[$abstract] = $instance;
return $instance;
}
// 宏扩展(运行时添加方法)
public function macro($name, $callback)
{
$this->macros[$name] = $callback;
}
}
配置文件驱动的扩展
<?php
class AppConfig
{
public static function load($configFile)
{
$configs = include $configFile;
foreach ($configs as $key => $value) {
self::$config[$key] = $value;
}
}
// 注册第三方扩展
public static function registerExtension($extension)
{
$extension->boot(self::$config);
}
}
组合使用案例:完整的插件系统
<?php
// 插件接口
interface PluginInterface
{
public function registerListeners(EventManager $events);
public function boot(Container $app);
}
// 插件管理器
class PluginManager
{
private $plugins = [];
private $events;
private $container;
public function __construct(EventManager $events, Container $container)
{
$this->events = $events;
$this->container = $container;
}
// 动态加载插件
public function loadPlugin($pluginClass)
{
if (!is_subclass_of($pluginClass, PluginInterface::class)) {
throw new Exception("Invalid plugin");
}
$plugin = new $pluginClass();
$plugin->registerListeners($this->events);
$plugin->boot($this->container);
$this->plugins[] = $plugin;
}
public function getPlugins()
{
return $this->plugins;
}
}
// 使用示例
$manager = new PluginManager($events, $container);
$manager->loadPlugin(PaymentPlugin::class);
$manager->loadPlugin(LoggingPlugin::class);
PHP 8 特性增强扩展
<?php
// 属性(Attributes)用于标记扩展点
#[Attribute]
class ExtensionPoint
{
public function __construct(public string $purpose = '') {}
}
// 注解驱动扩展
class Service
{
// 标记可扩展方法
#[ExtensionPoint('自定义业务逻辑')]
protected function handleRequest()
{
// 默认实现
}
}
最佳实践建议
- 明确接口:定义清晰的接口,确保扩展点稳定
- 组合优于继承:优先使用策略模式而不是继承
- 配置化:允许通过配置文件开启/关闭扩展
- 依赖注入:使用容器管理扩展的依赖
- 版本兼容:为扩展点制定版本策略
// 最终组合示例
abstract class FrameworkExtension
{
// 必须实现的扩展
abstract public function getName(): string;
// 可选配置
public function configure(array $config): void {}
// 生命周期钩子
public function boot(): void {}
public function shutdown(): void {}
}
选择哪种方式取决于你的具体需求:是简单的回调、灵活的策略、还是完整的插件系统?
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播