]> git.mxchange.org Git - friendica.git/commitdiff
Quickfix for MYSQLi (prepared statement problem)
authorMichael <heluecht@pirati.ca>
Tue, 8 Aug 2017 06:07:04 +0000 (06:07 +0000)
committerMichael <heluecht@pirati.ca>
Tue, 8 Aug 2017 06:07:04 +0000 (06:07 +0000)
include/dba.php

index d921167c1ded9fcfb21f5416666de3c4754edd04..231f5905beb5e1d8e06a4834aea2eb9934c91258 100644 (file)
@@ -547,6 +547,8 @@ class dba {
                $sql = self::$dbo->clean_query($sql);
                $sql = self::$dbo->any_value_fallback($sql);
 
+               $orig_sql = $sql;
+
                if (x($a->config,'system') && x($a->config['system'], 'db_callstack')) {
                        $sql = "/*".$a->callstack()." */ ".$sql;
                }
@@ -555,6 +557,18 @@ class dba {
                self::$dbo->errorno = 0;
                self::$dbo->affected_rows = 0;
 
+               // We have to make some things different if this function is called from "e"
+               $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
+
+               if (isset($trace[2])) {
+                       $called_from = $trace[2];
+               } else {
+                       // We use just something that is defined to avoid warnings
+                       $called_from = $trace[0];
+               }
+               // We are having an own error logging in the function "e"
+               $called_from_e = ($called_from['function'] == 'e');
+
                switch (self::$dbo->driver) {
                        case 'pdo':
                                if (!$stmt = self::$dbo->db->prepare($sql)) {
@@ -580,6 +594,28 @@ class dba {
                                }
                                break;
                        case 'mysqli':
+                               // There are SQL statements that cannot be executed with a prepared statement
+                               $parts = explode(' ', $orig_sql);
+                               $command = strtolower($parts[0]);
+                               $can_be_prepared = in_array($command, array('select', 'update', 'insert', 'delete'));
+
+                               // The fallback routine currently only works with statements that doesn't return values
+                               if (!$can_be_prepared && $called_from_e) {
+                                       $retval = self::$dbo->db->query(self::replace_parameters($sql, $args));
+                                       if (self::$dbo->db->errno) {
+                                               self::$dbo->error = self::$dbo->db->error;
+                                               self::$dbo->errorno = self::$dbo->db->errno;
+                                               $retval = false;
+                                       } else {
+                                               if (isset($retval->num_rows)) {
+                                                       self::$dbo->affected_rows = $retval->num_rows;
+                                               } else {
+                                                       self::$dbo->affected_rows = self::$dbo->db->affected_rows;
+                                               }
+                                       }
+                                       break;
+                               }
+
                                $stmt = self::$dbo->db->stmt_init();
 
                                if (!$stmt->prepare($sql)) {
@@ -637,27 +673,17 @@ class dba {
                                break;
                }
 
-               if (self::$dbo->errorno != 0) {
-                       $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
-
-                       if (isset($trace[2])) {
-                               $called_from = $trace[2];
-                       } else {
-                               // We use just something that is defined to avoid warnings
-                               $called_from = $trace[0];
-                       }
-                       // We are having an own error logging in the function "e"
-                       if ($called_from['function'] != 'e') {
-                               // We have to preserve the error code, somewhere in the logging it get lost
-                               $error = self::$dbo->error;
-                               $errorno = self::$dbo->errorno;
+               // We are having an own error logging in the function "e"
+               if ((self::$dbo->errorno != 0) && !$called_from_e) {
+                       // We have to preserve the error code, somewhere in the logging it get lost
+                       $error = self::$dbo->error;
+                       $errorno = self::$dbo->errorno;
 
-                               logger('DB Error '.self::$dbo->errorno.': '.self::$dbo->error."\n".
-                                       $a->callstack(8)."\n".self::replace_parameters($sql, $params));
+                       logger('DB Error '.self::$dbo->errorno.': '.self::$dbo->error."\n".
+                               $a->callstack(8)."\n".self::replace_parameters($sql, $params));
 
-                               self::$dbo->error = $error;
-                               self::$dbo->errorno = $errorno;
-                       }
+                       self::$dbo->error = $error;
+                       self::$dbo->errorno = $errorno;
                }
 
                $a->save_timestamp($stamp1, 'database');