你遇到的问题是:日志里只显示 status=:ycp2 这种占位符,看不到真实参数值,这是因为 Yii1 虽然开启了参数记录,但默认不会把参数拼到 SQL 里,只会单独记录。

我给你一个100%能看到真实SQL、真实值的最终方案,复制就能用。

最终方案:日志直接输出【带真实值的完整SQL】

1. 先确认你的 db 配置(必须这2行)

protected/config/main.php

'db'=>array(
    'connectionString' => 'mysql:host=localhost;dbname=xxx',
    'username' => 'xxx',
    'password' => 'xxx',
    'charset' => 'utf8',
    'enableProfiling' => true,
    'enableParamLogging' => true, // 必须开
),

2. 用这个日志配置(直接替换)

'log'=>array(
    'class'=>'CLogRouter',
    'routes'=>array(
        array(
            'class'=>'CFileLogRoute',
            'categories'=>'system.db.CDbCommand.query',
            'levels'=>'profile',
            'logFile'=>'sql_real_'.date('Y-m-d').'.log',
            // 关键:把参数和SQL拼在一起
            'filter'=>array(
                'class'=>'CLogFilter',
            ),
        ),
    ),
),

3. 这样还不够!必须加一段代码(核心)

新建文件:
protected/components/DbLogger.php

<?php
class DbLogger extends CDbCommand
{
    public function query($fetchMode = null)
    {
        $sql = $this->getText();
        $params = $this->params;

        // 把占位符替换成真实值
        foreach ($params as $key => $value) {
            $sql = str_replace($key, var_export($value, true), $sql);
        }

        // 记录真实SQL
        Yii::log($sql, 'profile', 'db.real');
        return parent::query($fetchMode);
    }
}

然后在 db 配置里加一行:

'db'=>array(
    'connectionString' => 'mysql:host=localhost;dbname=xxx',
    'username' => 'xxx',
    'password' => 'xxx',
    'charset' => 'utf8',
    'enableProfiling' => true,
    'enableParamLogging' => true,
    'commandClass' => 'DbLogger', // 加这一行
),

4. 最后日志路由改成记录真实SQL

array(
    'class'=>'CFileLogRoute',
    'categories'=>'db.real',
    'levels'=>'profile',
    'logFile'=>'sql_real_'.date('Y-m-d').'.log',
),

最终效果(你想要的样子)

2025-04-08 11:22:33 [profile] db.real
SELECT * FROM user WHERE status=1 AND id=100

直接看到完整SQL + 真实值,没有占位符


最简单懒人版(不用新建类)

如果你不想新建文件,只想快速看到值,用这个日志配置:

array(
    'class'=>'CWebLogRoute',
    'categories'=>'system.db.*',
    'levels'=>'profile,trace',
),

页面底部会显示:

SELECT * FROM user WHERE status=:ycp2
Bound with {":ycp2":1}

虽然不是拼在一起,但能直接看到值


我可以直接给你生成一份完整可覆盖的配置,你要吗?

你只要告诉我:

  • 要记录到文件
  • 还是要在页面显示
    我直接给你最终版。

标签: none

添加新评论