Skip to content

Yii

Yii(发音为 "Yee" 或 [ji:])是一个高性能、组件化的 PHP 框架,由 Qiang Xue 创建。Yii 以其出色的性能、强大的代码生成工具(Gii)和丰富的扩展生态著称,特别适合开发 Web 2.0 应用程序。Yii 2.x 是当前主要版本,提供了完整的 MVC 架构、ActiveRecord ORM、RESTful API 支持和 RBAC 权限管理系统。本节将全面介绍 Yii 框架的核心概念和使用方法。

前置知识

阅读本节前,建议先了解:

基础概念

Yii 的特点

特性说明
高性能内置性能优化, benchmarks 表现优秀
Gii 代码生成强大的 CRUD 代码自动生成工具
ActiveRecord强大的数据库 ORM
RBAC内置基于角色的访问控制
国际化内置完善的多语言支持
缓存支持多种缓存后端
扩展生态丰富的官方和社区扩展
RESTful完善的 RESTful API 支持

版本信息

YiiPHP 最低版本支持状态
Yii 2PHP 7.3维护中
Yii 3(草案)PHP 8.1开发中

Yii 3

Yii 3 正在开发中,将基于 Symfony 组件和 PSR 规范重构,目前尚未正式发布。

详细说明

项目创建

bash
# 使用 Composer 创建基础应用模板
composer create-project yiisoft/yii2-app-basic myapp

# 使用 Composer 创建高级应用模板(含用户认证等)
composer create-project yiisoft/yii2-app-advanced myapp

目录结构(基础模板)

yii-basic/
├── assets/            # 前端资源
├── commands/          # 控制台命令
├── config/            # 配置文件
│   ├── db.php
│   ├── web.php
│   └── console.php
├── controllers/       # 控制器
├── mail/              # 邮件模板
├── models/            # 模型
├── runtime/           # 运行时文件
├── tests/             # 测试文件
├── vendor/            # Composer 依赖
├── views/             # 视图
├── web/               # Web 根目录
│   └── index.php      # 入口文件
├── yii                # CLI 入口
└── composer.json

控制器

php
<?php
declare(strict_types=1);

namespace app\controllers;

use app\models\User;
use Yii;
use yii\rest\ActiveController;
use yii\web\Controller;
use yii\web\Response;

class UserController extends Controller
{
    public $modelClass = User::class;

    public function behaviors(): array
    {
        $behaviors = parent::behaviors();
        $behaviors['contentNegotiator'] = [
            'class' => \yii\filters\ContentNegotiator::class,
            'formats' => [
                'application/json' => Response::FORMAT_JSON,
            ],
        ];
        return $behaviors;
    }

    // 列表
    public function actionIndex(): array
    {
        $users = User::find()->where(['status' => 1])
            ->orderBy(['created_at' => SORT_DESC])
            ->all();

        return $users;
    }

    // 详情
    public function actionView(int $id): ?User
    {
        return User::findOne($id);
    }

    // 创建
    public function actionCreate(): User
    {
        $model = new User();
        $model->load(Yii::$app->request->post(), '');
        
        if ($model->save()) {
            Yii::$app->response->statusCode = 201;
        }

        return $model;
    }
}

ActiveRecord 模型

php
<?php
declare(strict_types=1);

namespace app\models;

use yii\db\ActiveRecord;
use yii\web\IdentityInterface;

class User extends ActiveRecord implements IdentityInterface
{
    public static function tableName(): string
    {
        return '{{%users}}';
    }

    public function rules(): array
    {
        return [
            [['username', 'email', 'password_hash'], 'required'],
            [['email'], 'email'],
            [['email'], 'unique'],
            [['status'], 'default', 'value' => 10],
            [['status'], 'integer'],
            [['username', 'email'], 'string', 'max' => 255],
        ];
    }

    // 关联关系
    public function getPosts(): \yii\db\ActiveQuery
    {
        return $this->hasMany(Post::class, ['user_id' => 'id']);
    }

    public function getProfile(): \yii\db\ActiveQuery
    {
        return $this->hasOne(Profile::class, ['user_id' => 'id']);
    }

    // IdentityInterface 实现
    public static function findIdentity(int $id): ?static
    {
        return static::findOne($id);
    }

    public static function findIdentityByAccessToken(string $token, ?string $type = null): ?static
    {
        return static::findOne(['access_token' => $token]);
    }

    public function getId(): int
    {
        return $this->id;
    }

    public function getAuthKey(): ?string
    {
        return $this->auth_key;
    }

    public function validateAuthKey(string $authKey): bool
    {
        return $this->getAuthKey() === $authKey;
    }
}

配置文件

php
<?php
// config/db.php
return [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=myapp',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8',
    'enableSchemaCache' => YII_ENV_PROD,
    'schemaCacheDuration' => 3600,
    'schemaCache' => 'cache',
];
php
<?php
// config/web.php
return [
    'id' => 'basic',
    'basePath' => dirname(__DIR__),
    'components' => [
        'db' => require __DIR__ . '/db.php',
        'cache' => [
            'class' => 'yii\caching\FileCache',
        ],
        'user' => [
            'identityClass' => 'app\models\User',
            'enableAutoLogin' => true,
        ],
        'authManager' => [
            'class' => 'yii\rbac\DbManager',
        ],
        'request' => [
            'enableCsrfValidation' => true,
        ],
    ],
];

Gii 代码生成器

bash
# Gii 通过 Web 界面使用
# 访问 http://localhost:8080/index.php?r=gii

# Gii 可以自动生成:
# - Model(从数据库表生成 ActiveRecord 模型)
# - Controller(CRUD 控制器)
# - Form(表单模型)
# - Module(模块)
# - Extension(扩展)

视图与布局

php
<?php
// views/layouts/main.php
use yii\helpers\Html;

$this->beginPage() ?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <?= Html::csrfMetaTags() ?>
    <title><?= Html::encode($this->title) ?></title>
    <?php $this->head() ?>
</head>
<body>
    <?php $this->beginBody() ?>
    <div class="container">
        <?= $content ?>
    </div>
    <?php $this->endBody() ?>
</body>
</html>
<?php $this->endPage() ?>
php
<?php
// views/site/index.php
use yii\helpers\Html;
use yii\widgets\LinkPager;

/** @var yii\web\View $this */
/** @var array $dataProvider */

$this->title = 'Users';
$this->params['breadcrumbs'][] = $this->title;
?>

<div class="user-index">
    <h1><?= Html::encode($this->title) ?></h1>

    <?php foreach ($dataProvider->getModels() as $user): ?>
        <div class="user-item">
            <h3><?= Html::encode($user->username) ?></h3>
            <p><?= Html::encode($user->email) ?></p>
        </div>
    <?php endforeach; ?>

    <?= LinkPager::widget(['pagination' => $dataProvider->getPagination()]) ?>
</div>

ActiveForm

php
<?php
// views/user/_form.php
use yii\helpers\Html;
use yii\widgets\ActiveForm;

/** @var yii\web\View $this */
/** @var app\models\User $model */
/** @var yii\widgets\ActiveForm $form */
?>

<div class="user-form">
    <?php $form = ActiveForm::begin(); ?>

    <?= $form->field($model, 'username')->textInput(['maxlength' => true]) ?>
    <?= $form->field($model, 'email')->textInput(['maxlength' => true]) ?>
    <?= $form->field($model, 'password')->passwordInput(['maxlength' => true]) ?>

    <div class="form-group">
        <?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
    </div>

    <?php ActiveForm::end(); ?>
</div>

实战示例

场景一:RESTful API

php
<?php
// config/web.php 中配置 URL 管理器
'urlManager' => [
    'enablePrettyUrl' => true,
    'enableStrictParsing' => true,
    'showScriptName' => false,
    'rules' => [
        ['class' => 'yii\rest\UrlRule', 'controller' => 'user'],
    ],
],
php
<?php
declare(strict_types=1);

namespace app\controllers;

use yii\rest\ActiveController;

class PostController extends ActiveRecordController
{
    public $modelClass = 'app\models\Post';

    public $serializer = [
        'class' => 'yii\rest\Serializer',
        'collectionEnvelope' => 'items',
    ];
}

场景二:RBAC 权限管理

bash
# 初始化 RBAC 迁移
php yii migrate/up --migrationPath=@yii/rbac/migrations
php
<?php
declare(strict_types=1);

// 创建角色和权限
$auth = Yii::$app->authManager;

// 添加权限
$createPost = $auth->createPermission('createPost');
$auth->add($createPost);

$updatePost = $auth->createPermission('updatePost');
$auth->add($updatePost);

// 添加角色
$author = $auth->createRole('author');
$auth->add($author);
$auth->addChild($author, $createPost);

$admin = $auth->createRole('admin');
$auth->add($admin);
$auth->addChild($admin, $updatePost);
$auth->addChild($admin, $author);

// 分配角色
$auth->assign($author, 1); // 用户 ID 1 成为 author

// 检查权限
if ($auth->checkAccess(1, 'createPost')) {
    // 用户 1 有 createPost 权限
}

注意事项

1. 安全配置

php
<?php
// 生产环境必须
defined('YII_DEBUG') or define('YII_DEBUG', false);
defined('YII_ENV') or define('YII_ENV', 'prod');

// 开发环境
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');

2. 数据库迁移

bash
# 创建迁移
php yii migrate/create create_user_table

# 运行迁移
php yii migrate

# 回滚
php yii migrate/down

最佳实践

1. 使用 ActiveRecord 的条件查询

php
<?php
$users = User::find()
    ->where(['status' => User::STATUS_ACTIVE])
    ->andWhere(['like', 'username', 'admin'])
    ->orderBy(['created_at' => SORT_DESC])
    ->limit(10)
    ->all();

下一节

继续学习:CakePHP / Slim / Laminas — 了解其他有特色的 PHP 框架。

参考链接