关于在Laravel 4中记录SQL查询已经有几个问题了.但是我已经尝试了几乎所有这些问题,但它仍然没有按照我想要的方式工作.
这是我的情况
收到AJAX请求并运行RAW参数化Postgres SQL查询(例如
DB :: select('select*from my_table where id =?',array(1))
如果我使用
Event::listen('illuminate.query', function($sql)
{
Log::error($sql);
});
Run Code Online (Sandbox Code Playgroud)
我只是得到"select*from my_table where id =?" 作为没有实际填充ID值的日志消息.
如果我使用
$queries = DB::getQueryLog();
$last_query = end($queries);
Log::error(print_r($last_query, true));
Run Code Online (Sandbox Code Playgroud)
我仍然没有填充ID的最终SQL查询.
最后,如果我使用像https://github.com/loic-sharma/profiler这样的日志记录工具- 由于我正在制作AJAX请求,它不会显示任何内容.
我用尽了我的选择吗?还有另一种更好的方法吗?
Col*_*mes 56
这是我目前用于记录sql查询的内容.您应该能够将其放入主路由文件中,然后将"log"=> true添加到数据库配置中.
if (Config::get('database.log', false))
{
Event::listen('illuminate.query', function($query, $bindings, $time, $name)
{
$data = compact('bindings', 'time', 'name');
// Format binding data for sql insertion
foreach ($bindings as $i => $binding)
{
if ($binding instanceof \DateTime)
{
$bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
}
else if (is_string($binding))
{
$bindings[$i] = "'$binding'";
}
}
// Insert bindings into query
$query = str_replace(array('%', '?'), array('%%', '%s'), $query);
$query = vsprintf($query, $bindings);
Log::info($query, $data);
});
}
Run Code Online (Sandbox Code Playgroud)
感谢Jeemusu回答有关将绑定插入预处理语句的问题.
Jee*_*usu 11
您应该能够通过传递$bindings
作为Event函数的第二个参数来找到绑定.
Event::listen('illuminate.query', function($sql, $bindings, $time){
echo $sql; // select * from my_table where id=?
print_r($bindings); // Array ( [0] => 4 )
echo $time; // 0.58
// To get the full sql query with bindings inserted
$sql = str_replace(array('%', '?'), array('%%', '%s'), $sql);
$full_sql = vsprintf($sql, $bindings);
});
Run Code Online (Sandbox Code Playgroud)
在Laravel 3.x中,我认为事件监听器被调用了 laravel.query
继续@Collin詹姆斯回答.
如果你只想为sql登录一个单独的文件,你可以这样做:
if (Config::get('database.log', false)) {
Event::listen('illuminate.query', function($query, $bindings, $time, $name) {
$data = compact('bindings', 'time', 'name');
// Format binding data for sql insertion
foreach ($bindings as $i => $binding) {
if ($binding instanceof \DateTime) {
$bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
} else if (is_string($binding)) {
$bindings[$i] = "'$binding'";
}
}
// Insert bindings into query
$query = str_replace(array('%', '?'), array('%%', '%s'), $query);
$query = vsprintf($query, $bindings);
$log = new Logger('sql');
$log->pushHandler(new StreamHandler(storage_path().'/logs/sql-' . date('Y-m-d') . '.log', Logger::INFO));
// add records to the log
$log->addInfo($query, $data);
});
}
Run Code Online (Sandbox Code Playgroud)
将它放在文件的顶部:
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
Run Code Online (Sandbox Code Playgroud)
这会将您的所有查询记录到名为的文件sql-YYYY-mm-dd.log
中storage/logs/
.
虽然接受的答案是正确的,但这个答案解释了如何在使用jQuery发出Ajax请求时更新loic-sharma探查器.使用这种方法,不需要读取文件日志.
第一个问题是在每个Ajax请求上将更新的探查器数据发送到客户端.这可以使用Laravel应用程序的"after"事件来解决.
应用程序/ filters.php:
App::after(function($request, $response)
{
// If it's a JsonResponse and the profiler is enabled, include it in the response.
if($response instanceof \Illuminate\Http\JsonResponse && Profiler::isEnabled()) {
$profiler = Profiler::getFacadeRoot();
$profilerJson = json_encode($profiler->render());
$content = substr($response->getContent(), 0, -1) . ',"profiler":' . $profilerJson . '}';
$response->setContent($content);
}
});
Run Code Online (Sandbox Code Playgroud)
该App::after
过滤器将在每次Laravel要求运行.上面闭包的第一行确保只有在响应类型为JsonResponse且启用了探查器时它才会继续.如果是这种情况,请渲染探查器并将HTML附加到JSON对象.
注意:此代码假定返回的JSON是一个对象.所以它对于数组会失败:Response::json(array(1,2,3))
.
现在已将更新的探查器HTML发送到客户端,我们必须使用javascript使用新的探查器HTML更新DOM.每次客户端获得JSON响应时都会发生这种情况.jQuery提供全局Ajax事件处理程序,这是完美的实现.
$(document).ajaxSuccess(function(event, request, settings) {
try {
json = jQuery.parseJSON(request.responseText);
if(json.profiler) {
renderProfiler(json.profiler);
}
} catch(error) {
// Its not JSON.
return;
}
});
Run Code Online (Sandbox Code Playgroud)
这是用新的方法替换旧的探查器的方法:
renderProfiler = function(data) {
// Remove previous
$anbu = $('.anbu');
$anbu.prev().remove(); // Removes <style> tag of profiler
$anbu.next().next().remove(); // Removes the inline script tag of profiler
$anbu.next().remove(); // Removes jQuery script tag by the profiler
$anbu.remove(); // Removes the <div> tag of profiler
$(document.body).append(data);
};
Run Code Online (Sandbox Code Playgroud)
现在它就像返回响应一样简单:
return Response::json(array(
'user' => Auth::user()
));
Run Code Online (Sandbox Code Playgroud)
Laravel将追加探查器HTML.javascript将捕获JSON响应并更新DOM.您将在网页上获得SQL查询和计时.
在测试代码时,可能存在一两个错误.这也不是我怎么做的.我没有在json响应中发送HTML,而是使用分析器中的实际数据扩展对象.在客户端,我使用胡子模板渲染探查器.
归档时间: |
|
查看次数: |
29431 次 |
最近记录: |