YII2常用知识点总结

时间:2021-02-01 03:28:46

YII2常用知识点总结

(一)总结性语句

(1)经常看看yii源码比如vendor\yiisoft\yii2\web这个目录(很重要)下的文件中的方法(这些文件中的公共方法,大致看了下基本上都可以通过\Yii::$app->functionName()这种方式引用)

(2)批量操作时一般会返回成功操作的行数;

(3)尽量能用框架自带的CRUD方法就用框架的,除非sql语句非常复杂就自己拼写sql语句;

(4)把查询条件作为参数,比较安全,可直接避免注入。要是直接用在SQL语句中,最好要经过防注入处理。

 

(二)数据的增删查改

1.查:

例一:

//you have to define db connection in config/main.php

$connection = \yii::$app->db;

$queryEmailSql = "select email  from user";

$allEmail = $connection->createCommand($queryEmailSql)->queryAll();

例二:

public  static function getSubscribeByWhere($where)

{

return (new \yii\db\Query())->select(['category_id''name''create_time'])

->from(self::TableName)

->where($where)

->indexBy('category_id')

->all();

}

$where  = ['status'=>1, 'type'=>0, 'creater'=>$param['uid'], 'pid'=>$param['pid'], 'source_type'=>0];

例三:

// 取回所有活跃客户(状态为 *active* 的客户)并以他们的 ID 排序:

$customers = Customer::find() ->where(['status' => Customer::STATUS_ACTIVE]) ->orderBy('id') ->all();

// 返回ID为1的客户:

$customer = Customer::find() ->where(['id' => 1])  ->one();

// 取回活跃客户的数量:

$count = Customer::find() ->where(['status' => Customer::STATUS_ACTIVE]) ->count();

// 以客户ID索引结果集:

$customers = Customer::find()->indexBy('id')->all();

// $customers 数组以 ID 为索引

// 用原生 SQL 语句检索客户:

$sql = 'SELECT * FROM customer';

$customers = Customer::findBySql($sql)->all();

// 返回 id 为 1 的客户

$customer = Customer::findOne(1);

// 返回 id 为 1 且状态为 *active* 的客户

$customer = Customer::findOne([ 'id' => 1,   'status' => Customer::STATUS_ACTIVE,]);

// 返回id为1、2、3的一组客户

$customers = Customer::findAll([1, 2, 3]);

// 返回所有状态为 "deleted" 的客户

$customer = Customer::findAll([ 'status' => Customer::STATUS_DELETED,]);

// 以数组而不是对象形式取回客户信息:

$customers = Customer::find()->asArray()->all();// $customers 的每个元素都是键值对数组

http://www.yiifans.com/yii2/guide/db-active-record.html

User::find()->all();    此方法返回所有数据;

User::findOne($id);  此方法返回 主键 id=1 的一条数据(举个例子);

User::find()->where(['name' => '小伙儿'])->one();  此方法返回 ['name' => '小伙儿'] 的一条数据;

User::find()->where(['name' => '小伙儿'])->all();  此方法返回 ['name' => '小伙儿'] 的所有数据;

User::find()->orderBy('id DESC')->all();  此方法是排序查询;

User::findBySql('SELECT * FROM user')->all();  此方法是用 sql  语句查询 user 表里面的所有数据;

User::findBySql('SELECT * FROM user')->one();  此方法是用 sql  语句查询 user 表里面的一条数据;

User::find()->andWhere(['sex' => '男', 'age' => '24'])->count('id');  统计符合条件的总条数;

User::find()->one();    此方法返回一条数据;

User::find()->all();    此方法返回所有数据;

User::find()->count();    此方法返回记录的数量;

User::find()->average();    此方法返回指定列的平均值;

User::find()->min();    此方法返回指定列的最小值 ;

User::find()->max();    此方法返回指定列的最大值 ;

User::find()->scalar();    此方法返回值的第一行第一列的查询结果;

User::find()->column();    此方法返回查询结果中的第一列的值;

User::find()->exists();    此方法返回一个值指示是否包含查询结果的数据行;

User::find()->batch(10);  每次取 10 条数据

User::find()->each(10);  每次取 10 条数据, 迭代查询

User::find()->select(['id','name','author'])->where(['in','id',$ids])->asArray()->all();

例四:

 

获得表中某一int类型字段的最大值

$maxListorder = Category::find()->select('listorder')->where(['=''pid', $pid])->orderBy('listorder desc')->limit(1)->one()->listorder;//(返回int类型的数值)

或$maxListorder = Category::find()->select(['max'=>new Expression('max(listorder)')])->where(['=', 'pid', $pid])->createCommand()->queryAll();//一个二位数组

或$maxListorder = Category::find()->select('max(listorder) as maxlistorder')->where(['=', 'pid', $pid])->asArray()->all();//一个二维数组

2.增:

方法一:

$applyres = $connection->createCommand()->insert('user',['email'=>$email, 'name'=>$name, 'mobile'=>$phone, 'status'=>$status,'create_time'=>time(), 'is_super'=>0, 'password'=>new Expression('PASSWORD(:p)',[':p'=>$password]), 'remark'=>$disc])->execute();//成功返回1,否则返回0

方法二:

$admin = new Admin;

$admin->username = $username;

$admin->password = $password;

$admin->save();

if( $admin->save()> 0){

echo "添加成功";

$id = $admin->attributes['id'];//返回刚才插入的那条数据的id

}else{ echo "添加失败"; }

据此封装函数如下:

public function diySaveAttribs($field2ValueMap, $pkFieldName = '')
{
    foreach ($field2ValueMap as $k => $v)
    {
        $this->$k = $v;
    }
    $isOk = $this->save();

return $pkFieldName ? $this->attributes[$pkFieldName] : $isOk;
}

批量插入:

INSERT 一次插入多行

$connection->createCommand()->batchInsert('user', ['name', 'age'], [ ['Tom', 30], ['Jane', 20], ['Linda', 25], ])->execute();

$count = \yii::$app->getDb()->createCommand()->batchInsert('notice', $columnArr, $dataArr)->execute();

封装函数如下:

//批量插入
public static function batchInsert($columns, $rows, $dbConfName = '')
{
    $dbConfName = $dbConfName ? $dbConfName : static::DB;

return static::getConn($dbConfName)->createCommand()->batchInsert(static::TableName, $columns, $rows)->execute();
}

3.改:

//update user set mobile='{$phone}',remark='{$remark}' where email='{$email}';

$count =User::updateAll(array('mobile'=>$phone,'remark'=>$remark),'email=:email',array(':email'=>$email));

//第一个参数是$attributes,即要被更改的字段对应的值,第二个参数是$conditions,第三个参数是条件的的值$param

$res = User::updateAll(['status'=>3],'id=:id',[':id'=>$userId]);//修改id为$userId的status为3

要查看sql语句可在execute之前执行getRawSql()

$connection->createCommand()->insert('user', ['email' => $email, 'name' => $name, 'mobile' => $phone, 'status' => $status, 'create_time' => time(), 'is_super' => 0, 'password' => new Expression('PASSWORD(:p)', [':p' => $password]), 'remark' => $disc])->getRawSql();

4.删:

$count = Projects::deleteAll('id=:id', [':id' => $id]);

$deletetopCount = Category::deleteAll('pid=:pid and type=:type', ['pid' => $pid, 'type' => $type]);

Category::deleteAll(['fid' => $id]);

Comment::deleteAll(['in''id', $ids]);

$count = WeiboUserAccount::deleteAll(['and', ['account_id' => $aid], ['in''user_id', $uids,]]);

$count = WechatKeyword::deleteAll(['or', ['in''id', $ids], ['in''related_id', $ids]]);

从上可看到deleteAll中的条件形式和where中的条件形式是一样的

$connection->createCommand()->delete('user''id = :userid and email=:email', [':userid'=>$userid, ':email'=>444])->execute();//打印出的语句DELETE FROM `user` WHERE id = '124' and email=444

//d多条件删除

$delCount = UserSubscribe::deleteAll([

'and',

['in''group_id'array_values(UserSubscribeGroup::groupMap($uid, true))/*得到 该用户的 所有 订阅分组*/],

['in''wechat_account_id', $wechatIds],

]);

(三)事务

$db = Yii::app()->db;

$dbTrans = $db->beginTransaction();

$dbTrans->commit();

$dbTrans->rollback();

//事务的基本结构(多表更新插入操作请使用事务处理)

$dbTrans = Yii::app()->db->beginTransaction();

try{

$post = new Post;

$post->'title' = 'Hello dodobook!!!';

if(!$post->save()) throw new Exception("Error Processing Request", 1);

$dbTrans->commit();

//  $this->_end(0,'添加成功!!!');

}catch(Exception $e){

$dbTrans->rollback();

//  $this->_end($e->getCode(),$e->getMessage());

}

(四)Yii中的常用路径总结

\Yii::$app->getRuntimePath()//获得项目runtime日志保存路径;

\Yii::$app->controller->id;// 得到当前controller的ID方法

\Yii::$app->controller->action->id;// 得到当前action的ID方法

\Yii::$app->request->hostInfo;// 得到当前域名

\yii::$app->request->userIP;//获得客户端ip

dirname(\yii::$app->basePath);//获得项目的根路径

\Yii::$app->request->referrer;//获得上一页面的请求url

\yii::$app->request->absoluteUrl;//The currently requested absolute URL

(五)Yii2中where条件使用总结

在Yii的Model里进行查询的时候 where是必不可少的。

Where方法声明为

static where( $condition )

其中参数 $condition类型为字符串或者数组

1、字符串

字符串是最简单的,直接按sql中的where条件写就可以,如

  1. $condition = 'name=\'xiaoming\' and age>10';

2、数组

如果是数组的情况下,有两种格式的写法。

  • name-value格式的字典数组:['column1' => value1, 'column2' => value2, ...]
  • 逻辑操作符格式:[operator, operand1, operand2, ...]

第一种写法:

如果value值是字符串或者数字等,那么生成的条件语句格式为column1=value1 AND column2=value2 AND ....

['type' => 1, 'status' => 2]

生成

(type = 1) AND (status = 2)

如果value值是数组,那么会生成sql 中的IN语句;

['id' => [1, 2, 3], 'status' => 2]

//生成

(id IN (1, 2, 3)) AND (status = 2)

如果value值为Null,那么会生成 Is Null语句。

['status' => null]

//生成

status IS NULL

第二种写法会根据不同的操作符生成不同的sql条件。

and: 会使用 AND把所有的操作数连接起来。如

['and', 'id=1', 'id=2']
// 生成

id=1 AND id=2

如果某个运算数也是数组,那么会按如下格式转换为字符串,如['and', 'type=1', ['or', 'id=1', 'id=2']]生成type=1 AND (id=1 OR id=2)

注意:这个方法不会对进行引用或者编码操作。

or: 和 and 类似,只不过是用 OR来连接操作数。

between: 第一个操作数是列的名称,第二个和第三个操作数为范围的最小值和最大值。如

['between', 'id', 1, 10]

//生成

id BETWEEN 1 AND 10

not between: 和between 相似。

in: 第一个操作数为列或者DB表达式,第二个操作数为数组, 如['in', 'id', [1, 2, 3]]

//生成

id IN (1, 2, 3)

注意:这个方法会对列进行引用,对数组中的值也会编码。

not in: 和上面的in 相似。

like: 第一个操作数为列或者DB表达式,第二个操作数为字符串或者数组如

['like', 'name', 'tester']

//生成

name LIKE '%tester%'

如果值是数组的话,会生成多个like语句,并用 AND来连接。如['like', 'name', ['test', 'sample']]

//生成

name LIKE '%test%' AND name LIKE '%sample%'

注意:这个方法会对列进行引用,对数组中的值也会编码。
有时候你可能需要自己来处理%,那么可以用第三个参数:

['like', 'name', '%tester', false]

//生成

name LIKE '%tester'

or like: 和like相似,只是在第二个参数为数组的情况下用or来连接多个like 语句。

not like: 和like 相似。

or not like: 和or like 相似。

(六)yii中第三方类通过命名空间方式引用的方法

如下,在web.php和console.php中添加

Yii::$classMap['SmsServer'] = '@app/lib/SmsServer.php';

这样的语句,key值为命名空间的名字(最好和类名一致),value为该类在项目中的存放路径

参考网站

http://www.yii-china.com/video/index.html

http://www.yii-china.com/tutorial/index.html?type=2

http://www.yiichina.com/doc/guide/2.0