piggly / php-hooks
控制当特定TAG被调用时将执行的钩子。
Requires
- php: ^7.1
Requires (Dev)
- phpunit/phpunit: ^6.4
This package is auto-updated.
Last update: 2024-08-29 05:37:24 UTC
README
要阅读此文件的葡萄牙语版本,请点击此处
此库受到Wordpress核心中可用的函数
do_action
和apply_filter
的启发。
钩子是在特定、预定义的位置运行某些代码的方式。此功能的主要优点是钩子可以累积在请求时才执行的一组函数。
与Wordpress建议相反,此库中有三种类型的钩子:过滤器、动作和调度器。所有这些都在标签上注册了回调
,包括或不包括参数。然后,该标签可以执行。
如果您喜欢这个库并想支持这项工作,请随意向BTC钱包
3DNssbspq7dURaVQH6yBoYwW3PhsNs8dnK
捐赠任何金额 ❤。
安装
可以使用Composer
通过以下命令安装此库:composer require piggly/php-hooks
;
注册回调
只要钩子标签没有被触发,就可以添加和/或删除注册到该标签的回调。对于每个注册的回调,都可以创建一个由以下内容组成的标签:标签名称、函数名称、必需参数和执行优先级。
标签可以通过两种方式形成:使用Syntax::create()
函数或使用以下标签语法编写字符串。
标签的语法由以下组成
{tagname}
:(必需)标签名称;.{function_name}
:函数名称;?{args}
:要接收的参数数量,默认总是为1
;::{priority}
:执行优先级,默认总是为10
;
给回调起的名字总是需要唯一的。如果函数名称已存在于标签中,它将引发
NameAlreadyExistsException
。
标签语法正则表达式为/^(?:(?P
。如果标签语法错误,将引发InvalidSyntaxException
。
例如
- 要注册一个具有标签
calculate
和优先级1
的回调,标签语法将是:calculate::1
; - 要注册一个具有标签
calculate
、名称pow
和接收两个参数的回调,标签语法将是:calculate.pow?2
;
下面是另一个示例
// Register in tag calculate $tag = 'calculate'; // Register in tag calculate ready to recieve two args $tag = 'calculate?2'; // Register in tag calculate with priority 1 $tag = 'calculate::1'; // Register in tag calculate ready to recieve two args and priority 1 $tag = 'calculate?2::1'; // Register in tag calculate with name sum $tag = 'calculate.sum'; // Register in tag calculate with name sum ready to recieve two args $tag = 'calculate.pow?2'; // Register in tag calculate with name sum and priority 1 $tag = 'calculate.sum::1'; // Register in tag calculate with name sum, ready to recieve two args and priority 1 $tag = 'calculate.pow?2::1';
回调
除了需要标签外,任何注册的函数还需要一个回调
。可以通过Hook::filter()
、Hook::action()
和Hook::dispatch()
方法接收的回调有
Closure
:闭包对象类型Hook::filter( $tagSyntax, function ( $number ) { return $number + 15; } );
Function
:一个指向函数名称的string
Hook::filter( $tagSyntax, 'sum' );
Static Object
:具有静态函数的class
,指向类名和静态方法Hook::filter( $tagSyntax, StaticClass::class, 'methodToCall' );
Object
:一个对象的instance
,指向要调用的对象方法Hook::filter( $tagSyntax, $instance, 'methodToCall' );
附加参数
在引用了 callback
之后,最后几个参数将始终是该函数附加的附加参数。例如,Hook::dispatch( $tagSyntax, 'sum', 1 );
将有一个附加参数为 1
。附加参数仅在 Hook::dispatch()
方法中使用。
以下详细了解
Hook::filter()
、Hook::action()
和Hook::dispatch()
。
过滤器 x 动作 x 分发器
这三种类型的钩子的主要区别是
- 过滤器在执行点接收信息,以某种方式修改它并返回它。换句话说:修改某些内容并返回以供下一个过滤器使用,依此类推;
一个过滤器的例子是过滤器
Hook::apply('comment', $comment)
,它通过删除非法单词、删除链接等来过滤评论。
- 动作在执行点接收信息,对其进行操作并返回空值。换句话说:执行某些操作,然后以开始、中间和结束的方式结束你的代码。
一个动作的例子是创建新票据时的通知
Hook::run('new_ticket', $ticket)
。该动作将接收$ticket
并相应地发送通知。
- 分发器类似于动作,但它不是在执行点接收信息,而是在注册点接收信息。换句话说:它执行与执行点无关的操作,但会干扰它。
一个分发器的例子是在 HTML 标签中包含 CSS 文件
Hook::run('head')
。在这里,分发器将在注册时接收 CSS$name
文件,即Hook::dispatch('head', 'importCss', 'home.css')
时。
Hook::filter()
过滤器
过滤器 使钩子能够在执行过程中操纵数据。过滤器函数将接收一个变量,修改它并返回它。注册在过滤器中的函数必须独立工作,并且永远不应该有副作用。过滤器始终期望从它们那里返回某些内容。
要将新回调注册到过滤器,应使用以下参数调用 Hook::filter()
方法
$tagSyntax
:函数将注册的标签语法;$callback, ?$method
:要执行的回调。
要应用过滤器,应使用以下参数调用 Hook::apply()
方法
$tag
:将要执行的标签名称;$value
:要过滤的初始值;...$params
:要过滤的附加参数(Hook::filter()
需要能够在标签语法中接收这些参数,以?{args}
的形式,默认情况下始终为1
);
此外,还有两种 Hook::apply()
方法的变体
Hook::applyByName()
仅执行特定标签的一个函数;Hook::applyOnce()
仅执行标签一次,之后,它将无法再使用;
还可以使用 Hook::removeFilter()
方法在执行之前删除过滤器。
提示:当过滤器标签在应用程序生命周期中仅使用一次时,请使用
Hook::applyOnce()
方法,它将在运行时释放内存空间。
以下是一个使用过滤器的实际示例
function fsum ( $number ) { return $number+15; } function fsub ( $number ) { return $number - 10; } function fmul ( $number ) { return $number * 3; } function fdiv ( $number ) { return $number / 2; } function fpow ( $number, $exp ) { return is_numeric($exp) ? pow($number, $exp) : $number; } Hook::filter('calculate.sum', 'fsum'); Hook::filter('calculate.sub', 'fsub'); Hook::filter('calculate.mul', 'fmul'); Hook::filter('calculate.div', 'fdiv'); // -> Apply => Expects (((10+15)-10)*3)/2 = 22.5 $number = Hook::apply('calculate', 10); echo sprintf("Number: %s\n", $number);
完整示例可在 此处 查看。
Hook::action()
动作
动作 允许您修改应用程序的行为。动作的函数可以写入一些输出,将数据插入数据库,发送通知等。注册在动作中的函数必须始终执行某种类型的任务,因此不会发生任何类型的返回。
要注册一个新回调到动作,应使用以下参数调用方法 Hook::action()
$tagSyntax
:函数将注册的标签语法;$callback, ?$method
:要执行的回调。
要运行一个动作,应使用以下参数调用方法 Hook::run()
$tag
:将要执行的标签名称;...$params
:传递给动作的附加参数(Hook::action()
需要能够以?{args}
语法接收这些参数,默认情况下总是1
);
此外,还有两种 Hook::run()
方法变体,它们是:
Hook::runByName()
只执行标签的特定功能;Hook::runOnce()
只执行一次标签,之后将无法再使用;
还可以使用方法 Hook::removeAction()
在执行前删除动作。
提示:当动作标签在应用程序的生命周期中只使用一次时,请使用
Hook::runOnce()
方法,它将在运行时释放内存空间。
以下是一个使用动作的实际示例
function line () { echo "I am line 02\n"; } function message ( $message ) { echo sprintf("Message: %s\n", $message); } Hook::action('sentences.line', 'line'); Hook::action('sentences.message', 'message'); Hook::run('sentences', 'Peace and Love');
完整示例请访问 这里。
分发器 Hook::dispatch()
分发器 具有与动作相同的行为。它们执行没有返回值的代码片段,并通过 Hook::dispatch()
方法注册。然而,它们接收附加参数的方式与动作不同。
假设您的应用程序中有一个 head
钩子,该钩子会在应用程序的 <head>
标签中添加 HTML 标签。
<html> <head> <?php Hook::run('head'); ?> </head> <body> </body> </html>
假设您有一个 Controller
,它包含 home()
、services()
和 about()
方法(每个页面一个),以及 home.css
、services.css
和 about.css
文件。要将这些文件包含在 head
中,需要为每个动作创建一个回调。请参阅
class Controller { // ... public function home() { Hook::action('head', $this, 'homeAction'); // ... } public function services() { Hook::action('head', $this, 'servicesAction'); // ... } public function about() { Hook::action('head', $this, 'aboutAction'); // ... } public function homeAction () { /** Add css file... **/ } public function servicesAction () { /** Add css file... **/ } public function aboutAction () { /** Add css file... **/ } // ... }
这不是很无聊吗?这是因为方法 Hook::run('head')
不会为动作传递参数,并且动作不会接收参数。这是因为我们需要一个回调来处理每个动作。此外,无法在执行点 Hook::run('head')
将 home()
、services()
和 about()
所需的参数传递给它们。
分发器就是为了解决这个问题而创建的。在这种情况下,假设我们有一个 importCss($name)
函数。该函数使用 $name
作为 CSS 文件名,在页面中生成 <link>
标签。现在,我们只需要将此函数的分发器与参数 $name
注册。请参阅
class Controller { // ... public function home() { Hook::dispatch('head', 'importCss', 'home.css'); // ... } public function services() { Hook::dispatch('head', 'importCss', 'services.css'); // ... } public function about() { Hook::dispatch('head', 'importCss', 'about.css'); // ... } // ... }
如您所见,我们简化了代码,并且使用了更高效的钩子。使用触发器,我们可以更智能地将函数包含在代码中,而无需依赖与创建的动作等效的函数(因为动作不允许在 Hook::run()
执行点之外传递附加参数)。
非常重要的一点是要理解,钩子 Hook::run('new_ticket', $ticket)
会发送 $ticket
参数,并且该参数将以 Hook::action('new_ticket.notification', 'notification');
的形式传递给任何动作,但它不会通过 Hook::dispatch('new_ticket.notification', 'notification', $ticket);
传递,后者需要在注册时包含 $ticket
。
当需要继承
Hook::run()
执行参数时,必须使用动作;而当我们想在钩子内包含具有自己参数的函数时,必须使用分发器。
还可以使用方法 Hook::removeDispatcher()
在执行前删除分发器。
以下是一个使用分发器的实际示例
function name ( $message ) { echo sprintf("Your name: %s\n", $message); } function prog ( $message ) { echo sprintf("Progamming Language: %s\n", $message); } Hook::dispatch('sentences.name::1', 'name', 'Alpha'); Hook::dispatch('sentences.prog::1', 'prog', 'JS'); Hook::run('sentences', 'Peace and Love');
完整示例请访问 这里。
变更日志
请查看CHANGELOG文件,了解所有代码更改的信息。
代码测试
此库使用PHPUnit。我们对本应用程序的所有主要类进行了测试。
vendor/bin/phpunit
贡献
在提交贡献前,请参阅CONTRIBUTING文件获取信息。
安全
如果您发现与安全相关的问题,请发送电子邮件至dev@piggly.com.br,而不是使用GitHub的问题跟踪器。
致谢
支持项目
Piggly Studio是一家位于巴西里约热内卢的代理机构。如果您喜欢这个库并希望支持这项工作,请自由地捐赠任意金额至BTC钱包3DNssbspq7dURaVQH6yBoYwW3PhsNs8dnK
❤。
许可证
MIT许可证(MIT)。请参阅LICENSE。