Yii2 provides a powerful event-driven programming model and behavior system, allowing developers to extend functionality without modifying core code. Events enable objects to communicate in a loosely coupled manner, while behaviors allow attaching reusable functionality to components dynamically.
Yii2’s event system allows objects to trigger and respond to specific actions.
Yii2 uses on() to attach event handlers and trigger() to fire events.
class User extends \yii\base\Component
{
const EVENT_NEW_USER_REGISTERED = 'newUserRegistered';
public function register()
{
// Simulate user registration process
echo "User registered successfully.\n";
// Trigger the event
$this->trigger(self::EVENT_NEW_USER_REGISTERED);
}
}
// Create an instance
$user = new User();
// Attach an event handler
$user->on(User::EVENT_NEW_USER_REGISTERED, function () {
echo "Sending welcome email...\n";
});
// Register user (this will trigger the event)
$user->register();Sometimes, you may need to pass additional data when triggering an event.
class Order extends \yii\base\Component
{
const EVENT_ORDER_PLACED = 'orderPlaced';
public function placeOrder($orderId)
{
echo "Order #{$orderId} placed successfully.\n";
// Trigger event with event data
$this->trigger(self::EVENT_ORDER_PLACED, new \yii\base\Event(['data' => ['orderId' => $orderId]]));
}
}
// Attach an event handler
$order = new Order();
$order->on(Order::EVENT_ORDER_PLACED, function ($event) {
echo "Generating invoice for Order ID: " . $event->data['orderId'] . "\n";
});
// Place order
$order->placeOrder(101);You can remove event handlers using off() and check if an event is attached with hasEventHandlers().
$order->off(Order::EVENT_ORDER_PLACED);
if (!$order->hasEventHandlers(Order::EVENT_ORDER_PLACED)) {
echo "No event handlers attached to ORDER_PLACED.\n";
}Behaviors allow you to extend the functionality of Yii components dynamically.
Behaviors can be attached at runtime or declared within a model.
class TimestampBehavior extends \yii\base\Behavior
{
public function events()
{
return [
ActiveRecord::EVENT_BEFORE_INSERT => 'beforeInsert',
];
}
public function beforeInsert($event)
{
$this->owner->created_at = time();
}
}
// Apply behavior to a model
class Post extends \yii\db\ActiveRecord
{
public function behaviors()
{
return [
TimestampBehavior::class,
];
}
}You can attach behaviors at runtime.
$post = new Post();
$post->attachBehavior('timestamp', new TimestampBehavior());Yii2 provides built-in behaviors such as:
Automatically sets created and updated timestamps.
use yii\behaviors\TimestampBehavior;
class User extends \yii\db\ActiveRecord
{
public function behaviors()
{
return [
[
'class' => TimestampBehavior::class,
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'],
ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'],
],
],
];
}
}Tracks which user created or updated a record.
use yii\behaviors\BlameableBehavior;
class Post extends \yii\db\ActiveRecord
{
public function behaviors()
{
return [
BlameableBehavior::class,
];
}
}Automatically generates URL-friendly slugs.
use yii\behaviors\SluggableBehavior;
class Article extends \yii\db\ActiveRecord
{
public function behaviors()
{
return [
[
'class' => SluggableBehavior::class,
'attribute' => 'title',
'slugAttribute' => 'slug',
],
];
}
}Imagine a system where:
created_at and updated_at.class User extends \yii\db\ActiveRecord
{
const EVENT_USER_REGISTERED = 'userRegistered';
public function behaviors()
{
return [
TimestampBehavior::class,
];
}
public function register()
{
if ($this->save()) {
$this->trigger(self::EVENT_USER_REGISTERED);
}
}
}Yii::$app->on(User::EVENT_USER_REGISTERED, function ($event) {
echo "Sending welcome email to User ID: " . $event->sender->id;
});You can integrate events in Yii2 console commands.
namespace app\commands;
use yii\console\Controller;
use app\models\User;
class UserController extends Controller
{
public function actionRegister($email)
{
$user = new User(['email' => $email]);
$user->on(User::EVENT_USER_REGISTERED, function () use ($user) {
echo "Console: Sending welcome email to {$user->email}\n";
});
if ($user->register()) {
echo "User Registered Successfully.\n";
}
}
}Run in terminal:
php yii user/register example@mail.comInside Module.php:
namespace app\modules\dashboard;
use Yii;
use yii\base\BootstrapInterface;
use app\models\User;
class Module extends \yii\base\Module implements BootstrapInterface
{
public function bootstrap($app)
{
User::on(User::EVENT_USER_REGISTERED, function ($event) {
echo "Module: User Registered Event Triggered.";
});
}
}Modify config/console.php:
return [
'bootstrap' => ['dashboard'],
'modules' => [
'dashboard' => [
'class' => 'app\modules\dashboard\Module',
],
],
];Modify Module.php:
if (Yii::$app->request->isConsoleRequest) {
\Yii::configure($this, ['controllerNamespace' => 'app\modules\dashboard\commands']);
}Yii2’s Events & Behaviors provide a powerful way to extend application functionality without modifying core logic. By leveraging events, you can create loosely coupled systems, and with behaviors, you can dynamically add reusable features to components.
Sign in to join the discussion and post comments.
Sign in