| [ Index ] |
PHP Cross Reference of YOURLS |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Custom logger for YOURLS that logs debug messages and queries. 5 * 6 * Based on \Aura\Sql\Profiler\MemoryLogger 7 * 8 * @since 1.7.10 9 */ 10 11 namespace YOURLS\Database; 12 13 use Psr\Log\AbstractLogger; 14 15 class Logger extends AbstractLogger { 16 /** 17 * Log messages. 18 * 19 * @var array 20 */ 21 protected $messages = []; 22 23 /** 24 * Logs a message. 25 * 26 * @param string $level The log level (ie type of message) 27 * @param string $message The log message. 28 * @param array $context Data to interpolate into the message. 29 * 30 * The logger receives the following: 31 * 32 * From yourls_debug("something went wrong") : 33 * $level : string 'debug' 34 * $message : string 'something went wrong' 35 * $context : array() 36 * See yourls_debug() in includes/functions-debug.php 37 * 38 * From a query that triggers the internal logging of Aura SQL : 39 * $level : string 'query' 40 * $message : string '{function} ({duration} seconds): {statement} {backtrace}' 41 * (which is the default $logFormat from Aura\Sql\Profiler\Profiler), we're not using it) 42 * $context : array( 43 * 'function' => string 'perform' 44 * 'duration' => float 0.0025360584259033 45 * 'statement' => string 'SELECT `keyword`,`url` FROM `yourls_url` WHERE `url` LIKE (:url)' 46 * 'values' => array('url' => '%rss%') 47 * ) 48 * See finish() in Aura\Sql\Profiler\Profiler 49 * 50 * @return void 51 */ 52 public function log($level, string|\Stringable $message, array $context = []): void { 53 // if it's an internal SQL query, format the message, otherwise store a string 54 if($level === 'query') { 55 // Get the real function name that called the query (not just "perform") 56 $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 6); 57 // We should have at index 5 "fetchSomething" (eg fetchAll, fetchOne, etc), otherwise make it "perform" 58 $function = $backtrace[5]['function'] ?? 'perform'; 59 $context['function'] = str_starts_with($function, 'fetch') ? $function : 'perform'; 60 $this->messages[] = sprintf( 61 'SQL %s: %s (%s s)', 62 $context['function'], 63 $this->pretty_format($context['statement'], $context['values']), 64 number_format($context['duration'], 5) 65 ); 66 } else { 67 $this->messages[] = (string)$message; 68 } 69 } 70 71 /** 72 * Returns the logged messages. 73 * 74 * @return array 75 */ 76 public function getMessages() { 77 return $this->messages; 78 } 79 80 /** 81 * Format PDO statement with bind/values replacement 82 * 83 * This replaces PDO binds such as 'key_name = :name' with corresponding array values, eg array('name'=>'some value') 84 * This is merely a cosmetic replacement to allow for readability: the result WILL NOT be valid SQL! (eg no proper quotes) 85 * 86 * @since 1.7.3 87 * @param string $statement SQL query with PDO style named placeholders 88 * @param array $values Optional array of values corresponding to placeholders 89 * @return string Readable SQL query with placeholders replaced 90 */ 91 public function pretty_format($statement, array $values = array() ) { 92 if (!$values) { 93 return $statement; 94 } 95 96 return preg_replace_callback( 97 '/:([^\s;)]*)/', 98 99 /** 100 * @param string $matches 101 */ 102 function ($matches) use ($values) { 103 $replacement = isset( $values[$matches[1]] ) ? $values[$matches[1]] : ''; 104 if(is_array($replacement)) { 105 $replacement = implode(",", $replacement); 106 } 107 return "'$replacement'"; 108 }, 109 $statement 110 ); 111 } 112 113 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Sat Aug 8 05:10:51 2026 | Cross-referenced by PHPXref 0.7.1 |