2015-10-19 14:28:21 5426次浏览 2条回答 0 悬赏 50 金钱

最近刚学yii2 对findOne()的源码产生疑问?具体是这样的(下面的流程都是我打断点一步步出来的):
首先findOne()是在yiisoft/yii2/db/BaseActiveRecord.php里的方法(大概在100行那) 代码如下:

public static function findOne($condition)
{
    return static::findByCondition($condition)->one();
}

然后运行findByCondition($condition)方法 此方法不是在BaseActiveRecord.php里的而是在yiisoft/yii2/db/ActiveRecord.php里的 代码如下:

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);
}

此方法返回Query的对象(yiisoft/yii2/db/Query.phpQuery.php里有one()方法 前面说了findOne()方法返回还有一个one()方法 代码如下:

public function one($db = null)
{
    return $this->createCommand($db)->queryOne();
}

现在运行到one方法里面了 现在的问题是$this->createCommand($db)这个方法,这个在Query.php有,但是没有运行进去,也就是说,他运行的不是Query.phpcreateCommand方法,经过打断点,他运行的是yiisoft/yii2/db/Connection.php里的createCommand方法,所有这里就糊涂了,为什么运行的不是自己的方法,而且Query和Connection好像没有继承关系吧,希望知道的人指点迷津

  • 回答于 2015-10-20 09:40 举报

    说明一点:findOne(),findAll(),和find()->one(),find()->all()是走不一样的代码的。后一种才是走的query。

    1 条回复
    回复于 2015-10-20 11:59 回复

    什么意思?

    觉得很赞
  • 回答于 2015-10-20 16:06 举报

    Query的createCommand方法不是调用的yiisoft/yii2/db/Connection.php方法么?

    这里,没有调用到Query::createCommand的方法的原因是在ActiveRecord::find方法里面,是创建的一个ActiveQuery对象。

    而ActiveQuery的类里面,对Query::createCommand方法进行了重写,所以,父类中的方法没有被调用。这也是你的父类中的断点没有进去的原因。

    ActiveQuery::createCommand就是调用的Connection::createCommand方法来创建一个Command对象的。

    3 条回复
    回复于 2015-10-20 16:31 回复

    也就是说 findByCondition($condition)方法内的$query = static::find();这个是ActiveQuery的对象而不是Query的对象?

    回复于 2015-10-21 09:02 回复

    你可以试一下,ActiveRecord里面对find方法进行了重写,实例的是一个ActiveQuery对象。

    回复于 2015-10-21 15:43 回复

    我打印过var_dump($this)确实是ActiveQuery的对象

您需要登录后才可以回答。登录 | 立即注册
xyf90314
副总裁

xyf90314

注册时间:2015-03-04
最后登录:2023-03-13
在线时长:95小时23分
  • 粉丝21
  • 金钱5257
  • 威望40
  • 积分6607

热门问题