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 支持 |
版本信息
| Yii | PHP 最低版本 | 支持状态 |
|---|---|---|
| Yii 2 | PHP 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/migrationsphp
<?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 框架。