Extension points for PHP · Hooks 2.x Beta

Build extensible applications without tightly coupling modules.

Run actions, transform values, and collect contributions through clear, named extension points.

Framework-independent at its core, with first-class Laravel integration.

Three useful hook points

Pick the behavior that fits.

01

Actions

Run callbacks for side effects such as notifications, audit entries, or integrations. Their return values are ignored.

02

Filters

Pass one value through a sequence of callbacks. Each callback receives the current value and returns the next one.

03

Collectors

Ask several callbacks for a contribution and keep one result from each. Hooks does not merge or flatten them for you.

Common use cases

Keep integrations out of your core classes.

See how actions, filters, collectors, processors, and renderers fit into invoices, dashboards, checkout, navigation, and Laravel applications.

Explore practical examples

Actions · framework-independent core

Open a workflow without adding dependencies.

An exporter can expose a synchronous configuration point for modules that need to add columns or other options. Unlike a domain event, this hook stays inside the current workflow, so each callback can adjust this export request immediately.

Learn about actions →
use App\Reports\ExportOptions;
use Magdicom\Hooks;
$hooks = new Hooks();
$options = new ExportOptions('sales');
$hooks->addAction('report.export.configure', static function (ExportOptions $options): void {
$options->includeColumn('customer_region');
});
$hooks->doAction('report.export.configure', $options);

Filters · same hook model

Change a value without coupling every module.

Filters pass a value through callbacks in order. The PHP and Laravel versions differ only in how the shared Hooks object is reached.

Learn about filters →
use Magdicom\Hooks;
$hooks = new Hooks();
$hooks->addFilter('invoice.total', static fn (int $total): int => $total - 1000);
$total = $hooks->applyFilters('invoice.total', 10000);
// 9000 cents

Collectors · independent results

Let packages contribute their own data.

Collectors keep one result from each callback. A dashboard can ask for widgets without knowing which modules provide them.

Learn about collectors →
use Magdicom\Hooks;
$hooks = new Hooks();
$hooks->addCollector('dashboard.widgets', static fn (string $userId): array => [
'key' => 'revenue',
'user_id' => $userId,
]);
$userId = 'user-42';
$widgets = $hooks->collect('dashboard.widgets', $userId);

Install the beta

Start with the package you need.

Use the framework-independent core package in any PHP application or reusable package.

Terminal window
composer require magdicom/hooks:"^2.0@beta"
View core on Packagist

Both beta packages are named explicitly so Composer can resolve them. You do not need to change your global minimum-stability setting.

Choose the right tool

Different jobs call for different tools.

ChooseWhen you need
Laravel EventsChoose these for domain events, queues, broadcasting, and Laravel event workflows.
Laravel PipelineChoose this for a known middleware-style chain where each step passes a value onward.
HooksChoose Hooks for named synchronous extension points, ordered filters, and independent results.

Keep exploring

Build your first extension point.