If you can't get it from PDO itself, consider using a wrapper class just for PDOStatement::execute()
which will log the SQL query and values, and then call execute()
on the statement. You will have to refactor your code to use the new class.
As a sidenote, I see that PDOStatement has a class variable $queryString
that holds the query being used. The values will have to be retrieved from whatever's passed into execute()
or bindParam()
.
First some utility functions for logging:
//removes newlines and extra spaces from print_r output
function str_squeeze($str) {
if (is_array($str)) {
$str = print_r($str, true);
}
$str = preg_replace('/[(\r)?\n|\t]/', ' ', $str);
$str = trim(ereg_replace(' +', ' ', $str));
return $str;
}
function logger($str) {
//log it somewhere
}
Option 1: wrapper class around PDOStatement
class My_PDO_Utils {
public static function execute(PDOStatement &$stm, $values = array()) {
logger("QUERY: " . $stm->queryString . ", values = " . str_squeeze($values)) ;
return $stm->execute($values) ;
}
}
Then your code will have to be:
$stm = $db->prepare("SELECT * FROM table2 WHERE id = ?") ;
$res = My_PDO_Utils::execute($stm, array(79)) ;
instead of
$res = $stm->execute(array(79)) ;
Thinking some more about it, you could take it one further:
Option 2: Extend PDO and PDOStatement
If you want to be adventurous you can extend PDOStatement to do the logging for you, and PDO to return your extended PDOStatement class. This will require the least possible refactoring, ie just change new PDO()
to new MY_PDO()
, but could get tricky in its implementation as you would need to explicitely define any PDOStatement functionality you need in MY_PDOStatement so it gets called properly.
class My_PDO extends PDO {
public function prepare($sql, $options = array()) {
//do normal call
$stm = parent::prepare($sql, $options) ;
//encapsulate it in your pdostatement wrapper
$myStm = new My_PDOStatement() ;
$myStm->stm = $stm ;
return $myStm ;
}
}
class My_PDOStatement extends PDOStatement {
/**
*
* @var PDOStatement
*/
public $stm ;
public function execute($values) {
logger("QUERY: " . $this->stm->queryString . ", values = " . str_squeeze($values)) ;
return $this->stm->execute($values) ;
}
public function fetchAll($fetch_style = PDO::FETCH_BOTH, $column_index = 0, $ctor_args = array()) {
return $this->stm->fetchAll($fetch_style, $column_index, $ctor_args) ;
}
}
But now your code can be:
$db = new My_PDO($dsn, $user, $pass) ;
$stm = $db->prepare("SELECT * FROM table2 WHERE id = ?") ;
$res = $stm->execute(array(79)) ;
$row = $stm->fetchAll() ;