Back to blog

Bắt Đầu với Yii2: Cài Đặt, Cấu Trúc & Cấu Hình

yii2phpbackendframeworkgetting-started
Bắt Đầu với Yii2: Cài Đặt, Cấu Trúc & Cấu Hình

Chào mừng đến với Phase 1 của series Yii2 Framework! Đây là nơi mọi thứ bắt đầu — môi trường development, project đầu tiên, và cái nhìn đầu tiên về cách Yii2 hoạt động.

Đến cuối bài này bạn sẽ có một ứng dụng Yii2 chạy được trên máy local, hiểu từng folder trong cây thư mục, và biết cách cấu hình framework cho các môi trường khác nhau.

Bạn Sẽ Học Được Gì

Kết Quả Học Tập:
✅ Cài đặt PHP 8.x, Composer và Yii2 trên máy
✅ Hiểu sự khác biệt giữa Basic và Advanced template
✅ Navigate cấu trúc thư mục Yii2 một cách tự tin
✅ Đọc và viết Yii2 configuration file
✅ Dùng service locator để access các built-in application component
✅ Hiểu request lifecycle của Yii2 từ browser đến response


Yêu Cầu Trước Khi Bắt Đầu

Trước khi bắt đầu, đảm bảo bạn có:

  • PHP 8.1+ đã cài (php -v)
  • Composer đã cài (composer -V)
  • Terminal / command line quen dùng
  • Kiến thức PHP cơ bản — function, class, namespace, interface

Nếu bạn chưa biết Composer, đây là dependency manager của PHP — tương đương npm của Node.js hay pip của Python. Cài từ getcomposer.org.


Bước 1: Cài Đặt PHP 8.x

Yii2 yêu cầu PHP 8.0 trở lên. Version khuyên dùng là PHP 8.2+.

macOS

# Dùng Homebrew
brew install php
 
# Kiểm tra
php -v
# PHP 8.2.x (cli) ...

Ubuntu / Debian

sudo apt update
sudo apt install php8.2 php8.2-cli php8.2-mbstring php8.2-xml \
     php8.2-curl php8.2-intl php8.2-pdo php8.2-mysql php8.2-zip
 
php -v

Windows

Tải PHP mới nhất cho Windows tại windows.php.net. Giải nén vào C:\php và thêm vào PATH.

Extension PHP Cần Có

Yii2 cần các extension này. Hầu hết đi kèm với cài đặt PHP chuẩn:

ExtensionMục đích
mbstringHỗ trợ multi-byte string
intlInternationalization
xmlXử lý XML
curlHTTP client
pdo + pdo_mysql / pdo_pgsqlTruy cập database
fileinfoXử lý file upload
zipAsset publishing

Kiểm tra những gì bạn đang có:

php -m | grep -E "mbstring|intl|xml|curl|pdo|fileinfo|zip"

Bước 2: Cài Đặt Composer

# macOS / Linux
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
 
# Kiểm tra
composer -V
# Composer version 2.x.x

Bước 3: Tạo Project Yii2 Đầu Tiên

Yii2 cung cấp hai official project template. Dưới đây là mỗi cái dùng để làm gì:

TemplateTrường hợp dùng
BasicSingle-application site, API, học Yii2
AdvancedMulti-app project (frontend + backend riêng biệt)

Bắt đầu với Basic. Bạn luôn có thể chuyển sang Advanced sau. Advanced thêm vào một mớ complexity không cần thiết cho đến khi bạn có team làm việc trên frontend/backend riêng biệt.

Tạo Project Basic

composer create-project --prefer-dist yiisoft/yii2-app-basic myapp
cd myapp

Composer sẽ tải Yii2 và tất cả dependencies. Lần đầu chạy mất khoảng một đến hai phút.

Chạy Development Server

php yii serve
# Server started on http://localhost:8080/

Mở http://localhost:8080 trên browser. Bạn sẽ thấy trang chào mừng Yii2 — "Congratulations!" với các link About, Contact và Login ở header.


Bước 4: Hiểu Cấu Trúc Project

Đây là một trong những thứ quan trọng nhất cần nắm sớm. Mọi thứ trong Yii2 đều có vị trí rõ ràng.

myapp/
├── assets/             # Định nghĩa asset bundle (đăng ký CSS/JS)
├── commands/           # Class console command
├── config/             # File cấu hình ứng dụng
│   ├── web.php         # Cấu hình web application (chính)
│   ├── console.php     # Cấu hình console application
│   ├── params.php      # Parameter dùng chung
│   └── db.php          # Cấu hình kết nối database
├── controllers/        # Class controller web
│   ├── SiteController.php
│   └── ...
├── models/             # Class model (Active Record + form model)
├── runtime/            # File runtime được tạo (log, cache, debug data)
├── tests/              # Test suite Codeception
├── vendor/             # Dependencies Composer (đừng đụng vào)
├── views/              # Template view (file .php)
│   ├── layouts/        # Template layout (site/main.php)
│   └── site/           # View cho SiteController
├── web/                # Document root — THƯ MỤC CÔNG KHAI DUY NHẤT
│   ├── index.php       # Entry script (mọi request đều qua đây)
│   ├── css/            # CSS asset đã publish
│   └── js/             # JS asset đã publish
├── .gitignore
├── composer.json
├── composer.lock
└── yii                 # Entry script console

Quy tắc quan trọng: Document root của web server phải trỏ vào thư mục web/, KHÔNG phải project root. Các thư mục config/, models/ và vendor/ không bao giờ được truy cập công khai.

Entry Script: web/index.php

Mọi HTTP request đều được route qua một file duy nhất:

<?php
 
// Bật báo lỗi trong development
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
 
require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';
 
$config = require __DIR__ . '/../config/web.php';
 
(new yii\web\Application($config))->run();

Đoạn này bootstrap ứng dụng Yii2 với cấu hình từ config/web.php, rồi gọi run() để xử lý request đến và gửi response. Chỉ bốn dòng logic thực sự.


Bước 5: Hiểu Hệ Thống Configuration

Hệ thống cấu hình của Yii2 là PHP array thuần. Không có YAML, không XML, không annotation — chỉ là PHP trả về một associative array mô tả ứng dụng của bạn được lắp ráp như thế nào.

Config Chính: config/web.php

<?php
 
$params = require __DIR__ . '/params.php';
$db = require __DIR__ . '/db.php';
 
$config = [
    'id' => 'basic',                         // App ID
    'basePath' => dirname(__DIR__),           // Root path của app
    'bootstrap' => ['log'],                   // Component bootstrap khi khởi động
    'aliases' => [
        '@bower' => '@vendor/bower-asset',
        '@npm'   => '@vendor/npm-asset',
    ],
    'components' => [                         // Đăng ký built-in component
        'request' => [
            'cookieValidationKey' => 'khóa-bí-mật-của-bạn',
        ],
        'cache' => [
            'class' => 'yii\caching\FileCache',
        ],
        'user' => [
            'identityClass' => 'app\models\User',
            'enableAutoLogin' => true,
        ],
        'errorHandler' => [
            'errorAction' => 'site/error',
        ],
        'log' => [
            'traceLevel' => YII_DEBUG ? 3 : 0,
            'targets' => [
                [
                    'class' => 'yii\log\FileTarget',
                    'levels' => ['error', 'warning'],
                ],
            ],
        ],
        'db' => $db,
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [],
        ],
    ],
    'params' => $params,
];
 
if (YII_ENV_DEV) {
    // Debug và Gii chỉ trong development
    $config['bootstrap'][] = 'debug';
    $config['modules']['debug'] = [
        'class' => 'yii\debug\Module',
        'allowedIPs' => ['127.0.0.1', '::1'],
    ];
    $config['bootstrap'][] = 'gii';
    $config['modules']['gii'] = [
        'class' => 'yii\gii\Module',
        'allowedIPs' => ['127.0.0.1', '::1'],
    ];
}
 
return $config;

Cấu Hình Database: config/db.php

<?php
 
return [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=myapp',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8mb4',
];

Parameter Dùng Chung: config/params.php

<?php
 
return [
    'adminEmail' => '[email protected]',
    'senderEmail' => '[email protected]',
    'senderName' => 'My App',
];

Truy cập parameter ở bất kỳ đâu trong app:

$email = Yii::$app->params['adminEmail'];

Bước 6: Service Locator

Yii2 dùng pattern service locator — Yii::$app là một global object chứa tất cả component đã đăng ký. Bạn truy cập chúng qua tên:

Yii::$app->db       // Kết nối database
Yii::$app->cache    // Component cache
Yii::$app->user     // User hiện tại / component auth
Yii::$app->request  // Object HTTP request
Yii::$app->response // Object HTTP response
Yii::$app->session  // Session
Yii::$app->mailer   // Gửi email
Yii::$app->urlManager // Tạo và parse URL

Đây là các singleton lazy-load — component chỉ được khởi tạo lần đầu tiên bạn truy cập nó.

// Ghi log
Yii::info('User đã đăng nhập', 'app.auth');
 
// Lấy query string param
$page = Yii::$app->request->get('page', 1);
 
// Redirect
return Yii::$app->response->redirect('/login');
 
// Kiểm tra user đã đăng nhập chưa
if (Yii::$app->user->isGuest) {
    Yii::$app->user->loginRequired();
}

Bước 7: Alias và Path Resolution

Yii2 dùng alias để tránh hardcode path khắp nơi trong code.

AliasTrỏ đến
@appBase path của ứng dụng (project root)
@webrootThư mục web/
@webBase URL cho request hiện tại
@vendorThư mục vendor/
@yiiThư mục Yii2 framework
@runtimeThư mục runtime/

Dùng chúng ở mọi nơi:

// Đọc file relative theo project root
$path = Yii::getAlias('@app/data/config.json');
 
// Tạo URL đến file public
$url = Yii::getAlias('@web/images/logo.png');
 
// Ghi vào runtime
$logPath = Yii::getAlias('@runtime/logs/app.log');

Định nghĩa alias tùy chỉnh trong config:

'aliases' => [
    '@uploads' => '@webroot/uploads',
    '@data'    => '@app/data',
],

Bước 8: Request Lifecycle

Hiểu điều gì xảy ra khi browser gọi vào app là điều cần thiết để debug.

Các bước chính:

  1. URL parsing — UrlManager chuyển URL đến thành route (controller/action)
  2. Tạo controller — Yii2 khởi tạo class controller
  3. Chạy filter — Các filter beforeAction() chạy (access control, auth, v.v.)
  4. Thực thi action — Method action chạy và trả về kết quả
  5. Render view — Controller render template view thành HTML
  6. Gửi response — Yii2 gửi header + body đến browser

Bước 9: Cấu Hình Theo Môi Trường

Trong production bạn muốn cài đặt khác với development (tắt debug, database khác, v.v.). Cách tiêu chuẩn của Yii2 dùng constant YII_ENV và pattern array_merge của PHP.

Các Constant Môi Trường

// Trong web/index.php — đặt TRƯỚC khi load Yii
defined('YII_DEBUG') or define('YII_DEBUG', true);   // false trong production
defined('YII_ENV') or define('YII_ENV', 'dev');       // 'prod' trong production

Merge Config Theo Môi Trường

Cách gọn gàng là có một config cơ sở và overlay theo môi trường:

config/
├── web.php          # Config chung (base)
├── web-local.php    # Override local (gitignored)
├── db.php           # DB cho dev
├── db-prod.php      # DB cho production (không bao giờ commit)
└── params.php       # Param dùng chung

Rồi trong web/index.php:

$config = require __DIR__ . '/../config/web.php';
 
// Merge override local nếu tồn tại (không commit lên git)
$localConfig = __DIR__ . '/../config/web-local.php';
if (is_file($localConfig)) {
    $config = yii\helpers\ArrayHelper::merge($config, require $localConfig);
}
 
(new yii\web\Application($config))->run();

web-local.php là config riêng của máy bạn, thêm vào .gitignore:

<?php
// config/web-local.php — KHÔNG commit lên git
return [
    'components' => [
        'db' => [
            'dsn'      => 'pgsql:host=localhost;dbname=myapp_dev',
            'username' => 'myuser',
            'password' => 'mypassword',
        ],
        'mailer' => [
            'useFileTransport' => true,  // Đừng gửi email thật trong dev
        ],
    ],
];

Quan trọng: Thêm config/web-local.php và config/db-prod.php vào .gitignore ngay lập tức. Password database không bao giờ được commit lên version control.

Dùng File .env

Với team thích file .env, dùng package vlucas/phpdotenv:

composer require vlucas/phpdotenv
// web/index.php — trước khi load Yii config
$dotenv = Dotenv\Dotenv::createImmutable(dirname(__DIR__));
$dotenv->safeLoad();
// config/db.php
return [
    'class'    => 'yii\db\Connection',
    'dsn'      => $_ENV['DB_DSN'] ?? 'mysql:host=localhost;dbname=myapp',
    'username' => $_ENV['DB_USER'] ?? 'root',
    'password' => $_ENV['DB_PASS'] ?? '',
];

Bước 10: Controller và View Đầu Tiên

Hãy tạo cái gì đó thực tế. Thêm HelloController với một action tùy chỉnh:

Tạo Controller

<?php
// controllers/HelloController.php
 
namespace app\controllers;
 
use yii\web\Controller;
 
class HelloController extends Controller
{
    public function actionIndex(): string
    {
        return $this->render('index', [
            'greeting' => 'Xin chào từ Yii2!',
        ]);
    }
 
    public function actionGreet(string $name = 'World'): string
    {
        return $this->render('greet', [
            'name' => $name,
        ]);
    }
}

Tạo View

<?php
// views/hello/index.php
/** @var yii\web\View $this */
/** @var string $greeting */
?>
<h1><?= htmlspecialchars($greeting, ENT_QUOTES, 'UTF-8') ?></h1>
<p>Chào mừng đến với controller Yii2 đầu tiên của bạn.</p>
<p><?= \yii\helpers\Html::a('Thử chào đón', ['hello/greet', 'name' => 'Yii2']) ?></p>
<?php
// views/hello/greet.php
/** @var yii\web\View $this */
/** @var string $name */
 
$this->title = "Xin chào, $name!";
?>
<h1>Xin chào, <?= htmlspecialchars($name, ENT_QUOTES, 'UTF-8') ?>!</h1>
<p><?= \yii\helpers\Html::a('← Quay lại', ['hello/index']) ?></p>

Thử Nghiệm

Truy cập http://localhost:8080/hello và http://localhost:8080/hello/greet?name=PHP.

Chú ý pattern URL: /controller/action. Đây là default routing của Yii2 — HelloController::actionGreet() map tới /hello/greet. Không cần đăng ký route thủ công.


Bước 11: Bật Pretty URL

Mặc định, Yii2 dùng query-string URL như index.php?r=hello/greet. Pretty URL trông như /hello/greet. Bật lên bằng hai bước.

1. Cập Nhật config/web.php

'urlManager' => [
    'enablePrettyUrl' => true,
    'showScriptName'  => false,  // Ẩn index.php khỏi URL
    'rules' => [],
],

2. Cấu Hình Web Server

Nginx:

server {
    listen 80;
    server_name myapp.local;
    root /path/to/myapp/web;
    index index.php;
 
    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }
 
    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Apache (.htaccess trong web/):

Options +FollowSymLinks
IndexIgnore */*
 
RewriteEngine on
 
# Chặn httpd không serve dotfile (.htaccess, .htpasswd, v.v.)
RewriteRule /\. - [f]
 
# Nếu là file hoặc thư mục thật, dùng request trực tiếp
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
 
# Ngược lại chuyển request đến index.php
RewriteRule . index.php

PHP built-in server (chỉ cho development):

php yii serve đã xử lý sẵn — pretty URL hoạt động tự động.


Thiết Lập Database

Hãy kết nối MySQL/PostgreSQL để bạn sẵn sàng cho Active Record ở Phase 3.

Tạo Database

# MySQL
mysql -u root -p
CREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
EXIT;
 
# PostgreSQL
psql -U postgres
CREATE DATABASE myapp;
\q

Cập Nhật config/db.php

<?php
// MySQL
return [
    'class'   => 'yii\db\Connection',
    'dsn'     => 'mysql:host=127.0.0.1;dbname=myapp;charset=utf8mb4',
    'username' => 'root',
    'password' => 'mật_khẩu_của_bạn',
    'charset' => 'utf8mb4',
    'tablePrefix' => '',
];
<?php
// PostgreSQL
return [
    'class'   => 'yii\db\Connection',
    'dsn'     => 'pgsql:host=127.0.0.1;dbname=myapp',
    'username' => 'postgres',
    'password' => 'mật_khẩu_của_bạn',
];

Test Kết Nối

php yii migrate
# Nếu DB cấu hình đúng, bạn sẽ thấy:
# No new migrations found. Your system is up-to-date.

Khám Phá Debug Toolbar

Trong development mode (YII_ENV=dev), Yii2 load Debug Toolbar tự động. Bạn sẽ thấy thanh nhỏ ở cuối mỗi trang.

Click vào để xem:

  • Request / Response — header, parameter, cookie
  • Database — mọi câu SQL query được thực thi, kèm thời gian
  • Log — tất cả message được log trong request
  • Config — cây cấu hình ứng dụng đầy đủ
  • Memory / Time — metric hiệu suất mỗi request

Đây là một trong những tính năng developer experience tốt nhất của Yii2. Dùng nó liên tục trong khi development.


Khám Phá Gii

Gii là code generator web-based của Yii2. Truy cập http://localhost:8080/gii để mở.

Bạn sẽ thấy các generator:

  • Model Generator — tạo class Active Record từ bảng DB
  • CRUD Generator — tạo scaffolding create/read/update/delete đầy đủ
  • Controller Generator — tạo stub controller
  • Form Generator — tạo class form model
  • Module Generator — tạo module có thể tái sử dụng
  • Extension Generator — tạo extension có thể cài đặt

Bạn chưa dùng Gii chi tiết cho đến Post #9, nhưng hãy dành chút thời gian mở nó và khám phá giao diện. Hiểu những gì Gii tạo ra cho bạn là chìa khóa để hiểu các convention của Yii2.


Những Lỗi Phổ Biến Của Người Mới

Trỏ web server vào project root thay vì web/ Luôn đặt document root thành myapp/web/, không phải myapp/. Nếu trỏ vào project root, các file config và vendor code trở thành publicly accessible — đây là security risk nghiêm trọng.

Commit cookieValidationKey lên version control Key này bảo vệ session cookie khỏi bị giả mạo. Tạo một chuỗi ngẫu nhiên unique (openssl rand -base64 32) và giữ nó ra khỏi git. Dùng local config file hoặc environment variable.

Dùng YII_DEBUG=true trong production Debug mode phơi bày thông báo lỗi chi tiết bao gồm đường dẫn file, giá trị cấu hình và stack trace. Luôn đặt YII_DEBUG=false trong production.

Không hiểu thư mục runtime/ Yii2 ghi log, cached view và debug data vào runtime/. Thư mục này phải được web server user ghi được. Nếu không ghi được, app sẽ throw error. Không bao giờ commit nội dung của runtime/ lên git.

Quên set file permission Trên Linux/macOS, web server cần quyền ghi vào runtime/ và web/assets/ (cho published asset bundle):

chmod -R 777 runtime/ web/assets/
# Hoặc tốt hơn — đổi owner thành web server user
chown -R www-data:www-data runtime/ web/assets/

Bước Tiếp Theo

Bạn đã cài đặt Yii2, hiểu cấu trúc project, cấu hình ứng dụng và tạo controller với view đầu tiên. Đây là những gì tiếp theo trong series:

Post #3: Phase 2 — MVC trong Yii2 — Đi sâu vào Controller, View, Model và URL management. Bạn sẽ học cách build các request/response flow thực tế, dùng layout, xử lý redirect và flash message, thiết kế URL rule gọn gàng.

Post #4: Phase 3 — Active Record & Query Builder — Kết nối database thực, định nghĩa Active Record model, chạy migration và query dữ liệu với relation.


Quick Reference

// Truy cập ứng dụng
Yii::$app->db          // Kết nối database
Yii::$app->cache       // Cache
Yii::$app->request     // HTTP request
Yii::$app->response    // HTTP response
Yii::$app->user        // Auth / user hiện tại
Yii::$app->session     // Session
Yii::$app->params      // Mảng parameter ứng dụng
 
// Path alias
Yii::getAlias('@app')      // /path/to/myapp
Yii::getAlias('@webroot')  // /path/to/myapp/web
Yii::getAlias('@web')      // http://localhost:8080
 
// Logging
Yii::info('message', 'category');
Yii::warning('message', 'category');
Yii::error('message', 'category');
 
// Truy cập params
$adminEmail = Yii::$app->params['adminEmail'];
 
// Chạy lệnh console
php yii serve            // Khởi động dev server
php yii migrate          // Chạy database migration
php yii help             // Liệt kê tất cả console command

Tóm Tắt

Trong bài này bạn đã:

✅ Cài đặt PHP 8.x và Composer
✅ Tạo project Yii2 Basic với composer create-project
✅ Nắm rõ từng thư mục và mục đích của nó
✅ Đọc và hiểu hệ thống cấu hình (web.php, db.php, params.php)
✅ Hiểu cách service locator hoạt động (Yii::$app->component)
✅ Hiểu Yii2 alias để quản lý path
✅ Tracing toàn bộ request lifecycle từ browser đến response
✅ Tạo controller và view đầu tiên
✅ Bật pretty URL
✅ Kết nối database
✅ Khám phá Debug Toolbar và Gii

Foundation này hỗ trợ mọi thứ tiếp theo. Trong bài tiếp theo chúng ta sẽ xây dựng trên đó với full MVC layer — controller thực với filter, view có cấu trúc với layout, và URL rule gọn gàng.

Tiếp tục Post #3: MVC trong Yii2 →

Quay lại Lộ Trình Học Yii2

📬 Đăng ký nhận bản tin

Nhận những bài viết mới nhất qua email mỗi tuần. Không spam, hủy đăng ký bất cứ lúc nào.

Chúng tôi tôn trọng quyền riêng tư của bạn. Hủy đăng ký bất cứ lúc nào.

💬 Comments

Đăng nhập để bình luận

Chúng tôi sẽ không đăng bất cứ điều gì mà không có sự cho phép của bạn.