Building a Yii2 application at scale requires a well-structured architecture, clean coding practices, and efficient performance optimization. This tutorial covers best practices for Yii2 development and how to structure a large-scale Yii2 application.
Yii2 provides two default application templates:
For large-scale applications, the Advanced Template or a custom modular structure is recommended.
Yii2 is built on the MVC pattern. Keep concerns separate:
Avoid putting business logic in controllers or views.
Instead of creating objects directly, use Yii2's Dependency Injection (DI) Container for better flexibility.
Example: Define a component in config/web.php:
'components' => [
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'useFileTransport' => false,
],
],Then, use it anywhere in your application:
Yii::$app->mailer->compose()
->setTo('user@example.com')
->setSubject('Hello')
->send();This makes it easier to replace components without modifying the entire codebase.
For reusable logic, use Behaviors and Events instead of writing redundant code in models.
Example: Attach a behavior to automatically set timestamps:
use yii\behaviors\TimestampBehavior;
public function behaviors()
{
return [
TimestampBehavior::class,
];
}Yii2 provides multiple caching mechanisms (FileCache, MemCache, Redis).
Enable file caching in config/web.php:
'components' => [
'cache' => [
'class' => 'yii\caching\FileCache',
],
],Use caching in queries:
$data = Yii::$app->cache->getOrSet('my-data-key', function () {
return MyModel::find()->all();
}, 3600);
$users = User::find()->cache(3600)->all()This reduces database queries and improves performance.
For large projects, organize your Yii2 application into modules and service layers.
Instead of keeping all code in controllers and models, use Modules to group related functionality.
1. Create a module:
php yii gii/module --moduleID=user2. Register the module in config/web.php:
'modules' => [
'user' => [
'class' => 'app\modules\user\Module',
],
],3. Access it via: https://yourapp.com/user/default/index
Each module has its own controllers, models, and views, making the application more manageable.
Instead of putting complex logic inside models or controllers, create Service Classes for better separation.
Example: services/UserService.php
namespace app\services;
use app\models\User;
class UserService
{
public function createUser($data)
{
$user = new User();
$user->attributes = $data;
return $user->save();
}
}Use in controllers:
$userService = new \app\services\UserService();
$userService->createUser(Yii::$app->request->post());This improves code reusability and testing.
Instead of writing queries directly in models, use a Repository Layer.
Example: repositories/UserRepository.php
namespace app\repositories;
use app\models\User;
class UserRepository
{
public function findActiveUsers()
{
return User::find()->where(['status' => 1])->all();
}
}Use in services:
$users = (new UserRepository())->findActiveUsers();This improves database query organization and allows easy modifications.
For role-based access control, use Yii2’s RBAC system instead of checking roles manually.
Set up RBAC in console/migrations:
$auth = Yii::$app->authManager;
$admin = $auth->createRole('admin');
$auth->add($admin);Assign roles dynamically:
$auth->assign($admin, $userId);Always use Yii2’s ActiveRecord and Query Builder to prevent SQL injection:
User::find()->where(['email' => $email])->one();Sanitize user input using Html::encode():
echo Html::encode($user->name);Yii2 has CSRF protection enabled by default. Ensure your forms include the CSRF token:
<?= Html::beginForm(['/user/login'], 'post', ['csrf' => true]) ?>Example:
$query = User::find()->where(['status' => 1]);
$pagination = new Pagination(['totalCount' => $query->count(), 'pageSize' => 10]);
$users = $query->offset($pagination->offset)->limit($pagination->limit)->all();If your application has heavy processing (email sending, reports), use Yii2 Queue.
Install Yii2 Queue:
composer require yiisoft/yii2-queueRun queue tasks:
php yii queue/runAdd this to .htaccess for faster response times:
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css application/javascript
</IfModule>Enable it in config/web.php:
if (YII_ENV_DEV) {
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = 'yii\debug\Module';
}Access it at /debug.
Install Codeception for testing:
composer require --dev codeception/codeceptionRun tests:
vendor/bin/codecept runFor large-scale Yii2 applications, following best practices ensures:
Sign in to join the discussion and post comments.
Sign in