Merge pull request #3618 from annando/mysqli-fix
Quickfix for MYSQLi (prepared statement problem)
This commit is contained in:
		
				commit
				
					
						4d77c8a90a
					
				
			
		
					 1 changed files with 45 additions and 19 deletions
				
			
		|  | @ -549,6 +549,8 @@ class dba { | ||||||
| 		$sql = self::$dbo->clean_query($sql); | 		$sql = self::$dbo->clean_query($sql); | ||||||
| 		$sql = self::$dbo->any_value_fallback($sql); | 		$sql = self::$dbo->any_value_fallback($sql); | ||||||
| 
 | 
 | ||||||
|  | 		$orig_sql = $sql; | ||||||
|  | 
 | ||||||
| 		if (x($a->config,'system') && x($a->config['system'], 'db_callstack')) { | 		if (x($a->config,'system') && x($a->config['system'], 'db_callstack')) { | ||||||
| 			$sql = "/*".$a->callstack()." */ ".$sql; | 			$sql = "/*".$a->callstack()." */ ".$sql; | ||||||
| 		} | 		} | ||||||
|  | @ -557,6 +559,18 @@ class dba { | ||||||
| 		self::$dbo->errorno = 0; | 		self::$dbo->errorno = 0; | ||||||
| 		self::$dbo->affected_rows = 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) { | 		switch (self::$dbo->driver) { | ||||||
| 			case 'pdo': | 			case 'pdo': | ||||||
| 				if (!$stmt = self::$dbo->db->prepare($sql)) { | 				if (!$stmt = self::$dbo->db->prepare($sql)) { | ||||||
|  | @ -582,6 +596,28 @@ class dba { | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| 			case 'mysqli': | 			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(); | 				$stmt = self::$dbo->db->stmt_init(); | ||||||
| 
 | 
 | ||||||
| 				if (!$stmt->prepare($sql)) { | 				if (!$stmt->prepare($sql)) { | ||||||
|  | @ -639,27 +675,17 @@ class dba { | ||||||
| 				break; | 				break; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (self::$dbo->errorno != 0) { | 		// We are having an own error logging in the function "e"
 | ||||||
| 			$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3); | 		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; | ||||||
| 
 | 
 | ||||||
| 			if (isset($trace[2])) { | 			logger('DB Error '.self::$dbo->errorno.': '.self::$dbo->error."\n". | ||||||
| 				$called_from = $trace[2]; | 				$a->callstack(8)."\n".self::replace_parameters($sql, $params)); | ||||||
| 			} 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; |  | ||||||
| 
 | 
 | ||||||
| 				logger('DB Error '.self::$dbo->errorno.': '.self::$dbo->error."\n". | 			self::$dbo->error = $error; | ||||||
| 					$a->callstack(8)."\n".self::replace_parameters($sql, $params)); | 			self::$dbo->errorno = $errorno; | ||||||
| 
 |  | ||||||
| 				self::$dbo->error = $error; |  | ||||||
| 				self::$dbo->errorno = $errorno; |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		$a->save_timestamp($stamp1, 'database'); | 		$a->save_timestamp($stamp1, 'database'); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue