Yii框架实战

前言

新入手的项目需要使用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

0%