1 | <?php |
||
2 | |||
3 | /** |
||
4 | * @package toolkit |
||
5 | */ |
||
6 | |||
7 | /** |
||
8 | * The DatabaseException class extends a normal Exception to add in |
||
9 | * debugging information when a SQL query fails such as the internal |
||
10 | * database error code and message in additional to the usual |
||
11 | * Exception information. It allows a DatabaseException to contain a human |
||
12 | * readable error, as well more technical information for debugging. |
||
13 | */ |
||
14 | class DatabaseException extends Exception |
||
15 | { |
||
16 | /** |
||
17 | * An associative array with three keys, 'query', 'msg' and 'num' |
||
18 | * @var array |
||
19 | */ |
||
20 | private $_error = array(); |
||
21 | |||
22 | /** |
||
23 | * Constructor takes a message and an associative array to set to |
||
24 | * `$_error`. The message is passed to the default Exception constructor |
||
25 | */ |
||
26 | public function __construct($message, array $error = null) |
||
0 ignored issues
–
show
Coding Style
introduced
by
![]() |
|||
27 | { |
||
28 | parent::__construct($message); |
||
29 | $this->_error = $error; |
||
30 | } |
||
31 | |||
32 | /** |
||
33 | * Accessor function for the original query that caused this Exception |
||
34 | * |
||
35 | * @return string |
||
36 | */ |
||
37 | public function getQuery() |
||
38 | { |
||
39 | return $this->_error['query']; |
||
40 | } |
||
41 | |||
42 | /** |
||
43 | * Accessor function for the Database error code for this type of error |
||
44 | * |
||
45 | * @return integer |
||
46 | */ |
||
47 | public function getDatabaseErrorCode() |
||
48 | { |
||
49 | return $this->_error['num']; |
||
50 | } |
||
51 | |||
52 | /** |
||
53 | * Accessor function for the Database message from this Exception |
||
54 | * |
||
55 | * @return string |
||
56 | */ |
||
57 | public function getDatabaseErrorMessage() |
||
58 | { |
||
59 | return $this->_error['msg']; |
||
60 | } |
||
61 | } |
||
62 | |||
63 | /** |
||
64 | * The MySQL class acts as a wrapper for connecting to the Database |
||
65 | * in Symphony. It utilises mysqli_* functions in PHP to complete the usual |
||
66 | * querying. As well as the normal set of insert, update, delete and query |
||
67 | * functions, some convenience functions are provided to return results |
||
68 | * in different ways. Symphony uses a prefix to namespace it's tables in a |
||
69 | * database, allowing it play nice with other applications installed on the |
||
70 | * database. An errors that occur during a query throw a `DatabaseException`. |
||
71 | * By default, Symphony logs all queries to be used for Profiling and Debug |
||
72 | * devkit extensions when a Developer is logged in. When a developer is not |
||
73 | * logged in, all queries and errors are made available with delegates. |
||
74 | */ |
||
75 | class MySQL |
||
76 | { |
||
77 | /** |
||
78 | * Constant to indicate whether the query is a write operation. |
||
79 | * |
||
80 | * @var integer |
||
81 | */ |
||
82 | const __WRITE_OPERATION__ = 0; |
||
83 | |||
84 | /** |
||
85 | * Constant to indicate whether the query is a write operation |
||
86 | * |
||
87 | * @var integer |
||
88 | */ |
||
89 | const __READ_OPERATION__ = 1; |
||
90 | |||
91 | /** |
||
92 | * Sets the current `$_log` to be an empty array |
||
93 | * |
||
94 | * @var array |
||
95 | */ |
||
96 | private static $_log = array(); |
||
97 | |||
98 | /** |
||
99 | * The number of queries this class has executed, defaults to 0. |
||
100 | * |
||
101 | * @var integer |
||
102 | */ |
||
103 | private static $_query_count = 0; |
||
104 | |||
105 | /** |
||
106 | * Whether query caching is enabled or not. By default this is set |
||
107 | * to true which will use SQL_CACHE to cache the results of queries |
||
108 | * |
||
109 | * @var boolean |
||
110 | */ |
||
111 | private static $_cache = true; |
||
112 | |||
113 | /** |
||
114 | * Whether query logging is enabled or not. By default this is set |
||
115 | * to true, which allows profiling of queries |
||
116 | * |
||
117 | * @var boolean |
||
118 | */ |
||
119 | private static $_logging = true; |
||
120 | |||
121 | /** |
||
122 | * An associative array of connection properties for this MySQL |
||
123 | * database including the host, port, username, password and |
||
124 | * selected database. |
||
125 | * |
||
126 | * @var array |
||
127 | */ |
||
128 | private static $_connection = array(); |
||
129 | |||
130 | /** |
||
131 | * The resource of the last result returned from mysqli_query |
||
132 | * |
||
133 | * @var resource |
||
134 | */ |
||
135 | private $_result = null; |
||
136 | |||
137 | /** |
||
138 | * The last query that was executed by the class |
||
139 | */ |
||
140 | private $_lastQuery = null; |
||
141 | |||
142 | /** |
||
143 | * The hash value of the last query that was executed by the class |
||
144 | */ |
||
145 | private $_lastQueryHash = null; |
||
146 | |||
147 | /** |
||
148 | * The auto increment value returned by the last query that was executed |
||
149 | * by the class |
||
150 | */ |
||
151 | private $_lastInsertID = null; |
||
152 | |||
153 | /** |
||
154 | * By default, an array of arrays or objects representing the result set |
||
155 | * from the `$this->_lastQuery` |
||
156 | */ |
||
157 | private $_lastResult = array(); |
||
158 | |||
159 | /** |
||
160 | * Magic function that will flush the MySQL log and close the MySQL |
||
161 | * connection when the MySQL class is removed or destroyed. |
||
162 | * |
||
163 | * @link http://php.net/manual/en/language.oop5.decon.php |
||
164 | */ |
||
165 | public function __destruct() |
||
166 | { |
||
167 | $this->flush(); |
||
168 | $this->close(); |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * Resets the result, `$this->_lastResult` and `$this->_lastQuery` to their empty |
||
173 | * values. Called on each query and when the class is destroyed. |
||
174 | */ |
||
175 | public function flush() |
||
176 | { |
||
177 | $this->_result = null; |
||
178 | $this->_lastResult = array(); |
||
179 | $this->_lastQuery = null; |
||
180 | $this->_lastQueryHash = null; |
||
181 | } |
||
182 | |||
183 | /** |
||
184 | * Sets the current `$_log` to be an empty array |
||
185 | */ |
||
186 | public static function flushLog() |
||
187 | { |
||
188 | self::$_log = array(); |
||
189 | } |
||
190 | |||
191 | /** |
||
192 | * Returns the number of queries that has been executed |
||
193 | * |
||
194 | * @return integer |
||
195 | */ |
||
196 | public static function queryCount() |
||
197 | { |
||
198 | return self::$_query_count; |
||
199 | } |
||
200 | |||
201 | /** |
||
202 | * Sets query caching to true, this will prepend all READ_OPERATION |
||
203 | * queries with SQL_CACHE. Symphony by default enables caching. It |
||
204 | * can be turned off by setting the `query_cache` parameter to `off` in the |
||
205 | * Symphony config file. |
||
206 | * |
||
207 | * @link http://dev.mysql.com/doc/refman/5.1/en/query-cache.html |
||
208 | */ |
||
209 | public static function enableCaching() |
||
210 | { |
||
211 | self::$_cache = true; |
||
212 | } |
||
213 | |||
214 | /** |
||
215 | * Sets query caching to false, this will prepend all READ_OPERATION |
||
216 | * queries will SQL_NO_CACHE. |
||
217 | */ |
||
218 | public static function disableCaching() |
||
219 | { |
||
220 | self::$_cache = false; |
||
221 | } |
||
222 | |||
223 | /** |
||
224 | * Returns boolean if query caching is enabled or not |
||
225 | * |
||
226 | * @return boolean |
||
227 | */ |
||
228 | public static function isCachingEnabled() |
||
229 | { |
||
230 | return self::$_cache; |
||
231 | } |
||
232 | |||
233 | /** |
||
234 | * Enables query logging and profiling. |
||
235 | * |
||
236 | * @since Symphony 2.6.2 |
||
237 | */ |
||
238 | public static function enableLogging() |
||
239 | { |
||
240 | self::$_logging = true; |
||
241 | } |
||
242 | |||
243 | /** |
||
244 | * Disables query logging and profiling. Use this in low memory environments |
||
245 | * to reduce memory usage. |
||
246 | * |
||
247 | * @since Symphony 2.6.2 |
||
248 | * @link https://github.com/symphonycms/symphony-2/issues/2398 |
||
249 | */ |
||
250 | public static function disableLogging() |
||
251 | { |
||
252 | self::$_logging = false; |
||
253 | } |
||
254 | |||
255 | /** |
||
256 | * Returns boolean if logging is enabled or not |
||
257 | * |
||
258 | * @since Symphony 2.6.2 |
||
259 | * @return boolean |
||
260 | */ |
||
261 | public static function isLoggingEnabled() |
||
262 | { |
||
263 | return self::$_logging; |
||
264 | } |
||
265 | |||
266 | /** |
||
267 | * Symphony uses a prefix for all it's database tables so it can live peacefully |
||
268 | * on the same database as other applications. By default this is `sym_`, but it |
||
269 | * can be changed when Symphony is installed. |
||
270 | * |
||
271 | * @param string $prefix |
||
272 | * The table prefix for Symphony, by default this is `sym_` |
||
273 | */ |
||
274 | public function setPrefix($prefix) |
||
275 | { |
||
276 | self::$_connection['tbl_prefix'] = $prefix; |
||
277 | } |
||
278 | |||
279 | /** |
||
280 | * Returns the prefix used by Symphony for this Database instance. |
||
281 | * |
||
282 | * @since Symphony 2.4 |
||
283 | * @return string |
||
284 | */ |
||
285 | public function getPrefix() |
||
286 | { |
||
287 | return self::$_connection['tbl_prefix']; |
||
288 | } |
||
289 | |||
290 | /** |
||
291 | * Determines if a connection has been made to the MySQL server |
||
292 | * |
||
293 | * @return boolean |
||
294 | */ |
||
295 | public static function isConnected() |
||
296 | { |
||
297 | try { |
||
298 | $connected = ( |
||
299 | isset(self::$_connection['id']) |
||
300 | && !is_null(self::$_connection['id']) |
||
301 | ); |
||
302 | } catch (Exception $ex) { |
||
303 | return false; |
||
304 | } |
||
305 | |||
306 | return $connected; |
||
307 | } |
||
308 | |||
309 | /** |
||
310 | * Called when the script has finished executing, this closes the MySQL |
||
311 | * connection |
||
312 | * |
||
313 | * @return boolean |
||
314 | */ |
||
315 | public function close() |
||
316 | { |
||
317 | if ($this->isConnected()) { |
||
318 | return mysqli_close(self::$_connection['id']); |
||
319 | } |
||
320 | } |
||
321 | |||
322 | /** |
||
323 | * Creates a connect to the database server given the credentials. If an |
||
324 | * error occurs, a `DatabaseException` is thrown, otherwise true is returned |
||
325 | * |
||
326 | * @param string $host |
||
327 | * Defaults to null, which MySQL assumes as localhost. |
||
328 | * @param string $user |
||
329 | * Defaults to null |
||
330 | * @param string $password |
||
331 | * Defaults to null |
||
332 | * @param string $port |
||
333 | * Defaults to 3306. |
||
334 | * @param null $database |
||
0 ignored issues
–
show
|
|||
335 | * @throws DatabaseException |
||
336 | * @return boolean |
||
337 | */ |
||
338 | public function connect($host = null, $user = null, $password = null, $port = '3306', $database = null) |
||
0 ignored issues
–
show
|
|||
339 | { |
||
340 | self::$_connection = array( |
||
341 | 'host' => $host, |
||
342 | 'user' => $user, |
||
343 | 'pass' => $password, |
||
344 | 'port' => $port, |
||
345 | 'database' => $database |
||
346 | ); |
||
347 | |||
348 | try { |
||
349 | self::$_connection['id'] = mysqli_connect( |
||
350 | self::$_connection['host'], |
||
351 | self::$_connection['user'], |
||
352 | self::$_connection['pass'], |
||
353 | self::$_connection['database'], |
||
354 | self::$_connection['port'] |
||
355 | ); |
||
356 | |||
357 | if (!$this->isConnected()) { |
||
358 | $this->__error('connect'); |
||
359 | } |
||
360 | } catch (Exception $ex) { |
||
361 | $this->__error('connect'); |
||
362 | } |
||
363 | |||
364 | return true; |
||
365 | } |
||
366 | |||
367 | /** |
||
368 | * Accessor for the current MySQL resource from PHP. May be |
||
369 | * useful for developers who want complete control over their |
||
370 | * database queries and don't want anything abstract by the MySQL |
||
371 | * class. |
||
372 | * |
||
373 | * @return resource |
||
374 | */ |
||
375 | public static function getConnectionResource() |
||
376 | { |
||
377 | return self::$_connection['id']; |
||
378 | } |
||
379 | |||
380 | /** |
||
381 | * This will set the character encoding of the connection for sending and |
||
382 | * receiving data. This function will run every time the database class |
||
383 | * is being initialized. If no character encoding is provided, UTF-8 |
||
384 | * is assumed. |
||
385 | * |
||
386 | * @link http://au2.php.net/manual/en/function.mysql-set-charset.php |
||
387 | * @param string $set |
||
388 | * The character encoding to use, by default this 'utf8' |
||
389 | */ |
||
390 | public function setCharacterEncoding($set = 'utf8') |
||
0 ignored issues
–
show
|
|||
391 | { |
||
392 | mysqli_set_charset(self::$_connection['id'], $set); |
||
393 | } |
||
394 | |||
395 | /** |
||
396 | * This function will set the character encoding of the database so that any |
||
397 | * new tables that are created by Symphony use this character encoding |
||
398 | * |
||
399 | * @link http://dev.mysql.com/doc/refman/5.0/en/charset-connection.html |
||
400 | * @param string $set |
||
401 | * The character encoding to use, by default this 'utf8' |
||
402 | * @throws DatabaseException |
||
403 | */ |
||
404 | public function setCharacterSet($set = 'utf8') |
||
0 ignored issues
–
show
|
|||
405 | { |
||
406 | $this->query("SET character_set_connection = '$set', character_set_database = '$set', character_set_server = '$set'"); |
||
0 ignored issues
–
show
As per coding-style, please use concatenation or
sprintf for the variable $set instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
![]() |
|||
407 | $this->query("SET CHARACTER SET '$set'"); |
||
0 ignored issues
–
show
As per coding-style, please use concatenation or
sprintf for the variable $set instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
![]() |
|||
408 | } |
||
409 | |||
410 | /** |
||
411 | * Sets the MySQL connection to use this timezone instead of the default |
||
412 | * MySQL server timezone. |
||
413 | * |
||
414 | * @throws DatabaseException |
||
415 | * @link https://dev.mysql.com/doc/refman/5.6/en/time-zone-support.html |
||
416 | * @link https://github.com/symphonycms/symphony-2/issues/1726 |
||
417 | * @since Symphony 2.3.3 |
||
418 | * @param string $timezone |
||
419 | * Timezone will human readable, such as Australia/Brisbane. |
||
420 | */ |
||
421 | public function setTimeZone($timezone = null) |
||
0 ignored issues
–
show
|
|||
422 | { |
||
423 | if (is_null($timezone)) { |
||
424 | return; |
||
425 | } |
||
426 | |||
427 | // What is the time now in the install timezone |
||
428 | $symphony_date = new DateTime('now', new DateTimeZone($timezone)); |
||
429 | |||
430 | // MySQL wants the offset to be in the format +/-H:I, getOffset returns offset in seconds |
||
431 | $utc = new DateTime('now ' . $symphony_date->getOffset() . ' seconds', new DateTimeZone("UTC")); |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
The string literal
UTC does not require double quotes, as per coding-style, please use single quotes.
PHP provides two ways to mark string literals. Either with single quotes String literals in single quotes on the other hand are evaluated very literally and the only two
characters that needs escaping in the literal are the single quote itself ( Double quoted string literals may contain other variables or more complex escape sequences. <?php
$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";
print $doubleQuoted;
will print an indented: If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear. For more information on PHP string literals and available escape sequences see the PHP core documentation. ![]() |
|||
432 | |||
433 | // Get the difference between the symphony install timezone and UTC |
||
434 | $offset = $symphony_date->diff($utc)->format('%R%H:%I'); |
||
435 | |||
436 | $this->query("SET time_zone = '$offset'"); |
||
0 ignored issues
–
show
As per coding-style, please use concatenation or
sprintf for the variable $offset instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
![]() |
|||
437 | } |
||
438 | |||
439 | /** |
||
440 | * This function will clean a string using the `mysqli_real_escape_string` function |
||
441 | * taking into account the current database character encoding. Note that this |
||
442 | * function does not encode _ or %. If `mysqli_real_escape_string` doesn't exist, |
||
443 | * `addslashes` will be used as a backup option |
||
444 | * |
||
445 | * @param string $value |
||
446 | * The string to be encoded into an escaped SQL string |
||
447 | * @return string |
||
448 | * The escaped SQL string |
||
449 | */ |
||
450 | public static function cleanValue($value) |
||
451 | { |
||
452 | if (function_exists('mysqli_real_escape_string') && self::isConnected()) { |
||
453 | return mysqli_real_escape_string(self::$_connection['id'], $value); |
||
454 | } else { |
||
455 | return addslashes($value); |
||
456 | } |
||
457 | } |
||
458 | |||
459 | /** |
||
460 | * This function will apply the `cleanValue` function to an associative |
||
461 | * array of data, encoding only the value, not the key. This function |
||
462 | * can handle recursive arrays. This function manipulates the given |
||
463 | * parameter by reference. |
||
464 | * |
||
465 | * @see cleanValue |
||
466 | * @param array $array |
||
467 | * The associative array of data to encode, this parameter is manipulated |
||
468 | * by reference. |
||
469 | */ |
||
470 | public static function cleanFields(array &$array) |
||
471 | { |
||
472 | foreach ($array as $key => $val) { |
||
0 ignored issues
–
show
|
|||
473 | |||
474 | // Handle arrays with more than 1 level |
||
475 | if (is_array($val)) { |
||
476 | self::cleanFields($val); |
||
477 | continue; |
||
478 | } elseif (strlen($val) == 0) { |
||
479 | $array[$key] = 'null'; |
||
480 | } else { |
||
481 | $array[$key] = "'" . self::cleanValue($val) . "'"; |
||
482 | } |
||
483 | } |
||
484 | } |
||
485 | |||
486 | /** |
||
487 | * Determines whether this query is a read operation, or if it is a write operation. |
||
488 | * A write operation is determined as any query that starts with CREATE, INSERT, |
||
489 | * REPLACE, ALTER, DELETE, UPDATE, OPTIMIZE, TRUNCATE or DROP. Anything else is |
||
490 | * considered to be a read operation which are subject to query caching. |
||
491 | * |
||
492 | * @param string $query |
||
493 | * @return integer |
||
494 | * `self::__WRITE_OPERATION__` or `self::__READ_OPERATION__` |
||
495 | */ |
||
496 | public function determineQueryType($query) |
||
497 | { |
||
498 | return (preg_match('/^(create|insert|replace|alter|delete|update|optimize|truncate|drop)/i', $query) ? self::__WRITE_OPERATION__ : self::__READ_OPERATION__); |
||
499 | } |
||
500 | |||
501 | /** |
||
502 | * Takes an SQL string and executes it. This function will apply query |
||
503 | * caching if it is a read operation and if query caching is set. Symphony |
||
504 | * will convert the `tbl_` prefix of tables to be the one set during installation. |
||
505 | * A type parameter is provided to specify whether `$this->_lastResult` will be an array |
||
506 | * of objects or an array of associative arrays. The default is objects. This |
||
507 | * function will return boolean, but set `$this->_lastResult` to the result. |
||
508 | * |
||
509 | * @uses PostQueryExecution |
||
510 | * @param string $query |
||
511 | * The full SQL query to execute. |
||
512 | * @param string $type |
||
513 | * Whether to return the result as objects or associative array. Defaults |
||
514 | * to OBJECT which will return objects. The other option is ASSOC. If $type |
||
515 | * is not either of these, it will return objects. |
||
516 | * @throws DatabaseException |
||
517 | * @return boolean |
||
518 | * true if the query executed without errors, false otherwise |
||
519 | */ |
||
520 | public function query($query, $type = "OBJECT") |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
The string literal
OBJECT does not require double quotes, as per coding-style, please use single quotes.
PHP provides two ways to mark string literals. Either with single quotes String literals in single quotes on the other hand are evaluated very literally and the only two
characters that needs escaping in the literal are the single quote itself ( Double quoted string literals may contain other variables or more complex escape sequences. <?php
$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";
print $doubleQuoted;
will print an indented: If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear. For more information on PHP string literals and available escape sequences see the PHP core documentation. ![]() |
|||
521 | { |
||
522 | if (empty($query) || self::isConnected() === false) { |
||
523 | return false; |
||
524 | } |
||
525 | |||
526 | $start = precision_timer(); |
||
527 | $query = trim($query); |
||
528 | $query_type = $this->determineQueryType($query); |
||
529 | $query_hash = md5($query.$start); |
||
530 | |||
531 | if (self::$_connection['tbl_prefix'] !== 'tbl_') { |
||
532 | $query = preg_replace('/tbl_(\S+?)([\s\.,]|$)/', self::$_connection['tbl_prefix'].'\\1\\2', $query); |
||
533 | } |
||
534 | |||
535 | // TYPE is deprecated since MySQL 4.0.18, ENGINE is preferred |
||
536 | if ($query_type == self::__WRITE_OPERATION__) { |
||
537 | $query = preg_replace('/TYPE=(MyISAM|InnoDB)/i', 'ENGINE=$1', $query); |
||
538 | } elseif ($query_type == self::__READ_OPERATION__ && !preg_match('/^SELECT\s+SQL(_NO)?_CACHE/i', $query)) { |
||
539 | if ($this->isCachingEnabled()) { |
||
540 | $query = preg_replace('/^SELECT\s+/i', 'SELECT SQL_CACHE ', $query); |
||
541 | } else { |
||
542 | $query = preg_replace('/^SELECT\s+/i', 'SELECT SQL_NO_CACHE ', $query); |
||
543 | } |
||
544 | } |
||
545 | |||
546 | $this->flush(); |
||
547 | $this->_lastQuery = $query; |
||
548 | $this->_lastQueryHash = $query_hash; |
||
549 | $this->_result = mysqli_query(self::$_connection['id'], $query); |
||
0 ignored issues
–
show
It seems like
mysqli_query(self::_connection['id'], $query) of type boolean or mysqli_result is incompatible with the declared type resource of property $_result .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
550 | $this->_lastInsertID = mysqli_insert_id(self::$_connection['id']); |
||
551 | self::$_query_count++; |
||
552 | |||
553 | if (mysqli_error(self::$_connection['id'])) { |
||
554 | $this->__error(); |
||
555 | } elseif (($this->_result instanceof mysqli_result)) { |
||
556 | if ($type == "ASSOC") { |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
The string literal
ASSOC does not require double quotes, as per coding-style, please use single quotes.
PHP provides two ways to mark string literals. Either with single quotes String literals in single quotes on the other hand are evaluated very literally and the only two
characters that needs escaping in the literal are the single quote itself ( Double quoted string literals may contain other variables or more complex escape sequences. <?php
$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";
print $doubleQuoted;
will print an indented: If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear. For more information on PHP string literals and available escape sequences see the PHP core documentation. ![]() |
|||
557 | while ($row = mysqli_fetch_assoc($this->_result)) { |
||
558 | $this->_lastResult[] = $row; |
||
559 | } |
||
560 | } else { |
||
561 | while ($row = mysqli_fetch_object($this->_result)) { |
||
562 | $this->_lastResult[] = $row; |
||
563 | } |
||
564 | } |
||
565 | |||
566 | mysqli_free_result($this->_result); |
||
567 | } |
||
568 | |||
569 | $stop = precision_timer('stop', $start); |
||
570 | |||
571 | /** |
||
572 | * After a query has successfully executed, that is it was considered |
||
573 | * valid SQL, this delegate will provide the query, the query_hash and |
||
574 | * the execution time of the query. |
||
575 | * |
||
576 | * Note that this function only starts logging once the ExtensionManager |
||
577 | * is available, which means it will not fire for the first couple of |
||
578 | * queries that set the character set. |
||
579 | * |
||
580 | * @since Symphony 2.3 |
||
581 | * @delegate PostQueryExecution |
||
582 | * @param string $context |
||
583 | * '/frontend/' or '/backend/' |
||
584 | * @param string $query |
||
585 | * The query that has just been executed |
||
586 | * @param string $query_hash |
||
587 | * The hash used by Symphony to uniquely identify this query |
||
588 | * @param float $execution_time |
||
589 | * The time that it took to run `$query` |
||
590 | */ |
||
591 | if (self::$_logging === true) { |
||
592 | if (Symphony::ExtensionManager() instanceof ExtensionManager) { |
||
0 ignored issues
–
show
|
|||
593 | Symphony::ExtensionManager()->notifyMembers('PostQueryExecution', class_exists('Administration', false) ? '/backend/' : '/frontend/', array( |
||
594 | 'query' => $query, |
||
595 | 'query_hash' => $query_hash, |
||
596 | 'execution_time' => $stop |
||
597 | )); |
||
598 | |||
599 | // If the ExceptionHandler is enabled, then the user is authenticated |
||
600 | // or we have a serious issue, so log the query. |
||
601 | if (GenericExceptionHandler::$enabled) { |
||
602 | self::$_log[$query_hash] = array( |
||
603 | 'query' => $query, |
||
604 | 'query_hash' => $query_hash, |
||
605 | 'execution_time' => $stop |
||
606 | ); |
||
607 | } |
||
608 | |||
609 | // Symphony isn't ready yet. Log internally |
||
610 | } else { |
||
611 | self::$_log[$query_hash] = array( |
||
612 | 'query' => $query, |
||
613 | 'query_hash' => $query_hash, |
||
614 | 'execution_time' => $stop |
||
615 | ); |
||
616 | } |
||
617 | } |
||
618 | |||
619 | return true; |
||
620 | } |
||
621 | |||
622 | /** |
||
623 | * Returns the last insert ID from the previous query. This is |
||
624 | * the value from an auto_increment field. |
||
625 | * |
||
626 | * @return integer |
||
627 | * The last interested row's ID |
||
628 | */ |
||
629 | public function getInsertID() |
||
630 | { |
||
631 | return $this->_lastInsertID; |
||
632 | } |
||
633 | |||
634 | /** |
||
635 | * A convenience method to insert data into the Database. This function |
||
636 | * takes an associative array of data to input, with the keys being the column |
||
637 | * names and the table. An optional parameter exposes MySQL's ON DUPLICATE |
||
638 | * KEY UPDATE functionality, which will update the values if a duplicate key |
||
639 | * is found. |
||
640 | * |
||
641 | * @param array $fields |
||
642 | * An associative array of data to input, with the key's mapping to the |
||
643 | * column names. Alternatively, an array of associative array's can be |
||
644 | * provided, which will perform multiple inserts |
||
645 | * @param string $table |
||
646 | * The table name, including the tbl prefix which will be changed |
||
647 | * to this Symphony's table prefix in the query function |
||
648 | * @param boolean $updateOnDuplicate |
||
649 | * If set to true, data will updated if any key constraints are found that cause |
||
650 | * conflicts. By default this is set to false, which will not update the data and |
||
651 | * would return an SQL error |
||
652 | * @throws DatabaseException |
||
653 | * @return boolean |
||
654 | */ |
||
655 | public function insert(array $fields, $table, $updateOnDuplicate = false) |
||
0 ignored issues
–
show
|
|||
656 | { |
||
657 | // Multiple Insert |
||
658 | if (is_array(current($fields))) { |
||
659 | $sql = "INSERT INTO `$table` (`".implode('`, `', array_keys(current($fields))).'`) VALUES '; |
||
0 ignored issues
–
show
As per coding-style, please use concatenation or
sprintf for the variable $table instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
![]() |
|||
660 | $rows = array(); |
||
661 | |||
662 | foreach ($fields as $key => $array) { |
||
663 | // Sanity check: Make sure we dont end up with ',()' in the SQL. |
||
664 | if (!is_array($array)) { |
||
665 | continue; |
||
666 | } |
||
667 | |||
668 | self::cleanFields($array); |
||
669 | $rows[] = '('.implode(', ', $array).')'; |
||
670 | } |
||
671 | |||
672 | $sql .= implode(", ", $rows); |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
The string literal
, does not require double quotes, as per coding-style, please use single quotes.
PHP provides two ways to mark string literals. Either with single quotes String literals in single quotes on the other hand are evaluated very literally and the only two
characters that needs escaping in the literal are the single quote itself ( Double quoted string literals may contain other variables or more complex escape sequences. <?php
$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";
print $doubleQuoted;
will print an indented: If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear. For more information on PHP string literals and available escape sequences see the PHP core documentation. ![]() |
|||
673 | |||
674 | // Single Insert |
||
675 | } else { |
||
676 | self::cleanFields($fields); |
||
677 | $sql = "INSERT INTO `$table` (`".implode('`, `', array_keys($fields)).'`) VALUES ('.implode(', ', $fields).')'; |
||
0 ignored issues
–
show
As per coding-style, please use concatenation or
sprintf for the variable $table instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
![]() |
|||
678 | |||
679 | if ($updateOnDuplicate) { |
||
680 | $sql .= ' ON DUPLICATE KEY UPDATE '; |
||
681 | |||
682 | foreach ($fields as $key => $value) { |
||
683 | $sql .= " `$key` = $value,"; |
||
0 ignored issues
–
show
As per coding-style, please use concatenation or
sprintf for the variable $key instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
![]() As per coding-style, please use concatenation or
sprintf for the variable $value instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
![]() |
|||
684 | } |
||
685 | |||
686 | $sql = trim($sql, ','); |
||
687 | } |
||
688 | } |
||
689 | |||
690 | return $this->query($sql); |
||
691 | } |
||
692 | |||
693 | /** |
||
694 | * A convenience method to update data that exists in the Database. This function |
||
695 | * takes an associative array of data to input, with the keys being the column |
||
696 | * names and the table. A WHERE statement can be provided to select the rows |
||
697 | * to update |
||
698 | * |
||
699 | * @param array $fields |
||
700 | * An associative array of data to input, with the key's mapping to the |
||
701 | * column names. |
||
702 | * @param string $table |
||
703 | * The table name, including the tbl prefix which will be changed |
||
704 | * to this Symphony's table prefix in the query function |
||
705 | * @param string $where |
||
706 | * A WHERE statement for this UPDATE statement, defaults to null |
||
707 | * which will update all rows in the $table |
||
708 | * @throws DatabaseException |
||
709 | * @return boolean |
||
710 | */ |
||
711 | public function update($fields, $table, $where = null) |
||
0 ignored issues
–
show
|
|||
712 | { |
||
713 | self::cleanFields($fields); |
||
714 | $sql = "UPDATE $table SET "; |
||
0 ignored issues
–
show
As per coding-style, please use concatenation or
sprintf for the variable $table instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
![]() |
|||
715 | $rows = array(); |
||
716 | |||
717 | foreach ($fields as $key => $val) { |
||
718 | $rows[] = " `$key` = $val"; |
||
0 ignored issues
–
show
As per coding-style, please use concatenation or
sprintf for the variable $key instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
![]() As per coding-style, please use concatenation or
sprintf for the variable $val instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
![]() |
|||
719 | } |
||
720 | |||
721 | $sql .= implode(', ', $rows) . (!is_null($where) ? ' WHERE ' . $where : null); |
||
722 | |||
723 | return $this->query($sql); |
||
724 | } |
||
725 | |||
726 | /** |
||
727 | * Given a table name and a WHERE statement, delete rows from the |
||
728 | * Database. |
||
729 | * |
||
730 | * @param string $table |
||
731 | * The table name, including the tbl prefix which will be changed |
||
732 | * to this Symphony's table prefix in the query function |
||
733 | * @param string $where |
||
734 | * A WHERE statement for this DELETE statement, defaults to null, |
||
735 | * which will delete all rows in the $table |
||
736 | * @throws DatabaseException |
||
737 | * @return boolean |
||
738 | */ |
||
739 | public function delete($table, $where = null) |
||
0 ignored issues
–
show
|
|||
740 | { |
||
741 | $sql = "DELETE FROM `$table`"; |
||
0 ignored issues
–
show
As per coding-style, please use concatenation or
sprintf for the variable $table instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
![]() |
|||
742 | |||
743 | if (!is_null($where)) { |
||
744 | $sql .= " WHERE $where"; |
||
0 ignored issues
–
show
As per coding-style, please use concatenation or
sprintf for the variable $where instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
![]() |
|||
745 | } |
||
746 | |||
747 | return $this->query($sql); |
||
748 | } |
||
749 | |||
750 | /** |
||
751 | * Returns an associative array that contains the results of the |
||
752 | * given `$query`. Optionally, the resulting array can be indexed |
||
753 | * by a particular column. |
||
754 | * |
||
755 | * @param string $query |
||
756 | * The full SQL query to execute. Defaults to null, which will |
||
757 | * use the _lastResult |
||
758 | * @param string $index_by_column |
||
759 | * The name of a column in the table to use it's value to index |
||
760 | * the result by. If this is omitted (and it is by default), an |
||
761 | * array of associative arrays is returned, with the key being the |
||
762 | * column names |
||
763 | * @throws DatabaseException |
||
764 | * @return array |
||
765 | * An associative array with the column names as the keys |
||
766 | */ |
||
767 | public function fetch($query = null, $index_by_column = null) |
||
0 ignored issues
–
show
|
|||
768 | { |
||
769 | if (!is_null($query)) { |
||
770 | $this->query($query, "ASSOC"); |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
The string literal
ASSOC does not require double quotes, as per coding-style, please use single quotes.
PHP provides two ways to mark string literals. Either with single quotes String literals in single quotes on the other hand are evaluated very literally and the only two
characters that needs escaping in the literal are the single quote itself ( Double quoted string literals may contain other variables or more complex escape sequences. <?php
$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";
print $doubleQuoted;
will print an indented: If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear. For more information on PHP string literals and available escape sequences see the PHP core documentation. ![]() |
|||
771 | } elseif (is_null($this->_lastResult)) { |
||
0 ignored issues
–
show
|
|||
772 | return array(); |
||
773 | } |
||
774 | |||
775 | $result = $this->_lastResult; |
||
776 | |||
777 | if (!is_null($index_by_column) && isset($result[0][$index_by_column])) { |
||
778 | $n = array(); |
||
779 | |||
780 | foreach ($result as $ii) { |
||
781 | $n[$ii[$index_by_column]] = $ii; |
||
782 | } |
||
783 | |||
784 | $result = $n; |
||
785 | } |
||
786 | |||
787 | return $result; |
||
788 | } |
||
789 | |||
790 | /** |
||
791 | * Returns the row at the specified index from the given query. If no |
||
792 | * query is given, it will use the `$this->_lastResult`. If no offset is provided, |
||
793 | * the function will return the first row. This function does not imply any |
||
794 | * LIMIT to the given `$query`, so for the more efficient use, it is recommended |
||
795 | * that the `$query` have a LIMIT set. |
||
796 | * |
||
797 | * @param integer $offset |
||
798 | * The row to return from the SQL query. For instance, if the second |
||
799 | * row from the result was required, the offset would be 1, because it |
||
800 | * is zero based. |
||
801 | * @param string $query |
||
802 | * The full SQL query to execute. Defaults to null, which will |
||
803 | * use the `$this->_lastResult` |
||
804 | * @throws DatabaseException |
||
805 | * @return array |
||
806 | * If there is no row at the specified `$offset`, an empty array will be returned |
||
807 | * otherwise an associative array of that row will be returned. |
||
808 | */ |
||
809 | public function fetchRow($offset = 0, $query = null) |
||
0 ignored issues
–
show
|
|||
810 | { |
||
811 | $result = $this->fetch($query); |
||
812 | return (empty($result) ? array() : $result[$offset]); |
||
813 | } |
||
814 | |||
815 | /** |
||
816 | * Returns an array of values for a specified column in a given query. |
||
817 | * If no query is given, it will use the `$this->_lastResult`. |
||
818 | * |
||
819 | * @param string $column |
||
820 | * The column name in the query to return the values for |
||
821 | * @param string $query |
||
822 | * The full SQL query to execute. Defaults to null, which will |
||
823 | * use the `$this->_lastResult` |
||
824 | * @throws DatabaseException |
||
825 | * @return array |
||
826 | * If there is no results for the `$query`, an empty array will be returned |
||
827 | * otherwise an array of values for that given `$column` will be returned |
||
828 | */ |
||
829 | public function fetchCol($column, $query = null) |
||
0 ignored issues
–
show
|
|||
830 | { |
||
831 | $result = $this->fetch($query); |
||
832 | |||
833 | if (empty($result)) { |
||
834 | return array(); |
||
835 | } |
||
836 | |||
837 | $rows = array(); |
||
838 | foreach ($result as $row) { |
||
839 | $rows[] = $row[$column]; |
||
840 | } |
||
841 | |||
842 | return $rows; |
||
843 | } |
||
844 | |||
845 | /** |
||
846 | * Returns the value for a specified column at a specified offset. If no |
||
847 | * offset is provided, it will return the value for column of the first row. |
||
848 | * If no query is given, it will use the `$this->_lastResult`. |
||
849 | * |
||
850 | * @param string $column |
||
851 | * The column name in the query to return the values for |
||
852 | * @param integer $offset |
||
853 | * The row to use to return the value for the given `$column` from the SQL |
||
854 | * query. For instance, if `$column` form the second row was required, the |
||
855 | * offset would be 1, because it is zero based. |
||
856 | * @param string $query |
||
857 | * The full SQL query to execute. Defaults to null, which will |
||
858 | * use the `$this->_lastResult` |
||
859 | * @throws DatabaseException |
||
860 | * @return string|null |
||
861 | * Returns the value of the given column, if it doesn't exist, null will be |
||
862 | * returned |
||
863 | */ |
||
864 | public function fetchVar($column, $offset = 0, $query = null) |
||
0 ignored issues
–
show
|
|||
865 | { |
||
866 | $result = $this->fetch($query); |
||
867 | return (empty($result) ? null : $result[$offset][$column]); |
||
868 | } |
||
869 | |||
870 | /** |
||
871 | * This function takes `$table` and `$field` names and returns boolean |
||
872 | * if the `$table` contains the `$field`. |
||
873 | * |
||
874 | * @since Symphony 2.3 |
||
875 | * @link https://dev.mysql.com/doc/refman/en/describe.html |
||
876 | * @param string $table |
||
877 | * The table name |
||
878 | * @param string $field |
||
879 | * The field name |
||
880 | * @throws DatabaseException |
||
881 | * @return boolean |
||
882 | * true if `$table` contains `$field`, false otherwise |
||
883 | */ |
||
884 | public function tableContainsField($table, $field) |
||
885 | { |
||
886 | $table = MySQL::cleanValue($table); |
||
887 | $field = MySQL::cleanValue($field); |
||
888 | $results = $this->fetch("DESC `{$table}` `{$field}`"); |
||
0 ignored issues
–
show
As per coding-style, please use concatenation or
sprintf for the variable $table instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
![]() As per coding-style, please use concatenation or
sprintf for the variable $field instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
![]() |
|||
889 | return (is_array($results) && !empty($results)); |
||
890 | } |
||
891 | |||
892 | /** |
||
893 | * This function takes `$table` and returns boolean |
||
894 | * if it exists or not. |
||
895 | * |
||
896 | * @since Symphony 2.3.4 |
||
897 | * @link https://dev.mysql.com/doc/refman/en/show-tables.html |
||
898 | * @param string $table |
||
899 | * The table name |
||
900 | * @throws DatabaseException |
||
901 | * @return boolean |
||
902 | * true if `$table` exists, false otherwise |
||
903 | */ |
||
904 | public function tableExists($table) |
||
905 | { |
||
906 | $table = MySQL::cleanValue($table); |
||
907 | $results = $this->fetch(sprintf("SHOW TABLES LIKE '%s'", $table)); |
||
908 | return (is_array($results) && !empty($results)); |
||
909 | } |
||
910 | |||
911 | /** |
||
912 | * If an error occurs in a query, this function is called which logs |
||
913 | * the last query and the error number and error message from MySQL |
||
914 | * before throwing a `DatabaseException` |
||
915 | * |
||
916 | * @uses QueryExecutionError |
||
917 | * @throws DatabaseException |
||
918 | * @param string $type |
||
919 | * Accepts one parameter, 'connect', which will return the correct |
||
920 | * error codes when the connection sequence fails |
||
921 | */ |
||
922 | private function __error($type = null) |
||
0 ignored issues
–
show
|
|||
923 | { |
||
924 | if ($type == 'connect') { |
||
925 | $msg = mysqli_connect_error(); |
||
926 | $errornum = mysqli_connect_errno(); |
||
927 | } else { |
||
928 | $msg = mysqli_error(self::$_connection['id']); |
||
929 | $errornum = mysqli_errno(self::$_connection['id']); |
||
930 | } |
||
931 | |||
932 | /** |
||
933 | * After a query execution has failed this delegate will provide the query, |
||
934 | * query hash, error message and the error number. |
||
935 | * |
||
936 | * Note that this function only starts logging once the `ExtensionManager` |
||
937 | * is available, which means it will not fire for the first couple of |
||
938 | * queries that set the character set. |
||
939 | * |
||
940 | * @since Symphony 2.3 |
||
941 | * @delegate QueryExecutionError |
||
942 | * @param string $context |
||
943 | * '/frontend/' or '/backend/' |
||
944 | * @param string $query |
||
945 | * The query that has just been executed |
||
946 | * @param string $query_hash |
||
947 | * The hash used by Symphony to uniquely identify this query |
||
948 | * @param string $msg |
||
949 | * The error message provided by MySQL which includes information on why the execution failed |
||
950 | * @param integer $num |
||
951 | * The error number that corresponds with the MySQL error message |
||
952 | */ |
||
953 | if (self::$_logging === true) { |
||
954 | if (Symphony::ExtensionManager() instanceof ExtensionManager) { |
||
0 ignored issues
–
show
|
|||
955 | Symphony::ExtensionManager()->notifyMembers('QueryExecutionError', class_exists('Administration', false) ? '/backend/' : '/frontend/', array( |
||
956 | 'query' => $this->_lastQuery, |
||
957 | 'query_hash' => $this->_lastQueryHash, |
||
958 | 'msg' => $msg, |
||
959 | 'num' => $errornum |
||
960 | )); |
||
961 | } |
||
962 | } |
||
963 | |||
964 | throw new DatabaseException(__('MySQL Error (%1$s): %2$s in query: %3$s', array($errornum, $msg, $this->_lastQuery)), array( |
||
965 | 'msg' => $msg, |
||
966 | 'num' => $errornum, |
||
967 | 'query' => $this->_lastQuery |
||
968 | )); |
||
969 | } |
||
970 | |||
971 | /** |
||
972 | * Returns all the log entries by type. There are two valid types, |
||
973 | * error and debug. If no type is given, the entire log is returned, |
||
974 | * otherwise only log messages for that type are returned |
||
975 | * |
||
976 | * @param null|string $type |
||
977 | * @return array |
||
978 | * An array of associative array's. Log entries of the error type |
||
979 | * return the query the error occurred on and the error number and |
||
980 | * message from MySQL. Log entries of the debug type return the |
||
981 | * the query and the start/stop time to indicate how long it took |
||
982 | * to run |
||
983 | */ |
||
984 | public function debug($type = null) |
||
0 ignored issues
–
show
|
|||
985 | { |
||
986 | if (!$type) { |
||
987 | return self::$_log; |
||
988 | } |
||
989 | |||
990 | return ($type == 'error' ? self::$_log['error'] : self::$_log['query']); |
||
0 ignored issues
–
show
|
|||
991 | } |
||
992 | |||
993 | /** |
||
994 | * Returns some basic statistics from the MySQL class about the |
||
995 | * number of queries, the time it took to query and any slow queries. |
||
996 | * A slow query is defined as one that took longer than 0.0999 seconds |
||
997 | * This function is used by the Profile devkit |
||
998 | * |
||
999 | * @return array |
||
1000 | * An associative array with the number of queries, an array of slow |
||
1001 | * queries and the total query time. |
||
1002 | */ |
||
1003 | public function getStatistics() |
||
1004 | { |
||
1005 | $query_timer = 0.0; |
||
1006 | $slow_queries = array(); |
||
1007 | |||
1008 | foreach (self::$_log as $key => $val) { |
||
1009 | $query_timer += $val['execution_time']; |
||
1010 | if ($val['execution_time'] > 0.0999) { |
||
1011 | $slow_queries[] = $val; |
||
1012 | } |
||
1013 | } |
||
1014 | |||
1015 | return array( |
||
1016 | 'queries' => self::queryCount(), |
||
1017 | 'slow-queries' => $slow_queries, |
||
1018 | 'total-query-time' => number_format($query_timer, 4, '.', '') |
||
1019 | ); |
||
1020 | } |
||
1021 | |||
1022 | /** |
||
1023 | * Convenience function to allow you to execute multiple SQL queries at once |
||
1024 | * by providing a string with the queries delimited with a `;` |
||
1025 | * |
||
1026 | * @throws DatabaseException |
||
1027 | * @throws Exception |
||
1028 | * @param string $sql |
||
1029 | * A string containing SQL queries delimited by `;` |
||
1030 | * @param boolean $force_engine |
||
1031 | * If set to true, this will set MySQL's default storage engine to MyISAM. |
||
1032 | * Defaults to false, which will use MySQL's default storage engine when |
||
1033 | * tables don't explicitly define which engine they should be created with |
||
1034 | * @return boolean |
||
1035 | * If one of the queries fails, false will be returned and no further queries |
||
1036 | * will be executed, otherwise true will be returned. |
||
1037 | */ |
||
1038 | public function import($sql, $force_engine = false) |
||
0 ignored issues
–
show
|
|||
1039 | { |
||
1040 | if ($force_engine) { |
||
1041 | // Silently attempt to change the storage engine. This prevents INNOdb errors. |
||
1042 | $this->query('SET default_storage_engine = MYISAM'); |
||
1043 | } |
||
1044 | |||
1045 | $queries = preg_split('/;[\\r\\n]+/', $sql, -1, PREG_SPLIT_NO_EMPTY); |
||
1046 | |||
1047 | if (!is_array($queries) || empty($queries) || count($queries) <= 0) { |
||
1048 | throw new Exception('The SQL string contains no queries.'); |
||
1049 | } |
||
1050 | |||
1051 | foreach ($queries as $sql) { |
||
0 ignored issues
–
show
|
|||
1052 | if (trim($sql) !== '') { |
||
1053 | $result = $this->query($sql); |
||
1054 | } |
||
1055 | |||
1056 | if (!$result) { |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
1057 | return false; |
||
1058 | } |
||
1059 | } |
||
1060 | |||
1061 | return true; |
||
1062 | } |
||
1063 | } |
||
1064 |