Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
286 views
in Technique[技术] by (71.8m points)

php - Log the actual SQL query using ActiveRecord with Yii2?

I'm doing this:

$students = Student::find()->all();
    return $this->render('process', array('students' => $students));

and then this in the view:

foreach($students as $student)
    {
        echo $student->name . ',  ';
        echo $student->getQuizActivitiesCount(); ?> <br /> <?php
    }

i would like to see the sql query being performed. a student "has many" quiz activities, and the query performs perfectly, but i need to see the raw SQL. is this possible?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Method 1

With relations that return yiidbActiveQuery instance it's possible to extract the raw SQL query directly in code for example with var_dump().

For example if we have user relation:

/**
 * @return yiidbActiveQuery
 */
public function getUser()
{
    return $this->hasOne(User::className(), ['id' => 'user_id']);
}

You can then var_dump() the raw SQL like that:

var_dump($model->getUser()->prepare(Yii::$app->db->queryBuilder)->createCommand()->rawSql);
exit();

Note that you should call it like that and not $model->user->... (the latter returns User instance).

But in your case it's not possible because count() immediately returns int. You can var_dump() partial query without count(), but I think it's not convenient.

Note that you can use this method for dumping generated SQL of any ActiveQuery instances (not only those that were returned by relation), for example:

$query = User::find()->where(['status' => User::STATUS_ACTIVE]);
var_dump($query->prepare(Yii::$app->db->queryBuilder)->createCommand()->rawSql);
exit();

Method 2

This is much simpler in my opinion and I personally prefer this one when debugging SQL queries.

Yii 2 has built-in debug module. Just add this to your config:

'modules' => [
    'debug' => [
        'class' => 'yiidebugModule',
    ],
],

Make sure you only have it locally and not on production. If needed, also change allowedIPs property.

This gives you functional panel at the bottom of the page. Find the DB word and click on either count or time. On this page you can view all executed queries and filter them. I usually don't filter them in Grid and use standard browser search to quickly navigate through and find the necessary query (using the table name as keyword for example).

Method 3

Just make an error in query, for example in column name - cityy instead of city. This will result as database exception and then you can instantly see the generated query in error message.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...