前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Yii2中findAll()的正确使用姿势/返回为空的处理办法

Yii2中findAll()的正确使用姿势/返回为空的处理办法

作者头像
双面人
发布2019-04-10 16:32:29
3K0
发布2019-04-10 16:32:29
举报
文章被收录于专栏:热爱IT热爱IT

从一次错误的操作开始

代码语言:javascript
复制
$buildingObject = Building::findAll("status=1");
  • 1

这个调用看着没有任何毛病,但是在使用时返回的结果却是一个空数组。再回过头来看看数据表中: 

数据表
数据表

按照套路来讲,查询后应该返回的是一个对象数组呀!为什么是空呢?百思不得其解,还是去翻看一下代码吧。

抽丝剥茧从findAll开始

静态方法findAll()其实是在yii\db\BaseActiveRecord中的:

代码语言:javascript
复制
/**
 * @inheritdoc
 * @return static[] an array of ActiveRecord instances, or an empty array if nothing matches.
 */
public static function findAll($condition)
{
   return static::findByCondition($condition)->all();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

关于他的实现其实是调用了本方法中的findByCondition来实现的,从这儿大家也可以看到高大上的findAll($condition)的实现也是非常简单的调用了相应的方法来实现的而已。所以其实如果是查询多条数据的话也可以使用其他方式都非常方便的。

抽丝剥茧findByCondition($condition)

静态方法findAll($condition)其实是调用了findByCondition这个静态方法的那么这个方法是怎么样实现的呢?

代码语言:javascript
复制
protected static function findByCondition($condition)
{
    $query = static::find();

    if (!ArrayHelper::isAssociative($condition)) {
        // query by primary key
        $primaryKey = static::primaryKey();
        if (isset($primaryKey[0])) {
            $pk = $primaryKey[0];
            if (!empty($query->join) || !empty($query->joinWith)) {
                $pk = static::tableName() . '.' . $pk;
            }
            $condition = [$pk => $condition];
        } else {
            throw new InvalidConfigException('"' . get_called_class() . '" must have a primary key.');
        }
    }

    return $query->andWhere($condition);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

这儿有个误区大家要注意了,这儿的findByCondition($condition)其实是ActiveRecord中的而不是BaseActiveRecord,因为继承关系已经被重写。 这部分的代码也很简单,重点是在那个if判断中。

代码语言:javascript
复制
if (!ArrayHelper::isAssociative($condition))
  • 1

这个是使用了yii2提供的数组辅助类里边的isAssociative来判断传入的$condition是不是一个关联数组。如果不是一个关联数组则会进入if里边进行执行。

代码语言:javascript
复制
// query by primary key
$primaryKey = static::primaryKey();   //获取数据表的主键
if (isset($primaryKey[0])) {    //判断主键是否为空
    $pk = $primaryKey[0];
    //判断有没有连表查询,如果有连表查询就处理成  表名.主键   的方式
    if (!empty($query->join) || !empty($query->joinWith)) {
        $pk = static::tableName() . '.' . $pk;
    }
    //直接把条件当做主键拼接到条件了!!!
    $condition = [$pk => $condition];
} else {
    //如果主键为空则抛出异常
    throw new InvalidConfigException('"' . get_called_class() . '" must have a primary key.');
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

常用用法分析

可以看出你在findAll($condition)时传入的参数不是关联数组的情况下会当做主键处理。但是当做主键处理时这儿可以是数组。比如:

代码语言:javascript
复制
$buildingObject = Building::findAll([18,19]);
  • 1

这样查询的结果是id为18和19的两条数据的对象数组。但是如果你真的要按照id来查询多条数据的话注意了,参数中的id不能是字符串。例如

代码语言:javascript
复制
$buildingObject = Building::findAll("18,19");
  • 1

这样查询仅仅能查出id为18的数据。当然单条数据的查询还是推荐使用非常方便的findOne($condition)来查询。  当然如果有相等的组合条件也是可以的,例如:

代码语言:javascript
复制
$buildingObject = Building::findAll(['id'=>[18,19],'status'=>1]);
  • 1

这样就查询出id为18和19而且status字段为1的数据

错误示范

当然如果有表达式数组条件和字符串条件都不支持的。例如

代码语言:javascript
复制
//注意以下是错误示范
$buildingObject = Building::findAll("id>10");
$buildingObject = Building::findAll([">", "id", 10);
  • 1
  • 2
  • 3

所以在项目中findAll要慎重使用当然使用findAll来查询的都可以用其他方法来代替。

以下属于原创

findall出来的对象是一个数组,

一种情况 

$pc=Product_category::findAll(['p'=>'638']);

二种情况

        // $pc=Product_category::findOne(['p'=>'636']);

        // $pc->delete();

三种情况

       // $pc=Product_category::findOne('284');

        // $pc->delete();

        二和三等价

一出来的结果要遍历,如果后面有插入那就惨了。

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018/06/23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 从一次错误的操作开始
  • 抽丝剥茧从findAll开始
  • 抽丝剥茧findByCondition($condition)
  • 常用用法分析
  • 错误示范
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档