All pastes #88291 Raw Edit

Ashe

public php v1 · immutable
·published 2006-07-14 19:20 UTC
rendered paste body
	/**	* Format the SQL code needed for a [NOT] LIKE comparison	*	* Our [NOT] LIKE does not follow the SQL syntax. Instead, it uses * and ? as wildcards.	*  ? substitutes exactly 1 character (equivalent to _ in SQL)	*  * substitutes 0 or more characters (equivalent to % in SQL)	*	* Those characters can be escaped with a backslash \	* The backslash itself can be escaped with a backslash	*	* Note that we only provide the righthand side of the operation.	* Also note that [NOT] LIKE will be replaced by a simple [in]equality test if the pattern	* does not contain any wildcard character	*	* @param	string	$mode		Operation mode: either LIKE or NOT LIKE	* @param	string	$pattern	Matching pattern	* @param	array	$options	Query options	* @return	string				SQL code, either "[NOT] LIKE '<pattern>'" or "[=|<>] '<pattern>'"	*/	protected function format_like($mode, $pattern, array $options)	{		$constant = TRUE;		$wildcard = FALSE;		$pos = 0;		$len = strlen($pattern);		$tmp = '';		do		{			if ($spn = strcspn($pattern, '*?_%\\', $pos))			{				/**				* Skip all characters that do not have a special meaning				*/				$tmp .= substr($pattern, $pos, $spn);				$pos += $spn;				$wildcard = FALSE;			}			if ($pos == $len)			{				break;			}			/**			* Capture and consume current char			*/			$char = $pattern[$pos++];			switch ($char)			{				case '*':					if ($wildcard)					{						break;					}					$tmp .= '%';					$constant = FALSE;					$wildcard = TRUE;					break;				case '?':					$tmp .= '_';					$constant = FALSE;					$wildcard = FALSE;					break;				case '_':					$tmp .= '\\_';					$wildcard = FALSE;					break;				case '%':					$tmp .= '\\%';					$wildcard = FALSE;					break;				case '\\':					/**					* How many contiguous backslashes do we have?					*/					$spn = strspn($pattern, '\\', --$pos);					$pos += $spn;					if ($spn % 2 == 0)					{						/**						* The number of backslashes is even, just add them to the string						*/						$tmp .= str_repeat('\\', $spn);					}					else					{						/**						* There is an odd number of backslashes: either we are escaping a						* special char (* or ? or \) or the user was sloppy and forgot one						*/						if ($pos < $len						 && ($pattern[$pos] != '*' || $pattern[$pos] != '?'))						{							/**							* The last "odd" backslash is escaping a * or ? but since							* those characters have no special abilities in SQL we							* simply remove the last backslash and add the character							*							* Note that we increment $pos in order to consume the character							*/							$tmp .= str_repeat('\\', $spn - 1) . $pattern[$pos++];						}						else						{							/**							* Nope, just add an extra backslash							*/							$tmp .= str_repeat('\\', $spn + 1);						}					}					$wildcard = FALSE;					break;			}		}		while ($pos < $len);		if ($constant)		{			/**			* No wildcards found, treat the string as a constant			*			* Strip the extra backslashes, the string will then be properly escaped			* and the operator will be replaced with a simple equality operator			*/			return (($mode == 'LIKE') ? '= ' : '<> ') . $this->format('s', stripslashes($tmp), $options);		}		else		{			return $mode . ' ' . $this->format('s', $tmp, $options) . " ESCAPE '\\\\'";		}	}