3 namespace RedBeanPHP\Logger\RDefault;
5 use RedBeanPHP\Logger as Logger;
6 use RedBeanPHP\Logger\RDefault as RDefault;
7 use RedBeanPHP\RedException as RedException;
11 * A special logger for debugging purposes.
12 * Provides debugging logging functions for RedBeanPHP.
14 * @file RedBeanPHP/Logger/RDefault/Debug.php
15 * @author Gabor de Mooij and the RedBeanPHP Community
19 * copyright (c) G.J.G.T. (Gabor) de Mooij
20 * This source file is subject to the BSD/GPLv2 License that is bundled
21 * with this source code in the file license.txt.
23 class Debug extends RDefault implements Logger
31 * Writes a query for logging with all bindings / params filled
34 * @param string $newSql the query
35 * @param array $bindings the bindings to process (key-value pairs)
39 private function writeQuery( $newSql, $newBindings )
41 //avoid str_replace collisions: slot1 and slot10 (issue 407).
42 uksort( $newBindings, function( $a, $b ) {
43 return ( strlen( $b ) - strlen( $a ) );
47 foreach( $newBindings as $slot => $value ) {
48 if ( strpos( $slot, ':' ) === 0 ) {
49 $newStr = str_replace( $slot, $this->fillInValue( $value ), $newStr );
56 * Fills in a value of a binding and truncates the
57 * resulting string if necessary.
59 * @param mixed $value bound value
63 protected function fillInValue( $value )
65 if ( is_null( $value ) ) $value = 'NULL';
67 $value = strval( $value );
68 if ( strlen( $value ) > ( $this->strLen ) ) {
69 $value = substr( $value, 0, ( $this->strLen ) ).'... ';
72 if ( !\RedBeanPHP\QueryWriter\AQueryWriter::canBeTreatedAsInt( $value ) && $value !== 'NULL') {
73 $value = '\''.$value.'\'';
80 * Dependending on the current mode of operation,
81 * this method will either log and output to STDIN or
84 * Depending on the value of constant PHP_SAPI this function
85 * will format output for console or HTML.
87 * @param string $str string to log or output and log
91 protected function output( $str )
96 /* just a quick heuritsic to highlight schema changes */
97 if ( strpos( $str, 'CREATE' ) === 0
98 || strpos( $str, 'ALTER' ) === 0
99 || strpos( $str, 'DROP' ) === 0) {
102 if (PHP_SAPI === 'cli') {
103 if ($highlight) echo "\e[91m";
108 echo "<b style=\"color:red\">{$str}</b>";
118 * Normalizes the slots in an SQL string.
119 * Replaces question mark slots with :slot1 :slot2 etc.
121 * @param string $sql sql to normalize
125 protected function normalizeSlots( $sql )
129 while(strpos($newSql, '?') !== FALSE ){
130 $pos = strpos( $newSql, '?' );
132 $begin = substr( $newSql, 0, $pos );
133 $end = substr( $newSql, $pos+1 );
134 if (PHP_SAPI === 'cli') {
135 $newSql = "{$begin}\e[32m{$slot}\e[39m{$end}";
137 $newSql = "{$begin}<b style=\"color:green\">$slot</b>{$end}";
145 * Normalizes the bindings.
146 * Replaces numeric binding keys with :slot1 :slot2 etc.
148 * @param array $bindings bindings to normalize
152 protected function normalizeBindings( $bindings )
155 $newBindings = array();
156 foreach( $bindings as $key => $value ) {
157 if ( is_numeric($key) ) {
158 $newKey = ':slot'.$i;
159 $newBindings[$newKey] = $value;
162 $newBindings[$key] = $value;
171 * Takes a number of arguments tries to create
172 * a proper debug log based on the available data.
176 public function log()
178 if ( func_num_args() < 1 ) return;
180 $sql = func_get_arg( 0 );
182 if ( func_num_args() < 2) {
185 $bindings = func_get_arg( 1 );
188 if ( !is_array( $bindings ) ) {
189 return $this->output( $sql );
192 $newSql = $this->normalizeSlots( $sql );
193 $newBindings = $this->normalizeBindings( $bindings );
194 $newStr = $this->writeQuery( $newSql, $newBindings );
195 $this->output( $newStr );
199 * Sets the max string length for the parameter output in
200 * SQL queries. Set this value to a reasonable number to
201 * keep you SQL queries readable.
203 * @param integer $len string length
207 public function setParamStringLength( $len = 20 )
209 $this->strLen = max(0, $len);