diff options
Diffstat (limited to 'idiorm.php')
-rw-r--r-- | idiorm.php | 108 |
1 files changed, 107 insertions, 1 deletions
@@ -278,7 +278,11 @@ $query = str_replace("%", "%%", $query); // Replace placeholders in the query for vsprintf - $query = str_replace("?", "%s", $query); + if(false !== strpos($query, "'") || false !== strpos($query, '"')) { + $query = IdiormString::str_replace_outside_quotes("?", "%s", $query); + } else { + $query = str_replace("?", "%s", $query); + } // Replace the question marks in the query with the parameters $bound_query = vsprintf($query, $parameters); @@ -1382,3 +1386,105 @@ } } + /** + * A class to handle str_replace operations that involve quoted strings + * @example IdiormString::str_replace_outside_quotes('?', '%s', 'columnA = "Hello?" AND columnB = ?'); + * @example IdiormString::value('columnA = "Hello?" AND columnB = ?')->replace_outside_quotes('?', '%s'); + * @author Jeff Roberson <[email protected]> + * @author Simon Holywell <[email protected]> + * @link http://stackoverflow.com/a/13370709/461813 StackOverflow answer + */ + class IdiormString { + protected $subject; + protected $search; + protected $replace; + + /** + * Get an easy to use instance of the class + * @param string $subject + * @return \self + */ + public static function value($subject) { + return new self($subject); + } + + /** + * Shortcut method: Replace all occurrences of the search string with the replacement + * string where they appear outside quotes. + * @param string $search + * @param string $replace + * @param string $subject + * @return string + */ + public static function str_replace_outside_quotes($search, $replace, $subject) { + return static::value($subject)->replace_outside_quotes($search, $replace); + } + + /** + * Set the base string object + * @param string $subject + */ + public function __construct($subject) { + $this->subject = (string) $subject; + } + + /** + * Replace all occurrences of the search string with the replacement + * string where they appear outside quotes + * @param string $search + * @param string $replace + * @return string + */ + public function replace_outside_quotes($search, $replace) { + $this->search = $search; + $this->replace = $replace; + return $this->_str_replace_outside_quotes(); + } + + /** + * Validate an input string and perform a replace on all ocurrences + * of $this->search with $this->replace + * @author Jeff Roberson <[email protected]> + * @link http://stackoverflow.com/a/13370709/461813 StackOverflow answer + * @return string + */ + protected function _str_replace_outside_quotes(){ + $re_valid = '/ + # Validate string having embedded quoted substrings. + ^ # Anchor to start of string. + (?: # Zero or more string chunks. + "[^"\\\\]*(?:\\\\.[^"\\\\]*)*" # Either a double quoted chunk, + | \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' # or a single quoted chunk, + | [^\'"\\\\]+ # or an unquoted chunk (no escapes). + )* # Zero or more string chunks. + \z # Anchor to end of string. + /sx'; + if (!preg_match($re_valid, $this->subject)) // Exit if string is invalid. + exit("Error! String not valid."); + $re_parse = '/ + # Match one chunk of a valid string having embedded quoted substrings. + ( # Either $1: Quoted chunk. + "[^"\\\\]*(?:\\\\.[^"\\\\]*)*" # Either a double quoted chunk, + | \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' # or a single quoted chunk. + ) # End $1: Quoted chunk. + | ([^\'"\\\\]+) # or $2: an unquoted chunk (no escapes). + /sx'; + return preg_replace_callback($re_parse, array($this, '_str_replace_outside_quotes_cb'), $this->subject); + } + + /** + * Process each matching chunk from preg_replace_callback replacing + * each occurrence of $this->search with $this->replace + * @author Jeff Roberson <[email protected]> + * @link http://stackoverflow.com/a/13370709/461813 StackOverflow answer + * @param array $matches + * @return string + */ + protected function _str_replace_outside_quotes_cb($matches) { + // Return quoted string chunks (in group $1) unaltered. + if ($matches[1]) return $matches[1]; + // Process only unquoted chunks (in group $2). + return preg_replace('/'. preg_quote($this->search, '/') .'/', + $this->replace, $matches[2]); + } + }
\ No newline at end of file |