boxuk/wp-hook-attributes

一个mu-plugin,允许在WordPress钩子中使用PHP属性

安装: 19 199

依赖者: 0

建议者: 0

安全性: 0

星级: 10

关注者: 11

分支: 0

开放问题: 1

类型:wordpress-muplugin

0.0.2 2022-03-03 14:04 UTC

This package is auto-updated.

Last update: 2024-08-29 05:44:26 UTC


README

Build Status

安装

composer require boxuk/wp-hook-attributes

启用缓存(使用注解时推荐,用于生产)

基本基于数组的缓存已启用,但生产时您可能希望引入更优的适配器。以下是一个使用memcache的示例,但任何PSR-6适配器都是支持的。

composer require cache/memcache-adapter

use Cache\Adapter\Memcache\MemcacheCachePool;
use Psr\Cache\CacheItemPoolInterface;

if ( wp_get_environment_type() === 'production' ) {
	add_filter(
		'wp_hook_attributes_cache_adapter',
		function ( CacheItemPoolInterface $cache_adapter ): CacheItemPoolInterface {
			global $wp_object_cache;
			if ( $wp_object_cache->get_mc( 'default' ) instanceof \Memcache ) {
				$client = $wp_object_cache->get_mc( 'default' );

				return new MemcacheCachePool( $client );
			}

			return $cache_adapter;
		}
	);
}

注意:这仅适用于使用注解的情况,使用PHP8和属性时不需要。

使用

现在您可以使用注解为函数和方法附加属性并将它们附加到钩子。

use BoxUk\WpHookAttributes\Hook\Attributes\Action;
use BoxUk\WpHookAttributes\Hook\Attributes\Filter;

// Example of using an action hook
#[Action('init')]
function basic_action(): string {
	return 'something...';
}

// Example of using a filter hook
#[Filter('the_content')]
function basic_filter(): string {
	return 'something...';
}

// You can also attach a priority and args
#[Action('init', priority: 20, args: 4)]
function advanced_action( string $arg1, int $arg2, bool $arg3, array $arg4 ): string
	return 'something...';
}

还没有使用PHP8?您可以使用注解代替

use BoxUk\WpHookAttributes\Hook\Annotations\Action;
use BoxUk\WpHookAttributes\Hook\Annotations\Filter;

// Example of using an action hook
/**
 * @Action("init")
 */
function basic_action(): string {
	return 'something...';
}

// Example of using a filter hook
/**
 * @Filter("the_content") 
 */
function basic_filter(): string {
	return 'something...';
}

// You can also attach a priority and args
/**
 * @Action("init", priority="20", args="4")
 */
function advanced_action( string $arg1, int $arg2, bool $arg3, array $arg4 ): string
	return 'something...';
}

注意:低于PHP 7.4的版本不支持。

注册命名空间或前缀(强烈推荐)

您可能想要注册一个命名空间或前缀,以确保它只为您的代码查找属性/注解。您可以通过以下钩子完成此操作

如果您使用注解而不这样做,它可能会非常慢

// Namespace
add_filter( 'wp_hook_attributes_registered_namespaces', function(): array {
	return [
		'BoxUk\Mu\Plugins',
	];
});

// Prefix
add_filter( 'wp_hook_attributes_registered_prefixes', function(): array {
	return [
		'boxuk_',
	];
});

它执行stripos()比较,因此您只需放置命名空间/前缀的前部分即可。

注册文件和类

目前仅适用于在init钩子之前定义的函数和声明的类。为了解决这个问题,您可以使用以下钩子手动注册函数文件或类。但是,这需要在init之前完成,否则解析器需要手动调用(下面有详细说明)。

add_filter( 'wp_hook_attributes_registered_function_files', function( array $registered_files ): array {
	return array_merge(
		$registered_files,
			[
				'path/to/my/file/with/functions.php'
			]
	);
});

add_filter( 'wp_hook_attributes_registered_classes', function( array $registered_classes ): array {
	return array_merge(
		$registered_classes,
			[
				RegistrationService::class,
			]
	);
});

忽略现有的注解名称

有时在 使用注解时可能会出现错误,提示现有的注解尚未导入。这是因为有时您会发现需要忽略的非标准注解或docblock参数。

一些常见的WordPress和相关库默认被忽略,但这不会涵盖所有内容。

您可以使用以下钩子忽略任何您需要的自定义注解

add_filter( 
	'wp_hook_attributes_annotation_ignores',
	function( array $existing_ignores ): array {
		$existing_ignores[] = 'my-custom-annotation';
		return $existing_ignores;
	}
);

限制

init之前的钩子上的属性需要更多的工作

如果您想使用在init钩子之前的钩子,例如muplugins_loaded,您将无法在这些钩子中使用属性而不进行更多努力。因为这些钩子会在调用钩子解析器之前被调用。

/**
 * @ActionAnnotation("muplugins_loaded")
 */
#[Action('muplugins_loaded')]
function muplugins_loaded_action(): void
{
    echo 'on muplugins_loaded action';
}

假设您有一个在muplugins_loaded上的钩子,它是一个预初始化钩子。

/**
 * @ActionAnnotation("muplugins_loaded")
 */
#[Action('muplugins_loaded')]
function muplugins_loaded_action(): void
{
    echo 'on muplugins_loaded action';
}

// Some place earlier than `muplugins_loaded`, maybe a `000-my-project.php` or something within `mu-plugins`.
( new WordPressHookAttributes() )();

muplugins_loaded钩子会在调用钩子解析器的我们的init钩子被调用之前被调用。因此,在这些情况下,您需要手动调用钩子解析器,例如

请参阅下一个限制,了解为什么我们默认不提前加载解析器。

muplugins_loaded
registered_taxonomy
registered_post_type
plugins_loaded
sanitize_comment_cookies
setup_theme
unload_textdomain
load_textdomain
after_setup_theme
auth_cookie_malformed
auth_cookie_valid
set_current_user

来源: http://rachievee.com/the-wordpress-hooks-firing-sequence/

函数/方法必须在init钩子之前注册

属性应该适用于在调用init钩子之前注册的任何函数/方法。任何作为mu-plugintheme部分注册的函数/方法都应该正常工作,因为这些钩子是在init之前被调用的。

不会正常工作的是在 init 钩子之后注册的任何函数/方法,例如以下内容不会正常工作,因为 wp_loaddedinit 之后被调用,因此 my-functions.php 中的函数无法及时注册。

// This will not work.
add_action( 'wp_loaded', function() {
    require_once 'my-functions.php';
});

您可以手动注册文件,但同样,这必须在 init 之前完成,因此要修复上述问题,您可以这样做:

add_action( 'muplugins-loaded', function() {
    add_filter( 'wp_hook_attributes_registered_function_files', function() {
        return [
            'my-functions.php';
        ];
    });
});

类似地,仅仅包含它也会生效。

add_action( 'muplugins-loaded', function() {
    require_once 'my-functions.php';
});

不支持非静态方法。

如果您有一个依赖于当前对象实例的方法,例如:

class Example {
    private $foo = 'world';
    
    public function hello(): string {
        return 'Hello ' . $this->foo;
    }
}

您可以使用 Example 的实例设置一个回调,例如:

$example = new Example();
$callback = [ $example, 'hello' ];

然而,这个库不支持这样做,因为它无法假设如何实例化类。因此,只有静态方法才会工作。这也要求方法被标记为静态,即使它们是隐式静态的。无论如何,这也是一个好的做法,因为如果未显式声明将方法作为静态使用,将会在 PHP 7.4 上引发 PHP 弃用警告,在 PHP 8 上引发致命错误。