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条件写就可以,如
- $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