jenryollivierre/php-application-hooks

PHP 应用钩子是一个轻量级的独立包,允许您控制代码在应用中的执行时机和位置。

v2.0.0 2018-09-28 02:47 UTC

This package is auto-updated.

Last update: 2024-09-07 12:56:16 UTC


README

介绍

PHP 应用钩子是一个轻量级的独立包,允许您控制特定代码块在应用中的执行时机和位置。

安装

使用 composer 通过 composer require "jenryollivierre/php-application-hooks": "2.0.*" 安装,或从 github 下载

如何使用

首先创建一个全局可访问的实例来开始。

<?php

use JenryOllivierre\Hooks\Hooks;

$hooks = new Hooks;

然后,在您希望第三方应用能够执行操作的点,调用以下任一方法。

  • $hooks->applyActions($name, $arguments)
  • $hooks->applyFilters($name, $value, $arguments)

动作

当需要执行动作/任务时,我们使用动作。为了让第三方应用能够在应用中的特定点执行动作,您需要调用 $hooks->applyActions() 方法,该方法需要三个参数。

  • string $name :: 用于识别动作的名称。这应该是唯一的。
  • array $arguments :: 要传递给第三方应用钩子动作的参数数组。
  • bool $return :: 是否返回动作的内容。默认为 false,因为动作通常不应该返回任何内容。

动作示例

<?php

// The point in our application where we want to allow 3rd party apps to do something.

// Example - Let's allow 3rd party apps to do anything they want before a post is deleted
$postId = getPostId();
$canDelete = canPostBeDeleted($postId);
$hooks->applyActions('before_post_delete', [$postId, $canDelete]);

现在,为了让第三方应用能够钩入您的动作,它们将调用全局 $hook 实例并调用 addAction() 方法。

<?php

// Example in the 3rd party app - Let's clean up the database before we delete the post
$hooks->addAction('before_post_delete', [new Post, 'cleanUpDatabase'], 10);

addAction() 方法需要四个参数。

  • string $name :: 要钩入的动作的名称。
  • callable $callback :: 闭包 | 函数名称 | 类实例及其方法的数组
  • int $priority :: 默认为 100。数字较大的动作具有更高的优先级,最后执行。
  • int $arguments :: 传递给 $callback 的参数数量。默认情况下,这传递所有参数。如果主应用向动作传递了 5 个参数的数组,第三方应用可以声明为 2,以仅获取前两个参数。

为了解决上述示例,使用的回调函数是 Post::cleanUpDatabase()。它的工作方式如下

<?php

class Post
{
    /**
     * @param int $postId
     * @param bool $canDelete
     * @return void
     */
    public function cleanUpDatabase($postId, $canDelete)
    {
        // Do stuff
    }
}

过滤器

当需要过滤值时,我们使用过滤器。为了在应用中的特定点执行过滤器,您需要调用 $hooks->applyFilters() 方法,该方法需要三个参数。

  • string $name :: 用于识别过滤器的名称。这应该是唯一的。
  • mixed $value :: 要过滤的值。
  • array $arguments :: 要传递给第三方应用钩子过滤器的参数数组。

** 注意,$value 参数也将作为第一个参数传递给 $arguments。因此,从技术上讲,$arguments 数组中的所有内容都将作为第二个参数及以后传递给第三方应用。

过滤器示例

<?php

// Example of code in our application
// Let's allow 3rd party apps to determine if the post should be deleted

$postId = getPostId();
if ($hooks->applyFilters('user_can_delete_post', false, [$postId])) {
    deletePost($postId);
}

现在,为了让第三方应用能够钩入我们的过滤器,它们将调用全局 $hook 实例并调用 addFilter() 方法。

<?php

// Example in our 3rd party app - Let's check to see if the post should be allowed to be deleted

// Closure Example
$hooks->addFilter('user_can_delete_post', function ($value, $postId) {
    // The value to filter is always the first parameter passed to your callback
    // Any other parameters passed through the 'applyFilters()' method will be available in the order they were passed to the array
    $post = getPost($postId);
    $user = getCurrentUser();

    if ($user->id === $post->author) {
        return true;
    }

    // Tip:: Always return the original value if your conditionals doesn't match
    return $value;
});

// Function name example
$hooks->addFilter('user_can_delete_post', 'someFunctionName', 10, 2);

function someFunctionName($value, $postId)
{
    $post = getPost($postId);
    $user = getCurrentUser();

    if ($user->id === $post->author->id) {
        return true;
    }

    return $value;
}

// Class instance example
$hooks->addFilter('user_can_delete_post', [Post, 'userCanDeletePost'], 10, 1);

// In our Post class
class Post
{
    public function userCanDeletePost($canDelete)
    {
        if (getCurrentUser() === 'super_admin') {
            return true;
        }

        return $canDelete;
    }
}

addFilter() 方法需要四个参数。

  • string $name :: 要钩入的过滤器的名称。
  • callable $callback :: 闭包 | 函数名称 | 类实例及其方法的数组
  • int $priority :: 默认为 100。数字较大的过滤器具有更高的优先级,最后执行。
  • int $arguments :: 传递给 $callback 的参数数量。默认情况下,这传递所有参数。

扩展与创建自己的

该软件包完全可扩展,允许您创建自己的'钩子'。您只需扩展'JenryOllivierre\Hooks\HooksFoundation'类,然后定义自己的方法。例如

<?php

namespace MyNameSpace\Task;

use JenryOllivierre\Hooks\HooksFoundation;

class AppHooks extends HooksFoundation implements Filterable, Actionable
{
    use HasActions;
    use HasFilters;
}

或者自己创建

<?php

namespace MyNameSpace\Task;

use JenryOllivierre\Hooks\HooksFoundation;

class Hooks extends HooksFoundation
{
    /**
     * Add a task hook.
     *
     * @param string $name
     * @param callable $callback
     * @param int $priority
     * @param int $params
     * @return void
     */
    public function addAppTask(string $name, callable $callback, int $priority = 100, int $params = 0)
    {
        $this->storeHook('app_tasks', $name, $callback, $priority, $params);
    }

     /**
     * Apply all the callbacks that was added to a specific task.
     *
     * @since 1.0
     * @param string $name
     * @param array $args
     * @param bool $return
     * @return mixed|void
     */
    public function applyAppTasks(string $name, array $args, bool $return = false)
    {
        return $this->resolveTasks('app_tasks', $name, $args, $return);
    }
}

HooksFoundation类提供许多有用的方法,允许您完全扩展并创建自己的钩子类。它们包括

    /**
     * Add a hook.
     * @param string $type
     * @param string $name
     * @param callable $callback
     * @param int $priority
     * @param int $params
     * @return void
     */
    protected function storeHook(string $type, $name, callable $callback, int $priority = 100, int $params = 1);

    /**
     * Resolve all the values for a given hook.
     * @since 1.0
     * @param string $hookType
     * @param string $name
     * @param mixed $value
     * @param array $args
     * @return mixed
     */
    protected function resolveValues(string $hookType, string $name, $value, array $args = []);

    /**
     * Resolve all the tasks for a given hook.
     * @since 1.0
     * @param string $hookType
     * @param string $name
     * @param array $args
     * @param bool $return
     * @return void
     */
    protected function resolveTasks(string $hookType, string $name, array $args = [], bool $return = false);

    /**
     * Check if anything have been added to a particular hook type.
     * @since 1.0
     * @param string $type
     * @return bool
     */
    protected function hookTypeExists(string $type);

    /**
     * Check if there has been anything set for a specific hook, for a
     * particular hook type.
     * @since 1.0
     * @param string $hookType
     * @param string $name
     * @return bool
     */
    protected function hookExistsByType(string $hookType, string $name);

    /**
     * Get everything that has been added to a specific hook type.
     * @since 1.0
     * @param string $type
     * @return array
     */
    protected function getAllHooksByType(string $type);

    /**
     * Remove all hooks from a hook type.
     * @since 1.0
     * @param string $type
     * @return void
     */
    protected function removeAllHooksFromType(string $type)

    /**
     * Get everything that have been added to a specific hook, for a
     * particular hook type.
     * @since 1.0
     * @param string $type
     * @param string $name
     * @return array
     */
    protected function getHookByType(string $type, string $name);

    /**
     * Remove a hook type.
     * @since 1.0
     * @param string $type
     * @return void
     */
    protected function removeHookType(string $type);

    /**
     * Remove a specific hook for a particular hook type.
     * @since 1.0
     * @param string $hookType
     * @param string $name
     * @return void
     */
    protected function removeHookByType(string $hookType, string $name);

安全漏洞

如果您发现任何安全漏洞,请通过电子邮件联系Jenry Ollivierre,邮箱地址为jenry@jenryollivierre.com

许可证

PHP应用程序钩子是开源软件,遵循MIT许可证