PHPackages                             x3p0-dev/x3p0-hooks - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. x3p0-dev/x3p0-hooks

ActiveLibrary

x3p0-dev/x3p0-hooks
===================

00PHP

Since Jun 19Pushed todayCompare

[ Source](https://github.com/x3p0-dev/x3p0-hooks)[ Packagist](https://packagist.org/packages/x3p0-dev/x3p0-hooks)[ RSS](/packages/x3p0-dev-x3p0-hooks/feed)WikiDiscussions master Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

X3P0: Hooks
===========

[](#x3p0-hooks)

A lightweight, attribute-based hook system for WordPress plugins and themes. Built with PHP 8.1+, it lets you register WordPress actions and filters declaratively with `#[Action]` and `#[Filter]` attributes instead of manual `add_action()`/`add_filter()` plumbing.

[![License](https://camo.githubusercontent.com/26f8b6541ea045cc1dbc2267208158b5a7ebbf5cf437c4b486d80fee9386f77e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d47504c2d2d322e302d2d6f722d2d6c617465722d626c75652e737667)](LICENSE.md)[![PHP Version](https://camo.githubusercontent.com/04744bae0a61d2ffe29c26f07a9612eae20445fc6feaeb77b3af1f0e9be6447c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253345253344382e312d3838393242462e737667)](https://php.net)

Features
--------

[](#features)

- **Attribute-Based Hooks**: Register WordPress actions and filters declaratively with `#[Action]` and `#[Filter]`
- **Hook Any Member**: Attach hooks to methods, properties, or class constants
- **Repeatable Attributes**: Register a single member on multiple hooks
- **Priority Shorthand**: Use integers or the `'first'` / `'last'` keywords
- **Extensible**: Define your own hook attributes by implementing the `Hook` interface
- **Lightweight**: Minimal overhead, no external dependencies
- **Type-Safe**: Full PHP 8.1+ type declarations for better IDE support

Requirements
------------

[](#requirements)

- PHP 8.1 or higher
- WordPress (recommended latest version)
- Composer

Installation
------------

[](#installation)

Install via Composer:

```
composer require x3p0-dev/x3p0-hooks
```

**Important:** If you're releasing this as part of a theme or plugin bundle, please vendor prefix your installation to avoid conflicts with other plugins/themes.

Quick Start
-----------

[](#quick-start)

Add the `Hookable` trait to a class, mark members with `#[Action]` or `#[Filter]`, and call `boot()`. The trait reflects the class and wires every attributed member to WordPress:

```
use X3P0\Hooks\Action;
use X3P0\Hooks\Filter;
use X3P0\Hooks\Hookable;

final class Assets
{
	use Hookable;

	#[Action('wp_enqueue_scripts')]
	public function enqueue(): void
	{
		wp_enqueue_style('theme', get_stylesheet_uri());
	}

	#[Filter('body_class')]
	public function bodyClass(array $classes): array
	{
		$classes[] = 'x3p0-theme';
		return $classes;
	}
}

// Wire up the hooks.
(new Assets())->boot();
```

The number of arguments passed to the callback is taken from the method's parameter count, so `bodyClass()` above receives the `$classes` argument automatically.

Core Concepts
-------------

[](#core-concepts)

### The `Hookable` Trait

[](#the-hookable-trait)

`Hookable` provides the `boot()` method that does the work. When called, it reflects the class and registers every method, property, and class constant marked with a hook attribute. Methods of any visibility are supported — protected and private methods are bound and registered as closures, so they work as hook callbacks without being public.

`boot()` throws a `ReflectionException` if the class cannot be reflected. If you already have a bootable contract in your project, the trait's `boot()` satisfies it, so a class can both `use Hookable` and implement your own `Bootable`interface.

### The `#[Action]` and `#[Filter]` Attributes

[](#the-action-and-filter-attributes)

`#[Action]` registers a member via `add_action()`, and `#[Filter]` registers it via `add_filter()`. Both accept the hook name and an optional priority:

```
#[Action('init')]
public function setup(): void
{
	// ...
}

#[Filter('the_content', priority: 20)]
public function content(string $content): string
{
	return $content;
}
```

The attributes are repeatable, so a single member can be attached to several hooks. Priority accepts an integer or the shorthand `'first'` (`PHP_INT_MIN`) / `'last'` (`PHP_INT_MAX`):

```
#[Action('init')]
#[Action('wp_loaded', priority: 'first')]
public function bootstrap(): void
{
	// Runs on both `init` (priority 10) and `wp_loaded` (priority PHP_INT_MIN).
}
```

### Hooking Properties and Constants

[](#hooking-properties-and-constants)

Properties and class constants can be hooked too, in which case their value is returned to the filter. This is a concise way to provide a static filter value:

```
#[Filter('big_image_size_threshold', priority: 'last')]
protected const THRESHOLD_WIDTH = 3480;

#[Filter('excerpt_length')]
private int $excerptLength = 40;
```

### Custom Hook Attributes

[](#custom-hook-attributes)

Attributes are matched by the `Hook` interface using `ReflectionAttribute::IS_INSTANCEOF`, so you can define your own hook attributes by implementing `Hook` (or extending `Filter` — which is exactly how `Action` is built), and the trait will pick them up automatically.

The `Hook` interface defines a single method:

```
namespace X3P0\Hooks;

interface Hook
{
	public function register(callable $callback, int $arguments = 1): void;
}
```

Best Practices
--------------

[](#best-practices)

### Decide When to Boot

[](#decide-when-to-boot)

This package fires no WordPress hooks of its own — you decide when `boot()`runs. Booting on an appropriate hook (such as `init` or after your services are constructed) keeps registration predictable:

```
add_action('after_setup_theme', function (): void {
	(new Assets())->boot();
});
```

### Keep Hookable Classes Focused

[](#keep-hookable-classes-focused)

Group related hooks by responsibility (assets, admin, REST, etc.) rather than collecting unrelated hooks in a single class. This keeps each class small and its `boot()` cost minimal.

### Vendor Prefix When Necessary

[](#vendor-prefix-when-necessary)

If you're distributing your plugin/theme, consider using a tool like [PHP-Scoper](https://github.com/humbug/php-scoper) to avoid conflicts.

License
-------

[](#license)

X3P0 Hooks is licensed under the [GPL-2.0-or-later](LICENSE.md) license.

Credits
-------

[](#credits)

Created and maintained by [Justin Tadlock](https://github.com/justintadlock) under the [X3P0](https://github.com/x3p0-dev) umbrella.

Support
-------

[](#support)

- [GitHub Issues](https://github.com/x3p0-dev/x3p0-hooks/issues)
- [Packagist](https://packagist.org/packages/x3p0-dev/x3p0-hooks)

###  Health Score

20

—

LowBetter than 13% of packages

Maintenance65

Regular maintenance activity

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/ef868a4b45ef0263f49361744b8bb04e8f3cfcb8f3f79b274fc62823115ee596?d=identicon)[justintadlock](/maintainers/justintadlock)

---

Top Contributors

[![justintadlock](https://avatars.githubusercontent.com/u/1816309?v=4)](https://github.com/justintadlock "justintadlock (1 commits)")

### Embed Badge

![Health badge](/badges/x3p0-dev-x3p0-hooks/health.svg)

```
[![Health](https://phpackages.com/badges/x3p0-dev-x3p0-hooks/health.svg)](https://phpackages.com/packages/x3p0-dev-x3p0-hooks)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
