a5hleyrich / wp-background-processing
WP Background Processing 可以用来执行非阻塞异步请求,或者作为后台处理工具,允许您排队任务。
Requires
- php: >=7.0
Requires (Dev)
- phpcompatibility/phpcompatibility-wp: *
- phpunit/phpunit: ^8.0
- spryker/code-sniffer: ^0.17.18
- wp-coding-standards/wpcs: ^2.3
- yoast/phpunit-polyfills: ^1.0
Suggests
- coenjacobs/mozart: Easily wrap this library with your own prefix, to prevent collisions when multiple plugins use this library
This package is not auto-updated.
Last update: 2024-09-14 18:26:20 UTC
README
WP Background Processing 可以用来执行非阻塞异步请求,或者作为后台处理工具,允许您排队任务。查看示例插件或阅读相关文章。
受TechCrunch WP Asynchronous Tasks启发。
需要 PHP 5.6+
安装
在项目中安装此库的推荐方法是通过Composer加载
composer require deliciousbrains/wp-background-processing
强烈建议使用Mozart包给库类文件添加前缀,以防止与其他使用此库的项目冲突。
用法
异步请求
异步请求对于将缓慢的一次性任务(如发送电子邮件)推送到后台处理非常有用。一旦请求被发送,它将立即在后台进行处理。
扩展WP_Async_Request
类
class WP_Example_Request extends WP_Async_Request { /** * @var string */ protected $prefix = 'my_plugin'; /** * @var string */ protected $action = 'example_request'; /** * Handle a dispatched request. * * Override this method to perform any actions required * during the async request. */ protected function handle() { // Actions to perform. } }
protected $prefix
应设置为与您的插件、主题或网站自定义函数前缀关联的唯一前缀。
protected $action
应设置为唯一名称。
protected function handle()
应在非阻塞请求期间执行任何逻辑。传递给请求的数据将通过$_POST
访问。
发送请求
实例化请求
$this->example_request = new WP_Example_Request();
如有需要,向请求中添加数据
$this->example_request->data( array( 'value1' => $value1, 'value2' => $value2 ) );
发送请求
$this->example_request->dispatch();
支持链式调用
$this->example_request->data( array( 'data' => $data ) )->dispatch();
后台处理
后台处理与异步请求类似,但允许您排队任务。一旦队列保存并发送,队列中的项目将在后台进行处理。队列也将根据可用服务器资源进行扩展,因此高端服务器将每批处理更多项目。一旦一批完成,下一批将立即开始。
默认情况下,每5分钟运行一次健康检查,以确保存在排队项目时队列正在运行。如果队列失败,它将被重新启动。
队列基于先进先出原则运行,允许即使它已经在处理时,也可以将更多项目推送到队列。在另一个后台处理实例已经运行时保存新一批排队项目并发送,将导致发送快捷操作跳过,现有实例最终会抓取新项目并在轮到它时处理。
扩展WP_Background_Process
类
class WP_Example_Process extends WP_Background_Process { /** * @var string */ protected $prefix = 'my_plugin'; /** * @var string */ protected $action = 'example_process'; /** * Perform task with queued item. * * Override this method to perform any actions required on each * queue item. Return the modified item for further processing * in the next pass through. Or, return false to remove the * item from the queue. * * @param mixed $item Queue item to iterate over. * * @return mixed */ protected function task( $item ) { // Actions to perform. return false; } /** * Complete processing. * * Override if applicable, but ensure that the below actions are * performed, or, call parent::complete(). */ protected function complete() { parent::complete(); // Show notice to user or perform some other arbitrary task... } }
protected $prefix
应设置为与您的插件、主题或网站自定义函数前缀关联的唯一前缀。
protected $action
应设置为唯一名称。
protected function task( $item )
应在队列中执行任何逻辑。返回false
以从队列中删除项目,或返回$item
以将其推回队列以进行进一步处理。如果项目已修改并推回队列,则将在退出批处理之前保存当前状态。
protected function complete()
可选地包含一旦队列完成时要执行的任何逻辑。
发送处理
实例化处理
$this->example_process = new WP_Example_Process();
注意:您必须无条件地实例化您的进程。所有请求都应该这样做,即使没有将任何内容推送到队列中。
将项目推送到队列
foreach ( $items as $item ) { $this->example_process->push_to_queue( $item ); }
项目可以是任何有效的PHP值,字符串、整数、数组或对象。如果需要,$item 在写入数据库时会进行序列化。
保存和分发队列
$this->example_process->save()->dispatch();
处理队列项目中的序列化对象
包含非标量值的队列项目在存储到数据库时会进行序列化。为了避免在unserialize过程中出现潜在的安全问题,此库提供了在调用unserialize()时设置allowed_classes
选项的功能,这限制了可以实例化的类。它作为受保护的$allowed_batch_data_classes
属性内部维护。
为了保持向后兼容性,默认值是true
,这意味着任何序列化的对象都将被实例化。请注意,此默认行为可能在未来的主要版本中更改。
我们鼓励所有此库的用户利用设置$allowed_batch_data_classes
的严格值。如果可能,将值设置为false
以禁止实例化任何对象,或者非常有限的类名列表,请参见下面的示例。
不允许实例化的序列化字符串中的对象将获得类类型__PHP_Incomplete_Class
。
覆盖默认的$allowed_batch_data_classes
可以通过传递允许的类数组到构造函数来覆盖默认行为
$allowed_batch_data_classes = array( MyCustomItem::class, MyItemHelper::class ); $this->example_process = new WP_Example_Process( $allowed_batch_data_classes );
或者,将值设置为false
$this->example_process = new WP_Example_Process( false );
另一种更改默认值的方法是在您的进程类中覆盖$allowed_batch_data_classes
属性
class WP_Example_Process extends WP_Background_Process { /** * @var string */ protected $prefix = 'my_plugin'; /** * @var string */ protected $action = 'example_process'; /** * * @var bool|array */ protected $allowed_batch_data_classes = array( MyCustomItem::class, MyItemHelper::class ); ...
后台进程状态
后台进程可以是排队、处理、暂停、取消或以上都不是(未启动或已完成)。
排队
要检查后台进程是否有排队项目,请使用is_queued()
。
if ( $this->example_process->is_queued() ) { // Do something because background process has queued items, e.g. add notice in admin UI. }
处理中
要检查后台进程是否正在处理队列项目,请使用is_processing()
。
if ( $this->example_process->is_processing() ) { // Do something because background process is running, e.g. add notice in admin UI. }
暂停
您可以使用pause()
暂停后台进程。
$this->example_process->pause();
当前正在处理的数据包将继续,直到它完成或达到时间或内存限制。到那时,它将解锁进程,如果队列已空,则完成数据包,或者执行分发,这将导致处理程序删除健康检查cron并触发“暂停”操作。
要检查后台进程是否当前已暂停,请使用is_paused()
。
if ( $this->example_process->is_paused() ) { // Do something because background process is paused, e.g. add notice in admin UI. }
您可以通过处理后台进程标识符($prefix + $action)的“暂停”操作来响应后台处理被暂停。
add_action( 'my_plugin_example_process_paused', function() { // Do something because background process is paused, e.g. add notice in admin UI. });
您可以使用resume()
恢复后台进程。
$this->example_process->resume();
您可以通过处理后台进程标识符($prefix + $action)的“恢复”操作来响应后台处理被恢复。
add_action( 'my_plugin_example_process_resumed', function() { // Do something because background process is resumed, e.g. add notice in admin UI. });
已取消
您可以使用cancel()
取消后台进程。
$this->example_process->cancel();
当前正在处理的数据包将继续,直到它完成或达到时间或内存限制。到那时,它将解锁进程,如果队列已空,则完成数据包,或者执行分发,这将导致处理程序删除健康检查cron,删除所有排队项目的所有数据包,并触发“取消”操作。
要检查后台进程是否当前已取消,请使用is_cancelled()
。
if ( $this->example_process->is_cancelled() ) { // Do something because background process is cancelled, e.g. add notice in admin UI. }
您可以通过处理后台进程标识符($prefix + $action)的“取消”操作来响应后台处理被取消。
add_action( 'my_plugin_example_process_cancelled', function() { // Do something because background process is paused, e.g. add notice in admin UI. });
“已取消”操作在队列被清理并取消状态删除后触发。之后,由于后台进程现在是休眠的,is_cancelled()
将不再为真。
活跃
要检查后台进程是否有排队项目,是否正在处理,是否已暂停或正在取消,请使用is_active()
。
if ( $this->example_process->is_active() ) { // Do something because background process is active, e.g. add notice in admin UI. }
如果后台进程不活跃,那么它要么还没有任何排队待处理的项目并且尚未启动,要么已经处理完所有排队项目。
BasicAuth
如果你的站点位于BasicAuth之后,异步请求和后台进程将无法完成。这是因为WP后台处理依赖于WordPress HTTP API,该API要求你将BasicAuth凭据附加到请求中。最简单的方法是使用以下过滤器
function wpbp_http_request_args( $r, $url ) { $r['headers']['Authorization'] = 'Basic ' . base64_encode( USERNAME . ':' . PASSWORD ); return $r; } add_filter( 'http_request_args', 'wpbp_http_request_args', 10, 2);
贡献
我们欢迎通过拉取请求进行贡献,但请在开始工作之前请提出一个问题,以便讨论变更,如果没有已经存在的问题。如果你有一个已经批准的问题想要解决,请在该问题上发表评论,让其他人知道你将尝试解决它,以避免重复劳动造成的浪费。
单元测试与风格测试
在处理库时,请将单元测试添加到tests
目录中适当的文件,以涵盖你的更改。
设置
我们使用标准的WordPress测试库来运行单元测试。
请运行以下命令来设置库
bin/install-wp-tests.sh db_name db_user db_pass
请根据需要替换db_name
、db_user
和db_pass
。
请注意,运行单元测试是一种破坏性操作,数据库表将被清空,因此请使用专门用于运行单元测试的数据库名称。WordPress社区通常使用的标准数据库名称是wordpress_test
,例如。
bin/install-wp-tests.sh wordpress_test root root
如果你遇到任何问题,请参阅WordPress手册的插件集成测试部分中的本地初始化测试环境部分。
运行单元测试
要运行单元测试,只需运行
make test-unit
如果composer
依赖项尚未就绪,它们将自动安装。
运行风格测试
库中的代码使用一致的风格非常重要,这有助于快速理解它,并避免一些常见问题。《PHP_Code_Sniffer》与大部分标准WordPress规则一起使用,以帮助检查一致性。
要运行风格测试,只需运行
make test-style
如果composer
依赖项尚未就绪,它们将自动安装。
运行所有测试
为了使事情尽可能简单,只需运行以下命令来运行所有测试
make
如果composer
依赖项尚未就绪,它们将自动安装。
创建PR
在创建PR时,请确保在描述的顶部提及要解决的哪个GitHub问题,例如。
解决#123
单元测试和风格测试将自动运行,除非通过,否则PR将无法合并,并且分支必须与master
保持最新。