
php-hooks 库的 `apply_filters()` 默认仅返回最后一个回调的返回值;若需收集所有已注册同名钩子的返回结果,须手动遍历调用或改用支持“累积模式”的钩子机制。
在 PHP-Hooks(bainternet/PHP-Hooks)中,add_filter() 允许为同一钩子名注册多个回调函数,但 apply_filters($hook, $value) 的行为是链式传递:前一个回调的返回值会作为参数传给下一个回调(即 $value 被不断覆盖),最终只返回最后一个回调的执行结果。这正是你观察到 'xy' 输出和最终数组仅含 y 的根本原因:
// 执行流程等价于: $value = 'some value to be passed'; $value = call_user_func($callback1, $value); // → "x" $value = call_user_func($callback2, $value); // → call_user_func($cb2, "x") → 输出 "x",返回 "y" // 最终 apply_filters 返回 "y"
因此,无法通过重复调用 add_filter('my_filter', ...) 并单次 apply_filters('my_filter', ...) 实现多结果收集。
✅ 正确解法:为每个逻辑回调分配唯一钩子名,并显式循环调用
app_hooks()->add_filter('my_filter_x', function ($value) {
echo $value; // 输出: some value to be passed
return "x";
});
app_hooks()->add_filter('my_filter_y', function ($value) {
echo $value; // 输出: some value to be passed(注意:不再是 "xy")
return "y";
});
$my_tabs = [];
$hook_names = ['my_filter_x', 'my_filter_y'];
foreach ($hook_names as $hook) {
$result = app_hooks()->apply_filters($hook, 'some value to be passed');
$my_tabs[] = $result;
}
print_r($my_tabs);
// 输出:
// Array
// (
// [0] => x
// [1] => y
// )⚠️ 注意事项:
立即学习“PHP免费学习笔记(深入)”;
- 避免复用同一钩子名期望“并行执行”——PHP-Hooks 本质是过滤器链(filter chain),非事件总线(event bus);
- 若业务逻辑强依赖“同一语义钩子触发多个独立处理”,建议封装一层调度器,或迁移到更成熟的钩子系统(如 WordPress Hooks 或 Symfony EventDispatcher);
- 确保 php-hooks.php 已正确加载且 $hooks 全局实例唯一,多次调用 app_hooks() 应返回同一对象(可加 static $instance 缓存优化)。
总结:PHP-Hooks 的设计目标是值转换(transform),而非结果聚合(collect)。需要多结果时,请主动解耦钩子命名并循环调用——这是清晰、可控且符合库设计意图的做法。











