问题
I'm trying to use a prepared PDO statement for use in a database query that looks like the following, where the placeholders variables are represented by the numbers in quotes, i.e., "123" and "456":
SELECT `user_ID` as `ID`
FROM `usermeta`
WHERE (`meta_key` = 'custom_fields')
AND (`meta_value` REGEXP '.*"ABC";.*s:[0-9]+:"123".*')
AND (`meta_value` REGEXP '.*"DEF";.*s:[0-9]+:"456".*')
My question is, would the best practice be to bind to the whole REGEX expression, or just the "123" and "456" variables (is that even possible in a REGEX expression), or something wholly different?
In other words, which is preferred, this:
SELECT `user_ID` as `ID`
FROM `usermeta`
WHERE (`meta_key` = 'custom_fields')
AND (`meta_value` :REGEXP1)
AND (`meta_value` :REGEXP2)
$stmt->bindParam(':REGEXP1', "REGEXP '.*"ABC";.*s:[0-9]+:"123".*'");
$stmt->bindParam(':REGEXP2', "REGEXP '.*"DEF";.*s:[0-9]+:"456".*'");
Or this? (I know there would be some issues with double quotes surrounding the placeholder.)
SELECT `user_ID` as `ID`
FROM `usermeta`
WHERE (`meta_key` = 'custom_fields')
AND (`meta_value` REGEXP '.*"ABC";.*s:[0-9]+:":value1".*')
AND (`meta_value` REGEXP '.*"DEF";.*s:[0-9]+:":value2".*')
$stmt->bindParam(':value1', '123');
$stmt->bindParam(':value2', '456');
Thank you.
回答1:
Placeholders can't be quoted. Simple as that:
SELECT ... WHERE foo = ?
SELECT ... WHERE foo = '?'
The first one is a placeholder, and works as expected. The other one is testing for equality against the character "question mark". It's not a placeholder anymore.
And then there's the problem of ? being a regex metacharacter as well. If placeholders COULD be quoted, then given
SELECT ... WHERE foo REGEXP '^.?'
would that ? be a query placeholder, or is it the regex "zero-or-one" range operator?
If you want to use placeholders in regexes, you have to "build" the regex pattern
SELECT ... WHERE foo REGEXP concat('^.', ?)
Exactly the same way as you would have to build a LIKE pattern:
SELECT ... WHERE foo LIKE '%?%' // wrong
SELECT ... WHERE foo LIKE concat('%', ?, '%') // right
来源:https://stackoverflow.com/questions/39171717/security-for-prepared-sql-statement-with-regex-in-query