45

I want to get the last query CakePHP ran. I can't turn debug on in core.php and I can't run the code locally. I need a way to get the last sql query and log it to the error log without effecting the live site. This query is failing but is being run.

something like this would be great:

$this->log($this->ModelName->lastQuery);

Thanks in advance.

11 Answers11

49

For Cake 2.0, the query log is protected so this will work

function getLastQuery() {
  $dbo = $this->getDatasource();
  $logs = $dbo->getLog();
  $lastLog = end($logs['log']);
  return $lastLog['query'];
}
Matt
  • 1,328
  • 1
  • 16
  • 28
  • I checked above function and its working fine if debug mode is 2 but its not returning query if debug mode is 0 . is there any another solution? – Ganesh Patil Sep 22 '14 at 06:30
32

Tested in CakePHP v2.3.2

$log = $this->Model->getDataSource()->getLog(false, false);
debug($log);
Haktan Suren
  • 651
  • 7
  • 17
29

In CakePHP 1.x, the data you want is accessible in DataSource::_queriesLog. Cake doesn't really provide a getter method for this member, but the underlying language being PHP, nothing stops you from doing the following:

In app/app_model.php:

function getLastQuery()
{
    $dbo = $this->getDatasource();
    $logs = $dbo->_queriesLog;

    return end($logs);
}
Brad Koch
  • 19,267
  • 19
  • 110
  • 137
Daniel Wright
  • 4,584
  • 2
  • 27
  • 28
  • When I try using this function I only get "2010-03-29 11:13:29 Error: " in the error log file. I used $this->log($this->Job->getLastQuery()); –  Mar 29 '10 at 00:36
  • $this->log(var_export($this->Job->getLastQuery(),true)); –  Mar 29 '10 at 00:54
  • Where are you calling $this->log()? Also, you might want to debug the output from Model::getLastQuery before throwing it in the log. It might be returning an array, causing an array-to-string conversion error. – Daniel Wright Mar 29 '10 at 02:21
  • 1
    I had to do: $query = end($logs); return $query['query']; Either the format of the _queriesLog changed, or the above code returned an array of data about the query rather than simply the query itself. – Brad Koch Aug 24 '11 at 19:06
4

You can use this inline.

$dbo = $this->Model->getDatasource();
// store old state
$oldStateFullDebug = $dbo->fullDebug;
// turn fullDebug on
$dbo->fullDebug = true;

// Your code here! eg.
$this->Model->find('all');

// write to logfile
// use print_r with second argument to return a dump of the array
Debugger::log(print_r($dbo->_queriesLog, true));
// restore fullDebug
$dbo->fullDebug = $oldStateFullDebug;
blavla
  • 543
  • 5
  • 4
  • gives an error `Cannot access protected property Mysql::$_queriesLog `, cake 2.3 – dav Jun 04 '14 at 04:16
4

Simple you can use showLog() function

var_dump($this->YourModel->getDataSource()->showLog());
Quy Le
  • 2,354
  • 25
  • 18
4

This is a very late answer, i know, but for whoever needs this in the future, you can always restrict setting debug to your IP, For example:

Configure::write('debug', 0);
if($_SERVER["REMOTE_ADDR"] == '192.168.0.100'){
Configure::write('debug', 2); //Enables debugging only for your IP.
}
Captain Sparrow
  • 1,114
  • 17
  • 26
alinn
  • 311
  • 2
  • 7
  • 1
    you can even make a debug method in one of your controllers that sets a session variable true/false and sets the debug config variable accordingly. – alinn Dec 10 '10 at 08:00
  • 1
    Alinn, if access to that method is not secured properly it could lead to a security exploit where anyone could enable debug mode. Be careful. – Brad Koch Jan 15 '13 at 16:38
3

Combination of Matt's and blavia's solution (works when debug is not 2):

$dbo = $this->Model->getDatasource();
$oldStateFullDebug = $dbo->fullDebug;
$dbo->fullDebug = true;
// find or whatever...
$this->Model->find("all");
$logs = $dbo->getLog();
$lastLog = end($logs['log']);
CakeLog::write("DBLog", $lastLog['query']);
$dbo->fullDebug = $oldStateFullDebug;
2

Having a quick skim of the book, cakephp api getLog you could turn on logTransaction. Although having not used it, I'm not sure how it will perform.

Otherwise you could experiment with FirePHP and here is the a guide for it,

You might try DebugKit, although off the top of my head I think you do still need debug 2 to get it to work.

Hopefully something might give you a lead. :)

RavatSinh Sisodiya
  • 1,596
  • 1
  • 20
  • 42
David Yell
  • 11,756
  • 13
  • 61
  • 100
1

You can use this:

$log = $this->Model->getDataSource()->getLog(false, false);

pr($log);die;
DimaSan
  • 12,264
  • 11
  • 65
  • 75
ajeet
  • 21
  • 4
1

There are two methods to view the query in CakePHP.

Both methods you have to add the below one line in app/Config/core.php

Configure::write('debug', 2); 

First methods :

debug($this->getLastQuery()); 

where you want to get the query add above line and call this function getLastQuery() on same controller using below code

public function getLastQuery() {
    $dbo = $this->TModel->getDatasource();  //Here TModel is a model.what table you want to print 
    $logs = $dbo->getLog();
    $lastLog = end($logs['log']);
    return $lastLog['query'];
}

second method :

add the below line in the any Elements files.

<?php echo $this->element('sql_dump'); ?>
krishna ragav
  • 182
  • 1
  • 1
  • 9
0

This will help you.

echo '<pre>';
$log = $this->YOUR_MODEL->getDataSource(); 
print_r($log);
exit;
Captain Sparrow
  • 1,114
  • 17
  • 26