views:

71

answers:

3

I'm trying to create a very simple database abstraction, one part of it using prepared queries.

Now, I have a function take a query string and an array of values like this:

$query = "SELECT `first_name`, `last_name` FROM ::table_name WHERE `id` = :id"
$values = array(
    'table_name' = $this->table_name,
    'id' = $user_id,
);

this will create a query like this:

SELECT `first_name`, `last_name` FROM `sometablename` WHERE `id` = '1234'

my problem is this:
I'm using preg_replace_callback to grab the ::identifiers and :identifiers from the query string, and then sending it to a sanitization function. The problem is, I also need to send the values array, so that the function can take the match from the regexp, get the item in the values array with that key, escape the value, wrap it in the right quotes and then return it.

But I can't pass any extra information to the callback. I could use a private static variable but this is very hacky.

What is another approach to this?

+1  A: 

Doesn't vsprintf fit your needs?

erenon
I don't think so, not without wiping out everything I have already
Carson Myers
+2  A: 

you could also check out pdo, zend_db, and mdb2. good thing is they have named parameters and drivers that can properly create prepared statements (or emulate prepared statements) on many storage engines.

for example, zend_db will do some basic sql parsing to handle edge cases, like say when a regex embedded in a query is a character class with a colon...

jspcal
Right, I haven't chosen to use a library though because I wanted to solve this one on my own, considering the tinyness of the project (it is truly tiny)
Carson Myers
+2  A: 

One of the alternatives suggested by various comments in the manual is to use preg_replace() with the 'e' modifier as part of the regexp:

preg_replace("/pattern/e","strtoupper('\\1')",$subject);

Essentially you're specifying code to evaluate. I think this comment has a good example, whereby you create the function, and then a small string to evaluate it which allows you to pass extra parameters:

preg_replace('/pattern/e',"your_function(\$array,\$foo,\$bar,\$etc)",$str);
zombat
this is perfect! I wish I read this before I used a big class to handle it... I guess I will change it over to this simpler version. Thank you!
Carson Myers
Or you could actually use http://php.net/manual/en/function.preg-replace-callback.php. I don't like the idea of putting code in strings.
Mark
@Mark - Carson specifically states that `preg_replace_callback()` isn't working for him, because you can't pass extra parameters to the callback function. Using `preg_replace()` with the 'e' option is the work-around. Note also that `preg_replace_callback()` utilizes evaluated code, so it's just the nature of the situation.
zombat