devgeniem / wp-queue
WordPress Queue 是一个用于管理 WordPress 中队列任务的模块化库。
Requires
- php: ^7.4 || ^8.0 || ^8.1
- psr/container: ^1.1.1
- psr/log: ^1.1.3
Requires (Dev)
- 10up/wp_mock: ^0.4.2
- brainmaestro/composer-git-hooks: ^v2.8.5
- devgeniem/geniem-rules-codesniffer: ^1
- m6web/redis-mock: ^5
- phpunit/phpunit: ^9
- predis/predis: 2.0.x-dev as 2.0.0.0
- roave/security-advisories: dev-latest
This package is auto-updated.
Last update: 2024-08-29 16:01:59 UTC
README
WordPress 队列
WordPress Queue 是一个用于管理 WordPress 中队列任务的模块化库。
安装
使用 Composer 安装
composer config repositories.wp-queue git git@github.com:devgeniem/wp-queue.git
composer require devgeniem/wp-queue
插件在 plugins_loaded
钩子中初始化自己。您的代码应该在 WordPress 运行此钩子之后开始使用插件功能。另一种选择是使用提供的过滤器 wqp_init_hook
自定义插件初始化钩子。有关详细信息,请参阅 plugin.php。
功能
队列结构
一个队列由其名称、一个条目处理器和一些条目组成。条目是静态类型对象,包含数据。条目处理器是在取消队列单个条目时调用的控制器。名称用于识别队列,例如,使用 WP-CLI。
使用 \Geniem\Queue\Interfaces\QueueInterface
接口定义队列功能。您可以通过实现此接口创建自己的队列控制器。我们提供了一个抽象类 Geniem\Queue\Instance\Base
,您可以从它作为起点进行扩展。
创建队列
要创建队列,请使用队列的唯一名称调用实现构造函数。要使 WordPress 队列了解您的队列,请通过 wpq_add_queue
钩子将其传递给队列容器。队列容器实现了 PSR-11 容器接口。
以下是一个创建 Redis 队列的示例
add_action( 'wpq_add_queue', function( \Psr\Container\ContainerInterface $container ) { $my_queue = new Geniem\Queue\Instance\RedisQueue( 'my_queue' ); // ... $container->add( $my_queue ); }, 1, 1 );
在创建新队列时,所有条目都应存储在受保护的 $entries
属性中,作为实现 \Geniem\Queue\Interfaces\EntryInterface
类的实例。实际的条目数据是无类型的,但我们鼓励在特定队列中保持类型的一致性。实际的条目处理器可以通过实现 \Geniem\Queue\Interfaces\EntryFetcherInterface
接口来创建。
使用 Geniem\Queue\QueueCreator
类处理队列创建。这确保了所有依赖项都具有严格的类型并且已注入到位。
访问队列
要手动与您之前创建的队列交互,您可以通过插件的队列容器访问它。要访问插件,您可以使用全局辅助函数 wpq()
。它返回插件的单例。
$my_queue = wpq()->get_queue_container()->get( 'my_queue' );
条目处理
一个队列由实现 \Geniem\Queue\Interfaces\EntryInterface
接口的条目列表组成。WordPress 队列对条目的处理方式是中立的。这留给您来实现。取消队列使用调用 handle 方法的 try-catch 块。因此,如果处理过程失败,您的处理器应该抛出错误。这允许记录错误并决定是继续取消队列还是回滚到队列中的上一个状态。以下是一个仅记录队列中数据的简单处理程序示例。
class MyHandler implements \Geniem\Queue\Interfaces\EntryHandlerInterface { public function handle( \Geniem\Queue\Interfaces\EntryInterface $entry ) { error_log( 'Entry data: ' . $entry->get_data() ); } }
创建处理程序后,将其实例传递给您的队列
add_action( 'wpq_add_queue', function( \Psr\Container\ContainerInterface $container ) { $my_queue = new Geniem\Queue\Instance\RedisQueue( 'my_queue' ); // Set the handler. $my_queue->set_entry_handler( new Myhandler() ); $container->add( $my_queue ); }, 1, 1 );
条目检索和入队
WordPress 队列引入了“检索器”的概念。检索器是一个具有为队列检索更多条目功能的实例。检索器应实现 \Geniem\Queue\Interfaces\EntryFetcherInterface
接口。使用检索器的一个示例是将您的队列集成到提供数据的 API 中。
Geniem\Queue\Enqueuer
类调用检索器的 fetch 方法,并将结果数组项包装成条目对象(如果尚未包装)。然后,每个条目都通过给定队列实例的 enqueue 方法运行。
以下是一个始终返回相同条目数组的简单检索器示例。
class MyFetcher implements \Geniem\Queue\Interfaces\EntryFetcherInterface { public function fetch() : ?array { $entry_data = [ 'Item 1', 'Item 2', 'Item 3', 'Item 4', ]; return $entries; } }
然后,为您的队列添加一个检索器实例
add_action( 'wpq_add_queue', function( \Psr\Container\ContainerInterface $container ) { $my_queue = new Geniem\Queue\Instance\RedisQueue( 'my_queue' ); // Set the fetcher. $my_queue->set_entry_fetcher( new MyFetcher() ); $container->add( $my_queue ); }, 1, 1 );
获取过程使用 Geniem\Queue\Enqueuer
运行。您可以使用 WP-CLI 命令运行它,或者如果想在 PHP 中手动运行,请运行以下代码
$enqueuer = new \Geniem\Queue\Enqueuer();
$enqueuer->fetch( $my_queue );
要添加单个条目,调用 enqueue
方法并传入一个条目
$entry = ( new \Geniem\Queue\Entry() )->set_data( 'Just a string' );
$enqueuer = new \Geniem\Queue\Dequeuer();
$enqueuer->enqueue( $my_queue, $entry );
注意!您可以直接从您的队列实例调用 enqueue 方法,但我们建议使用 enqueue 来进行通用错误处理和日志记录。
出队
出队过程处理队列中的第一个条目。如果处理成功,条目将被从队列中弹出。请注意,队列处理过程的最终实现取决于队列类。
出队过程由 Geniem\Queue\Dequeuer
处理。当使用 WP-CLI 命令时,这会自动完成。如果您想手动运行出队,请执行以下操作
$dequeuer = new \Geniem\Queue\Dequeuer();
$dequeuer->dequeue( $my_queue );
注意!您可以直接从您的队列实例调用 dequeue 方法,但我们建议使用 dequeue 来进行通用错误处理和日志记录。
示例
在以下示例中,我们创建了一个简单的获取器,它返回包含简单字符串数据的条目数组。然后处理程序只是将数据记录到 PHP 错误日志中。整个过程通过创建 Redis 队列来完成。之后,队列可以通过 WP-CLI 访问。
获取器示例
class MyFetcher implements \Geniem\Queue\Interfaces\EntryFetcherInterface { public function fetch() : ?array { $entry_data = [ 'Item 1', 'Item 2', 'Item 3', 'Item 4', ]; $entries = array_map( function( $data ) { $entry = new \Geniem\Queue\Entry(); $entry->set_data( $data ); return $entry; }, $entry_data ); return $entries; } }
处理程序示例
class MyHandler implements \Geniem\Queue\Interfaces\EntryHandlerInterface { public function handle( \Geniem\Queue\Interfaces\EntryInterface $entry ) { error_log( 'Entry data: ' . $entry->get_data() ); } }
使用示例
为了允许 WordPress 队列通过其名称 "my_queue" 找到我们的示例队列,我们必须通过将其添加到 wpq_add_queue
钩子中的队列容器来定义它。在这里,我们使用默认的 RedisQueue 作为我们的队列实例。要向容器中添加新的队列,请调用 add
方法。要替换具有相同名称的现有队列,请调用 replace
方法。
add_action( 'wpq_add_queue', function( \Psr\Container\ContainerInterface $container ) { $redis_queue = new Geniem\Queue\Instance\RedisQueue( 'my_queue' ); $redis_queue->set_entry_fetcher( new MyFetcher() ); $redis_queue->set_entry_handler( new MyHandler() ); $container->add( $redis_queue ); }, 1, 1 );
WP-CLI 命令
队列实例化并添加到队列容器后,您可以通过 WP-CLI 与其交互。
创建
要创建队列,请调用 WP-CLI 的 create
命令。这将运行队列设置中设置的获取器(如果有的话),并通过保存新获取的条目来(重新)创建队列。
wp queue create my_queue
出队
创建后,您可以从队列中出队一个条目
wp queue dequeue my_queue
获取
要向队列中获取更多条目,运行 fetch
命令。此命令将尝试调用获取器的 fetch
方法并将找到的条目追加到队列中。
wp queue fetch my_queue
测试
该插件使用 PHPUnit 在本地进行测试,并通过 GitHub 的 Travic CI 自动测试。对于本地测试,我们提供了一个 Dockerfile 配置,用于在 Docker 容器中运行 PHPUnit。容器还包含 pywatch,用于监视更改测试并在重新运行它们。要本地运行测试,请导航到您的插件目录并按照以下过程操作
# Install local composer packages.
composer install
# Build and tag the container.
docker build . -t phptest:7.4
# Run the container and watch changes.
docker run --rm -it -v $(pwd):/opt phptest:7.4 "php ./vendor/bin/phpunit" ./tests/*.php