yii2框架的安装我们在之前文章中已经提到下面我们开始了解YII2框架
强大的YII2框架网上指南:http://www.yii-china.com/doc/detail/1.html?postid=278或者
http://www.yiichina.com/doc/guide/2.0
Yii2的应用结构:
目录篇:



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?phpdefined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require(__DIR__ . '/../../vendor/autoload.php');
require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../../common/config/bootstrap.php');
require(__DIR__ . '/../config/bootstrap.php');
$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../../common/config/main.php'),
require(__DIR__ . '/../../common/config/main-local.php'),
require(__DIR__ . '/../config/main.php'),
require(__DIR__ . '/../config/main-local.php'));
$application = new yii\web\Application($config);$application->run();
|


其中:
- config 就是通用的配置,这些配置将作用于前后台和命令行。
- mail 就是应用的前后台和命令行的与邮件相关的布局文件等。
- models 就是前后台和命令行都可能用到的数据模型。 这也是 common 中最主要的部分。
当开发一个大型项目开发周期长,我们需要不断调整数据库结构。出于这个原因,我们还可以使用数据库迁移(DB migrations )功能来保持跟踪数据库的变化。我们将所有 DB migrations(数据库迁移)目录同样都放在公共(common)目录下面。

- 目录 dev
- 目录 prod
- 文件 index.php
其中, dev 和 prod 结构相同,分别又包含了4个目录和1个文件:
- frontend 目录,用于前台的应用,包含了存放配置文件的 config 目录和存放web入口脚本的web 目录
- backend 目录,用于后台应用,内容与 frontend 相同
- console 目录,用于命令行应用,仅包含了 config 目录,因为命令行应用不需要web入口脚本, 因此没有 web 目录。
- common 目录,用于各web应用和命令行应用通用的环境配置,仅包含了 config 目录, 因为不同应用不可能共用相同的入口脚本。 注意这个 common 的层级低于环境的层级,也就是说,他的通用,仅是某一环境下通用,并非所有环境下通用。
- yii 文件,是命令行应用的入口脚本文件。
对于分散于各处的 web 和 config 目录而言,它们也是有共性的。
- 凡是 web 目录,存放的都是web应用的入口脚本,一个 index.php 和一个测试版本的index-test.php
- 凡是 config 目录,存放的,都是本地配置信息 main-local.php 和 params-local.php



入口文件篇:
1、入口文件路径:
http://127.0.0.1/yii2/advanced/frontend/web/index.php
每个应用都有一个入口脚本 web/index.PHP,这是整个应用中唯一可以访问的 PHP 脚本。一个应用处理请求的过程如下:
可以看到中间有模型-视图-控制器 ,即常说的MVC。入口脚本并不会处理请求,而是把请求交给了应用主体,在处理请求时,会用到控制器,如果用到数据库中的东西,就会去访问模型,如果处理请求完成,要返回给用户信息,则会在视图中回馈要返回给用户的内容。1.用户向入口脚本 web/index.php 发起请求。
2.入口脚本加载应用配置并创建一个应用实例去处理请求。
3.应用通过请求组件解析请求的路由。
4.应用创建一个控制器实例去处理请求。
5.控制器创建一个操作实例并针对操作执行过滤器。
6.如果任何一个过滤器返回失败,则操作退出。
7.如果所有过滤器都通过,操作将被执行。
8.操作会加载一个数据模型,或许是来自数据库。
9.操作会渲染一个视图,把数据模型提供给它。
10.渲染结果返回给响应组件。
11.响应组件发送渲染结果给用户浏览器
2、为什么我们访问方法会出现url加密呢?
我们找到文件:vendor/yiisoft/yii2/web/UrlManager.php
return "$baseUrl/{ $route}{ $anchor}"; } else { $url = "$baseUrl?{ $this->routeParam}=" . urlencode($route); if (!empty($params) && ($query = http_build_query($params)) !== '') { $url .= '&' . $query; } 将urlencode去掉就可以了 3、入口文件内容入口文件流程如下:
MVC篇:
一、控制器详解:
1、修改默认控制器和方法
修改全局控制器:打开vendor/yiisoft/yii2/web/Application.php
eg:
public $defaultRoute = 'student/show'; 修改前台或者后台控制器: eg :打开 frontend/config/main.php 中2、建立控制器示例:StudentController.php'params' => $params, 'defaultRoute' => 'login/show',
//命名空间
namespace frontend\controllers;
use Yii;
use yii\web\Controller; vendor/yiisoft/yii2/web/Controller.php (该控制器继承的是\yii\base\Controller)
\web\Controller.php中干了些什么
1、默认开启了 授权防止csrf攻击
2、响应Ajax请求的视图渲染
3、将参数绑定到动作(就是看是不是属于框架自己定义的方法,如果没有定义就走run方法解析)
4、检测方法(beforeAction)beforeAction()
方法会触发一个 beforeAction
事件,在事件中你可以追加事件处理操作;
5、重定向路径 以及一些http Response(响应) 的设置
use yii\db\Query; //使用query查询
use yii\data\Pagination;//分页
use yii\data\ActiveDataProvider;//活动记录
use frontend\models\ZsDynasty;//自定义数据模型
class StudentController extends Controller
{
$request = YII::$app->request;//获取请求组件
$request->get('id');//获取get方法数据
$request->post('id');//获取post方法数据
$request->isGet;//判断是不是get请求
$request->isPost;//判断是不是post请求
$request->userIp;//获取用户IP地址
$res = YII::$app->response;//获取响应组件
$res->statusCode = '404';//设置状态码
$this->redirect('http://baodu.com');//页面跳转
$res->sendFile('./b.jpg');//文件下载
s
e
s
s
i
o
n
=
Y
I
I
:
:
session = YII::
session=YII::app->session;
$session->isActive;//判断session是否开启
$session->open();//开启session
//设置session值
$session->set(‘user’,‘zhangsan’);//第一个参数为键,第二个为值
$session[‘user’]=‘zhangsan’;
//获取session值
$session->get(‘user’);
$session[‘user’];
//删除session值
KaTeX parse error: Expected 'EOF', got '&' at position 25: …emove('user'); &̲nbsp; &nbs…session[‘user’]);
c
o
o
k
i
e
s
=
Y
i
i
:
:
cookies = Yii::
cookies=Yii::app->response->cookies;//获取cookie对象
$cookie_data = array(‘name’=>‘user’,‘value’=>‘zhangsan’)//新建cookie数据
KaTeX parse error: Expected 'EOF', got '&' at position 9: cookies-&̲gt;add(new Cook…cookie_data));
$cookies->remove(‘id’);//删除cookie
$cookies->getValue(‘user’);//获取cookie
//显示视图
return $this->render(‘add’); 默认.php
return KaTeX parse error: Expected 'EOF', got '&' at position 6: this-&̲gt;render('upda…data]);
}
}
二、模型层详解
简单模型建立:
<?php namespace frontend\models; class ListtModel extends \yii\db\ActiveRecord { public static function tableName() { return 'listt'; } public function one(){ return $this->find()->asArray()->one(); } }
控制器引用<?php namespace frontend\controllers; use Yii; use yii\web\controller; use frontend\models\ListtModel; class ListtController extends Controller{ public function actionAdd(){ $model=new ListtModel; $list=$model->one(); $data=$model->find()->asArray()->where("id=1")->all(); print_r($data); } } ?>
三、视图层详解首先在frontend下建立与控制器名一致的文件(小写)eg:student 在文件下建立文件





控制器中写入$layout
//$layout="main" 系统默认文件 //$layout=null 会找父类中默认定义的main public $layout="common"; public function actionIndex(){ return $this->render('index'); } 将以下内容插入 common中<?=$content;?> 它就是index文件中的内容
YII2框架数据的运用
1、数据库连接
简介
一个项目根据需要会要求连接多个数据库,那么在yii2中如何链接多数据库呢?其实很简单,在配置文件中稍加配置即可完成。
配置
打开数据库配置文件common\config\main-local.php,在原先的db配置项下面添加db2,配置第二个数据库的属性即可
-
'db' => [
-
'class' =>
'yii\db\Connection',
-
'dsn' =>
'mysql:host=localhost;dbname=hyii2',
//数据库hyii2
-
'username' =>
'root',
-
'password' =>
'pwhyii2',
-
'charset' =>
'utf8',
-
],
-
'db2' => [
-
'class' =>
'yii\db\Connection',
-
'dsn' =>
'mysql:host=localhost;dbname=hyii',
//数据库hyii
-
'username' =>
'root',
-
'password' =>
'pwhyii',
-
'charset' =>
'utf8',
-
],
如上配置就可以完成yii2连接多个数据库的功能,但还是需要注意几个点
如果使用的数据库前缀 在建立模型时 这样: eg:这个库叫 haiyong_test return {
{%test}}
应用
1.我们在hyii数据库中新建一个测试表test
2.通过gii生成模型,这里需要注意的就是数据库链接ID处要改成db2
3.查看生成的模型,比正常的model多了红色标记的地方
所以各位童鞋,如果使用多数据配置,在建db2的模型的时候,也要加上上图红色的代码。
好了,以上步骤就完成了,yii2的多数据库配置,配置完成之后可以和原因一样使用model或者数据库操作
2、数据操作:
方式一:使用createCommand()函数
增加
获取自增id
$id=Yii::$app->db->getLastInsertID();
-
Yii::$app->db->createCommand()->insert(
'user', [
-
'name' =>
'test',
-
'age' =>
30,
-
])->execute();
批量插入数据
-
Yii::$app->db->createCommand()->batchInsert(
'user', [
'name',
'age'], [
-
[
'test01',
30],
-
[
'test02',
20],
-
[
'test03',
25],
-
])->execute();
删除
Yii::$app->db->createCommand()->delete('user', 'age = 30')->execute();
修改
Yii::$app->db->createCommand()->update('user', ['age' => 40], 'name = test')->execute();
查询
-
//createCommand(执行原生的SQL语句)
-
$sql=
"SELECT u.account,i.* FROM sys_user as u left join user_info as i on u.id=i.user_id";
-
$rows=Yii::$app->db->createCommand($sql)->query();
-
-
查询返回多行:
-
$command = Yii::$app->db->createCommand(
'SELECT * FROM post');
-
$posts = $command->queryAll();
-
-
返回单行
-
$command = Yii::$app->db->createCommand(
'SELECT * FROM post WHERE id=1');
-
$post = $command->queryOne();
-
-
查询多行单值:
-
$command = Yii::$app->db->createCommand(
'SELECT title FROM post');
-
$titles = $command->queryColumn();
-
-
查询标量值/计算值:
-
$command = Yii::$app->db->createCommand(
'SELECT COUNT(*) FROM post');
-
$postCount = $command->queryScalar();
方式二:模型处理数据(优秀程序媛必备)!!
新增(因为save方法有点low)所以自己在模型层中定义:add和addAll方法
注意:!!!当setAttributes($attributes,fase);时不用设置rules规则,否则则需要设置字段规则;
//入库一维数组
public function add($data)
{
$this->setAttributes($data);
$this->isNewRecord = true;
$this->save();
return $this->id;
}
//入库二维数组
public function addAll($data){
$ids=array();
foreach($data as $attributes)
{
$this->isNewRecord = true;
$this->setAttributes($attributes);
$this->save()&& array_push($ids,$this->id) && $this->id=0;
}
return $ids;
}
public function rules()
{
return [
[['title','content'],'required'
]];
}
控制器:
$ids=$model->addAll($data);
var_dump($ids);
删除
使用model::delete()进行删除
-
$user = User::find()->where([
'name'=>
'test'])->one();
-
$user->delete();
直接删除:删除年龄为30的所有用户
$result = User::deleteAll(['age'=>'30']);
根据主键删除:删除主键值为1的用户
$result = User::deleteByPk(1);
/** * @param $files 字段 * @param $values 值 * @return int 影响行数 */ public function del($field,$values){ // $res = $this->find()->where(['in', "$files", $values])->deleteAll(); $res=$this->deleteAll(['in', "$field", "$values"]); return $res; }
修改
使用model::save()进行修改
-
$user = User::find()->where([
'name'=>
'test'])->one();
//获取name等于test的模型
-
$user->age =
40;
//修改age属性值
-
$user->save();
//保存
直接修改:修改用户test的年龄为40
$result = User::model()->updateAll(['age'=>40],['name'=>'test']);
/** * @param $data 修改数据 * @param $where 修改条件 * @return int 影响行数 */ public function upda($data,$where){ $result = $this->updateAll($data,$where); // return $this->id; return $result; }
基础查询
Customer::find()->one(); 此方法返回一条数据;
Customer::find()->all(); 此方法返回所有数据;
Customer::find()->count(); 此方法返回记录的数量;
Customer::find()->average(); 此方法返回指定列的平均值;
Customer::find()->min(); 此方法返回指定列的最小值 ;
Customer::find()->max(); 此方法返回指定列的最大值 ;
Customer::find()->scalar(); 此方法返回值的第一行第一列的查询结果;
Customer::find()->column(); 此方法返回查询结果中的第一列的值;
Customer::find()->exists(); 此方法返回一个值指示是否包含查询结果的数据行;
Customer::find()->batch(10); 每次取10条数据
Customer::find()->each(10); 每次取10条数据,迭代查询
//根据sql语句查询:查询name=test的客户
Customer::model()->findAllBySql(“select * from customer where name = test”);
//根据主键查询:查询主键值为1的数据
Customer::model()->findByPk(1);
//根据条件查询(该方法是根据条件查询一个集合,可以是多个条件,把条件放到数组里面)
Customer::model()->findAllByAttributes([‘username’=>‘admin’]);
//子查询
$subQuery = (new Query())->select('COUNT()’)->from(‘customer’);
// SELECT id
, (SELECT COUNT() FROM customer
) AS count
FROM customer
KaTeX parse error: Expected 'EOF', got '&' at position 6: query&̲nbsp;= (ne…subQuery])->from(‘customer’);
//关联查询:查询客户表(customer)关联订单表(orders),条件是status=1,客户id为1,从查询结果的第5条开始,查询10条数据
$data = (new Query())
->select(’*’)
->from(‘customer’)
->join(‘LEFT JOIN’,‘orders’,‘customer.id = orders.customer_id’)
->where([‘status’=>‘1’,‘customer.id’=>‘1’])
->offset(5)
->limit(10)
->all()
关联查询
-
/**
-
*客户表Model:CustomerModel
-
*订单表Model:OrdersModel
-
*国家表Model:CountrysModel
-
*首先要建立表与表之间的关系
-
*在CustomerModel中添加与订单的关系
-
*/
-
Class CustomerModel extends \yii\db\ActiveRecord
-
{
-
...
-
//客户和订单是一对多的关系所以用hasMany
-
//此处OrdersModel在CustomerModel顶部别忘了加对应的命名空间
-
//id对应的是OrdersModel的id字段,order_id对应CustomerModel的order_id字段
-
public
function getOrders()
-
{
-
return
$this->hasMany(OrdersModel::className(), [
'id'=>
'order_id']);
-
}
-
-
//客户和国家是一对一的关系所以用hasOne
-
public
function getCountry()
-
{
-
return
$this->hasOne(CountrysModel::className(), [
'id'=>
'Country_id']);
-
}
-
....
-
}
-
-
// 查询客户与他们的订单和国家
-
CustomerModel::find()->with(
'orders',
'country')->all();
-
-
// 查询客户与他们的订单和订单的发货地址(注:orders 与 address都是关联关系)
-
CustomerModel::find()->with(
'orders.address')->all();
-
-
// 查询客户与他们的国家和状态为1的订单
-
CustomerModel::find()->with([
-
'orders' =>
function ($query) {
-
$query->andWhere(
'status = 1');
-
},
-
'country',
-
])->all();