tags:

views:

96

answers:

3

Hello Stack Overflow!

I'm working with someone else's database connection PHP function that works fine as long as I pass it at least three arguments. If I pass it two argument, then the apache log says:

mysql_real_escape_string() expects parameter 2 to be resource, null given

I need the function to take a SQL query like so:

$sql = DatabaseManager::prepare("SELECT * FROM sometable WHERE somevar = %d", $var);

and prepare it for safe execution. Can someone help make it accept two arguments?

public static function prepare($query = null) { // ( $query, *$args )

    $args = func_get_args();

    array_shift($args);

    // If args were passed as an array (as in vsprintf), move them up
    if ( isset($args[0]) && is_array($args[0]) ){
        $args = $args[0];
    }

    $query = str_replace("'%s'", '%s', $query); // in case someone mistakenly already singlequoted it
    $query = str_replace('"%s"', '%s', $query); // doublequote unquoting
    $query = str_replace('%s', "'%s'", $query); // quote the strings

    for($i=0; $i<count($args); $i++){
        $args[$i] = mysql_real_escape_string($args[$i], self::$currentCon);
    }

    //array_walk($args, array(&$this, 'mysql_real_escape_string'));

    return @vsprintf($query, $args);
}   

Thanks a ton!

EDIT

As deceze points out, this is about self::$currentCon) and means that a database connection is coming back null

I've tried this multiple times. Still curious about why this works:

$sql = DatabaseManager::prepare("SELECT * FROM sometable WHERE id = ".$somevar); 

but this fails:

$sql = DatabaseManager::prepare("SELECT * FROM sometable WHERE somevar = %d", $var); 

How would that affect self::$currentCon)?

A: 

Your prepare need a 1 parameter($query);

DatabaseManager::prepare("SELECT * FROM sometable WHERE somevar = %d", $var);
  • in this code you give 2 parameters to function.
Alexander.Plutov
very good point @Alexander...Thanks for the help in clarifying my question. I mean that it won't take 1 extra parameter. So including the SQL query, it won't take anything less than 3 parameters. I edited my question to clarify.
Emile
+1  A: 

maybe it's just me, i'd write the function like this

public static function prepare($query = null,$args = array()) {
    $query = str_replace("'%s'", '%s', $query); // in case someone mistakenly already singlequoted it
    $query = str_replace('"%s"', '%s', $query); // doublequote unquoting
    $query = str_replace('%s', "'%s'", $query); // quote the strings

    foreach($args as $key=>$arg){
        $args[$key] = mysql_real_escape_string($arg, self::$currentCon);
    }

    //array_walk($args, array(&$this, 'mysql_real_escape_string'));

    return @vsprintf($query, $args);
}

I haven't tested it.. i don't understand why the function is using func_get_args() and array_shift() and then test if there was or not a second argument.. it seems too complicated, at least for me

pleasedontbelong
Thanks @pleasedontbelong ... My first steps into PHP so forgive me for the ignorance, but my apache log says "Invalid argument supplied for foreach()` when I run the code using your function. (although you did get rid of the last error message :) Any ideas?
Emile
well.. reading the other answers, and the apache log, i think this was not the problem so @deceze might be right. But just as a reference, if you use the function as i posted here, you would have to call the function in a different way.. something like this prepare("SELECT...", array($var1,$var2,...));... anyway.. use your original code and check the parameters passed to the mysql_real_escape_string() function
pleasedontbelong
thanks @pleasedontbelong for the cleaner code!
Emile
+4  A: 
deceze
thanks @deceze! that makes sense and I will follow that lead... The connection to the database works however if I feed it: $sql = DatabaseManager::prepare("SELECT * FROM sometable WHERE id = ".$somevar); but fails when I feed it $sql = DatabaseManager::prepare("SELECT * FROM sometable WHERE somevar = %d", $var); Any reason for that?
Emile
@Emile Yes. If you supply no extra `$args`, the `for (...) { ... }` loop isn't run at all, hence the offending `mysql_real_escape_string` is never called. That loop is only run as many times as there are (extra) arguments.
deceze
gotchya!! Thanks!!
Emile