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 框架。

参考链接 ​