Yii框架实战

文章目录
  1. 1. 前言
  2. 2. 环境准备
  3. 3. 下载安装
  4. 4. 项目结构
  5. 5. helloworld
    1. 5.1. 创建动作
    2. 5.2. 创建视图
    3. 5.3. 试运行
  6. 6. 路由控制
    1. 6.1. URL美化
    2. 6.2. 路由规则
  7. 7. 模板渲染
    1. 7.1. 默认模板引擎
    2. 7.2. smarty
  8. 8. 增删改查
    1. 8.1. 数据库配置
    2. 8.2. 连接配置
    3. 8.3. 新建model
    4. 8.4. 新建Controller
    5. 8.5. 测试接口
  9. 9. 源码分享
  10. 10. 书签

前言

新入手的项目需要使用Yii框架开发,那就仿照之前写的《ThinkPHP实战》,整理一下必须掌握的三个部分:路由控制、模板渲染、增删改查。

环境准备

参照《ThinkPHP开发环境搭建》

下载安装

1、下载Yii2的基本应用程序模板

2、解压出basic目录。

3、移动basic目录到wampserver的www目录下。

4、修改 basic/config/web.php 文件,给 cookieValidationKey 配置项 添加一个密钥:

1
'cookieValidationKey' => 'voidking',

5、启动wampserver,浏览器访问:http://localhost/basic/web/index.php 。如果安装成功,就会看到“Congratulations! You have successfully created your Yii-powered application.”。

项目结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
basic/                  应用根目录
composer.json Composer 配置文件, 描述包信息
config/ 包含应用配置及其它配置
console.php 控制台应用配置信息
web.php Web 应用配置信息
commands/ 包含控制台命令类
controllers/ 包含控制器类
models/ 包含模型类
runtime/ 包含 Yii 在运行时生成的文件,例如日志和缓存文件
vendor/ 包含已经安装的 Composer 包,包括 Yii 框架自身
views/ 包含视图文件
web/ Web 应用根目录,包含 Web 入口文件
assets/ 包含 Yii 发布的资源文件(javascript 和 css)
index.php 应用入口文件
yii Yii 控制台命令执行脚本

一般来说,应用中的文件可被分为两类:在 basic/web 下的和在其它目录下的。 前者可以直接通过 HTTP 访问,后者不能也不应该被直接访问。

helloworld

创建动作

对于“Hello”任务,需要创建一个 say 动作, 从请求中接收 message 参数并显示给最终用户。如果请求没有提供 message 参数, 动作将显示默认参数 “Hello”。

动作是最终用户可以直接访问并执行的对象。 动作被组织在控制器中。 一个动作的执行结果就是最终用户收到的响应内容。

动作必须声明在控制器中。为了简单起见, 你可以在现存的 SiteController 控制器里声明 say 动作。这个控制器定义在 controllers/SiteController.php 类文件中。 以下是一个动作的声明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

namespace app\controllers;

use yii\web\Controller;

class SiteController extends Controller
{
// ...现存的代码...

public function actionSay($message = 'Hello')
{
return $this->render('say', ['message' => $message]);
}
}

在上述 SiteController 代码中,say 动作被定义为 actionSay 方法。 Yii 使用 action 前缀区分普通方法和动作。 action 前缀后面的名称被映射为动作的 ID。

动作 ID 总是被以小写处理,如果一个操作 ID 由多个单词组成, 单词之间将由破折号连接(如 create-comment)。动作 ID 映射为方法名时移除了破折号, 将每个单词首字母大写,并加上 action 前缀。 比如:动作 ID create-comment 对应方法名 actionCreateComment。

上述代码中的动作方法接受一个参数 message,它的默认值是 “Hello”。

在动作方法中,yii\web\Controller::render() 被用来渲染一个名为 say 的视图文件。 message 参数也被传入视图,这样就可以在里面使用。动作方法会返回渲染结果。 结果会被应用接收并显示给最终用户的浏览器(作为整页 HTML 的一部分)。

创建视图

视图是你用来生成响应内容的脚本。为了说 “Hello”, 你需要创建一个 say 视图,以便显示从动作方法中传来的 message 参数。

1
2
3
4
<?php
use yii\helpers\Html;
?>
<?= Html::encode($message) ?>

say 视图应该存为 views/site/say.php 文件。当一个动作中调用了 yii\web\Controller::render() 方法时, 它将会寻找名为 views/控制器 ID/视图名.php 的PHP文件。。

当然了,你大概会在 say 视图里放入更多内容。内容可以由 HTML 标签,纯文本, 甚至 PHP 语句组成。实际上 say 视图就是一个由 yii\web\Controller::render() 执行的 PHP 脚本。 视图脚本输出的内容将会作为响应结果返回给应用。应用将依次输出结果给最终用户。

试运行

创建完动作和视图后,你就可以通过下面的 URL 访问新页面了:
http://localhost/basic/web/index.php?r=site/say&message=helloworld

路由控制

URL美化

从上面的helloworld例子中,我们看出,访问的URL分成几个部分:

  • 表示主机信息的 http://localhost/basic/web/
  • 表示入口脚本的 index.php
  • 表示路由的 r=site/say
  • 表示普通参数的 message=helloworld

该URL,如果变形成 http://localhost/basic/web/index.php/site/say?message=helloworld ,是不是好看很多?

该URL,如果变形成 http://localhost/basic/web/site/say?message=helloworld ,是不是更好看?

该URL,如果变形成 http://localhost/basic/web/say?message=helloworld ,是不是更好看?

该URL,如果变形成 http://localhost/basic/web/say/helloworld ,是不是更好看?

Yii有专门的 yii\web\UrlManager 来进行处理,其中:

  • 隐藏入口脚本可以通过 yii\web\UrlManager::showScriptName = false 来实现
  • 路由的路径化可以通过 yii\web\UrlManager::enablePrettyUrl = true 来实现
  • 参数的路径化可以通过路由规则来实现
  • 加入假后缀(fake suffix) .html 可以通过 yii\web\UrlManager::suffix = '.html' 来实现

路由规则

路由规则是指 urlManager 用于解析请求或生成URL的规则。

1、打开basic/config/web.php,找到urlManager,取消注释。

1
2
3
4
5
6
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
],
],

这时,http://localhost/basic/web/index.php/site/say?message=helloworld 就可以使用了。

2、找到apache的配置文件httpd.conf,去掉去掉rewrite前的#。

1
LoadModule rewrite_module modules/mod_rewrite.so

3、在index.php所在目录,添加.htaccess文件(不添加该文件也可以)。

1
2
3
4
5
6
7
8
9
10
Options +FollowSymLinks  
IndexIgnore */*
RewriteEngine on

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# otherwise forward it to index.php
RewriteRule . index.php

这时,http://localhost/basic/web/site/say?message=helloworld 就可以使用了。

4、打开basic/config/web.php,修改rules。

1
2
3
4
5
6
7
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'say' => 'site/say'
],
],

这时,http://localhost/basic/web/say?message=helloworld 就可以使用了。

5、继续修改rules。

1
2
3
4
5
6
7
8
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'say' => 'site/say',
'say/<message:\w+>'=>'site/say'
],
],

这时, http://localhost/basic/web/say/helloworld 就可以使用了。

模板渲染

默认模板引擎

1、在controllers/SiteController.php中添加函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public function actionTemplate()
{
$data = '测试数据';
$dataArr = array(
array('name'=>'郝锦','age'=>'24'),
array('name'=>'小帅','age'=>'22'),
array('name'=>'小飞','age'=>'22')
);
$dataObj = new userInfo();
return $this->render('template',
['data' => $data,
'dataArr' => $dataArr,
'dataObj' => $dataObj
]);
}

2、同时,在文件最后添加一个userInfo类:

1
2
3
4
5
6
7
class userInfo{
public $name = '郝锦';
public $age = '24';
function show(){
echo '一个函数';
}
}

3、在views/site中添加template.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Template</title>
</head>
<body>
<h1>模板</h1>
<p><?php echo $data; ?></p>
<p><?php echo $dataObj->name; ?></p>
<p><?php echo $dataObj->age; ?></p>
<p>
<?php
foreach ($dataArr as $value) {
echo $value['name'];
echo $value['age'];
}
?>
</p>
</body>
</html>

4、测试访问url: http://localhost/basic/web/site/template

smarty

上面的渲染中,我们发现,template.php中的写法不友好。
因为默认情况下,Yii 使用 PHP 作为其默认的模板引擎语言。但是,我们可以配置 Yii 以扩展的方式支持其他的渲染引擎, 比如 Twig 或 Smarty等。
下面我们把模板引擎换成smarty。

1、下载安装Composer

2、在basic目录,执行命令composer require --prefer-dist yiisoft/yii2-smarty,安装smarty插件。

如果提示输入token,解决办法为:
进入 https://github.com/settings/tokens 点击 「Generate new token」 新建一个 Token,选择默认新建就行,然后就会得到一个 Token,然后输入这个值就 OK 了。

3、打开basic/config/web.php,找到components,添加使用smarty:

1
2
3
4
5
6
7
8
9
10
11
'components' => [
// other settings
'view' => [
'renderers' => [
'tpl' => [
'class' => 'yii\smarty\ViewRenderer',
//'cachePath' => '@runtime/Smarty/cache',
],
],
],
],

4、修改actionTemplate为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public function actionTemplate()
{
$data = '测试数据';
$dataArr = array(
array('name'=>'郝锦','age'=>'24'),
array('name'=>'小帅','age'=>'22'),
array('name'=>'小飞','age'=>'22')
);
$dataObj = new userInfo();
return $this->render('template.tpl',
['data' => $data,
'dataArr' => $dataArr,
'dataObj' => $dataObj
]);
}

5、在views/site中添加template.tpl:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Template</title>
</head>
<body>
<h1>模板</h1>
<p>{$data}</p>
<p>{$dataObj->name}</p>
<p>{$dataObj->age}</p>
<p>
{foreach from=$dataArr key=mykey item=$value}
{$value.name}&nbsp;{$value.age}
{/foreach}
</p>
</body>
</html>

6、测试访问url: http://localhost/basic/web/site/template

增删改查

数据库配置

利用navicat等工具连接到本地mysql数据库,创建数据库basic,在数据库中创建表bas_project(int id, varchar title, varchar content)。注意,编码格式选择utf8。

连接配置

打开basic/config/db.php,修改内容如下:

1
2
3
4
5
6
7
8
9
10
<?php

return [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=basic',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'tablePrefix' => 'bas_',
];

新建model

在basic/models下,新建Project.php,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

namespace app\models;
use yii\db\ActiveRecord;

/**
* Project model
*/
class Project extends ActiveRecord
{
public static function model($className=__CLASS__)
{
return parent::model($className);
}
}

新建Controller

在basic/controllers下,新建ProjectController.php,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?php

namespace app\controllers;

use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\filters\VerbFilter;
use app\models\LoginForm;
use app\models\ContactForm;
use app\models\Project;

class ProjectController extends Controller
{
public function actionAdd($title, $content){
$project = new Project();
$project->title = $title;
$project->content = $content;

$success = $project->save();
if($success){
$result = array(
'code' => '0',
'ext' => 'success'
);
echo json_encode($result,JSON_UNESCAPED_UNICODE);
}

}

public function actionEdit($id, $title, $content){
$project = Project::find()->where(['id'=>$id])->one();
$project->title = $title;
$project->content = $content;
$success = $project->save();

if($success){
$result = array(
'code'=> '0',
'ext'=> 'success'
);
echo json_encode($result,JSON_UNESCAPED_UNICODE);
}else {
$result = array(
'code'=> '1',
'ext'=> 'fail'
);
echo json_encode($result,JSON_UNESCAPED_UNICODE);
}
}

public function actionDelete($id){
$project = Project::find()->where(['id'=>$id])->one();
$success = $project->delete();
if($success){
$result = array(
'code'=> '0',
'ext'=> 'success'
);
echo json_encode($result);
}else {
$result = array(
'code'=> '1',
'ext'=> 'fail'
);
echo json_encode($result);
}
}

public function actionList(){
$projectList = Project::find()->asArray()->all();
$result = array(
'code'=> '0',
'ext'=> 'success',
'projectList' => $projectList
);
echo json_encode($result,JSON_UNESCAPED_UNICODE);

}

public function actionPage($pageSize,$pageNum){
$project = new Project();
$total = $project->find()->count();
$totalPage = $total%$pageSize ? (int)($total/$pageSize)+1 : (int)($total/$pageSize);

$projectList = $project->find()->offset(($pageNum-1)*$pageSize)->limit($pageSize)->asArray()->all();

if($projectList){
$resultArr = array(
'totalPage'=> $totalPage,
'pageNum'=> $pageNum,
'projectList'=> $projectList

);
$result = array(
'code'=> '0',
'ext'=> 'success',
'obj'=> $resultArr
);
echo json_encode($result,JSON_UNESCAPED_UNICODE);
}
}

public function actionFind($id){
$project = new Project();
$item = $project->find()->where(['id'=>$id])->asArray()->one();
$result = array(
'code'=> '0',
'ext'=> 'success',
'obj'=> $item
);
echo json_encode($result,JSON_UNESCAPED_UNICODE);
}
}

测试接口

1、添加:http://localhost/basic/web/project/add?title=voidking-title&content=voidking-content

2、修改:http://localhost/basic/web/project/edit?id=1&title=voidking-title&content=voidking-content

3、查找全部:http://localhost/basic/web/project/list

4、查找一页:http://localhost/basic/web/project/page?pageSize=10&pageNum=1

5、查找一条:http://localhost/basic/web/project/find?id=1

6、删除:http://localhost/basic/web/project/delete?id=1

路由控制、模板渲染、增删改查,至此全部跑通,可以进行简单的开发了。至于yii框架提供的其他更加强大的功能,在需要时查查文档就好。

源码分享

1、下载安装:git clone https://github.com/voidking/yii-basic.git basic

2、利用navicat等工具连接到本地mysql数据库,创建数据库basic,在数据库中创建表bas_project(int id, varchar title, varchar content)。注意,编码格式选择utf8。

书签

Yii Framework中文社区

下载安装Yii

Yii 2.0 权威指南

URL Management(网址管理)

Yii2.0数据库操作增删改查详解

ActiveRecord