From c27d66307c2d395a5e071d2b9c1d8665f6dc952d Mon Sep 17 00:00:00 2001 From: Dries Buytaert Date: Thu, 15 Apr 2010 11:53:26 +0000 Subject: - Patch #770838 by sdboyer: optimize DatabaseConnection::ExpandArguments. --- includes/database/database.inc | 57 ++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 30 deletions(-) (limited to 'includes/database') diff --git a/includes/database/database.inc b/includes/database/database.inc index 20a312886..91547a5b8 100644 --- a/includes/database/database.inc +++ b/includes/database/database.inc @@ -213,7 +213,7 @@ abstract class DatabaseConnection extends PDO { /** * Index of what driver-specific class to use for various operations. - * + * * @var array */ protected $driverClasses = array(); @@ -592,36 +592,33 @@ abstract class DatabaseConnection extends PDO { protected function expandArguments(&$query, &$args) { $modified = FALSE; - foreach ($args as $key => $data) { - // If the placeholder value to insert is an array, assume that we need - // to expand it out into a comma-delimited set of placeholders. - if (is_array($data)) { - $new_keys = array(); - foreach ($data as $i => $value) { - // This assumes that there are no other placeholders that use the same - // name. For example, if the array placeholder is defined as :example - // and there is already an :example_2 placeholder, this will generate - // a duplicate key. We do not account for that as the calling code - // is already broken if that happens. - $new_keys[$key . '_' . $i] = $value; - } - - // Update the query with the new placeholders. - // preg_replace is a little bit slower than str_replace, but it is - // necessary to ensure the replacement does not affect placeholders - // that start with the same exact text. For example, if the query - // contains the placeholders :foo and :foobar, and :foo has an array - // of values, using str_replace would affect both placeholders, but - // using the following preg_replace would only affect :foo because it - // is followed by a non-word character. - $query = preg_replace('#' . $key . '\b#', implode(', ', array_keys($new_keys)), $query); - - // Update the args array with the new placeholders. - unset($args[$key]); - $args += $new_keys; - - $modified = TRUE; + // If the placeholder value to insert is an array, assume that we need + // to expand it out into a comma-delimited set of placeholders. + foreach (array_filter($args, 'is_array') as $key => $data) { + $new_keys = array(); + foreach ($data as $i => $value) { + // This assumes that there are no other placeholders that use the same + // name. For example, if the array placeholder is defined as :example + // and there is already an :example_2 placeholder, this will generate + // a duplicate key. We do not account for that as the calling code + // is already broken if that happens. + $new_keys[$key . '_' . $i] = $value; } + + // Update the query with the new placeholders. + // preg_replace is necessary to ensure the replacement does not affect + // placeholders that start with the same exact text. For example, if the + // query contains the placeholders :foo and :foobar, and :foo has an + // array of values, using str_replace would affect both placeholders, + // but using the following preg_replace would only affect :foo because + // it is followed by a non-word character. + $query = preg_replace('#' . $key . '\b#', implode(', ', array_keys($new_keys)), $query); + + // Update the args array with the new placeholders. + unset($args[$key]); + $args += $new_keys; + + $modified = TRUE; } return $modified; -- cgit v1.2.3