Implementing Event-Driven Architecture in ThinkPHP 6
The event system in ThinkPHP 6 offers a decoupled approach to handling application logic, allowing components to react to specific actions without tight dependencies.
Registering Listeners
Using Closures
Closures provide a quick way to define lightweight listeners inline.
use think\facade\Event;
Event::listen('user_login', function() {
echo 'User login detected.';
});
Event::listen('user_login', function() {
echo 'Logging login details.';
});
Method-Based Listeners
Stadnard Handling
Define a class where the default handle method acts as the listener.
// app/common/events/AuthAction.php
namespace app\common\events;
class AuthAction
{
public function handle()
{
echo 'Authentication action executed.';
}
}
Register it in your bootstrap or controller:
Event::listen('auth_action', 'app\common\events\AuthAction');
Custom Methods
You can map specific methods within a class to different events.
// app/common/events/AuthAction.php
namespace app\common\events;
class AuthAction
{
public function logAttempt()
{
echo 'Attempt logged.';
}
public function notifyAdmin()
{
echo 'Admin notified.';
}
public static function writeAudit()
{
echo 'Audit trail written.';
}
}
Event::listen('auth_attempt', 'app\common\events\AuthAction::writeAudit');
Event::listen('auth_attempt', ['app\common\events\AuthAction', 'logAttempt']);
Event::listen('auth_success', ['app\common\events\AuthAction', 'notifyAdmin']);
Batch Registration
To register multiple listeners for various events at once, use listenEvents.
Event::listenEvents([
'auth_attempt' => [
'app\common\events\AuthAction::writeAudit',
['app\common\events\AuthAction', 'logAttempt']
],
'auth_success' => [
['app\common\events\AuthAction', 'notifyAdmin']
]
]);
Subscribers
Manual Subscription
A subscriber class can define its own binding logic via a subscribe method.
// app/common/events/AuthAction.php
namespace app\common\events;
use think\Event;
class AuthAction
{
public function subscribe(Event $event)
{
$event->listen('auth_attempt', ['app\common\events\AuthAction', 'logAttempt']);
$event->listen('auth_success', ['app\common\events\AuthAction', 'notifyAdmin']);
}
}
Event::subscribe('app\common\events\AuthAction');
Automatic Discovery
If methods follow the on + EventName convention, they are automatically discovered.
// app/common/events/AuthAction.php
namespace app\common\events;
class AuthAction
{
public function onAuthAttempt()
{
echo 'Automatic detection: AuthAttempt.';
}
public function onAuthSuccess()
{
echo 'Automatic detection: AuthSuccess.';
}
}
Triggering the event uses the capitalized name:
Event::trigger('AuthAttempt');
Event::trigger('AuthSuccess');
Dispatching Events
Use the trigger method or the helper function to fire events.
Event::trigger('auth_success');
\event('auth_success');
Advanced Configuration
Prepending Listeners
Set the third argument of listen to true to add a listener to the beginning of the queue.
Event::listen('auth_attempt', 'app\common\events\AuthAction', true);
Triggering Only the First Listener
Pass true as the third argument to trigger to stop after the first listener executes.
Event::trigger('AuthAttempt', null, true);
Removing Listeners
Clear all listeners for a specific event using remove.
Event::remove('auth_attempt');
Event Aliasing
Create aliases to trigger the same event logic using different names.
Event::bind(['login_check' => 'app\common\events\AuthAction']);
Event::listen('login_check', ['app\common\events\AuthAction', 'logAttempt']);
Event::trigger('login_check');
Event::trigger('app\common\events\AuthAction');
Checking Listener Existence
Verify if an event has active listeners with hasListener.
if (Event::hasListener('auth_success')) {
// Proceed with logic
}