2

This is my first foray into the world of stack overflow, I'm new to programming and could desperately use some assistance. I'm attempting to dynamically parameterize a mysqli DB query but keep getting an error saying "Wrong parameter count for mysqli_stmt::bind_param()", even though I'm (pretty) sure my counting isn't that bad. Thanks in advance for your help, the relevant code is below.

$search = "SELECT Row1, Row2, Row3, Row4, Row5, Row6 FROM Listings WHERE (Search1 LIKE ?) AND (Search2 LIKE ?) AND (Search3 LIKE ?) AND (Status='Active')";

$params= array(&$param1, &$param2, &$param3);
$stmt = $con2->stmt_init();
        if($stmt->prepare($search)) {
            call_user_func_array(array($stmt, 'bind_param'), $params);

            if($stmt->execute()) {
                $stmt->bind_result($Row1, $Row2, $Row3, $Row4, $Row5, $Row6);
                echo 'Success';
          }
         }`
V.C.4
  • 19
  • 1
  • 3
  • 1
    Not what your looking for, but are you sure you want to use references to those three parameters? I think this is deprecated in current PHP. – ToBe Sep 09 '14 at 14:59
  • 1
    @ToBe: passing references to function calls is deprecated. Assigning references is not. Either way: the manual does mention `call_user_func_array`, saying that the array of arguments should be an array of references. So no: not deprecated, and yes: it's required here – Elias Van Ootegem Sep 09 '14 at 15:00

1 Answers1

3

Check the official manual. The function/method signature suggests that bind_param expects 3 arguments in your case:

bool mysqli_stmt::bind_param ( string $types , mixed &$var1 [, mixed &$... ] )

You're passing the values alright, but at no point are you passing the string that indicate the types:

$params = array(
    'sss',
    &$param1,
    &$param2,
    &$param3
);

Would make more sense. However, personally, I find code like this is pointless obfuscation of what you're actually doing, simply writing:

$stmt->bind_param('sss', $param1, $param2, $param3);

makes more sense, anyway, and you don't need to construct that array of references, call call_user_func_array, which simply invokes the bind_param method to begin with. So basically: stick to the one-liner

Slightly off-topic:
A bit of friendly advice: your query, though using prepared statements and all that is far from perfect: at no point do you seem to check for wildcards (% and _), so if these parameters are coming from the user, make sure that you don't end up performing a LIKE query that looks like this:

SELECT Row1, Row2, Row3, Row4, Row5, Row6 
FROM Listings 
WHERE Search1 LIKE '%'
  AND Search2 LIKE '%'
  AND Search3 LIKE '%'
  AND Status='Active'

Which will just return all records with Status = 'Active'. Fix this by Either using = instead of LIKE or sanitizing the input.

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • yep. call_user_func should only ever be used if the function in question is inside a variable, which in your case it isnt. And even then, people might say that is allways a bad idea. – ToBe Sep 09 '14 at 15:01
  • @ToBe: indeed it is a bad idea: if you are relying on variables to hold methods, you have a problem. And still, if it's a method you're invoking: `$instance->{$variable}($arguments);` works just fine... :) – Elias Van Ootegem Sep 09 '14 at 15:02
  • @EliasVanOotegem Thanks for the sanitizing tip. The reason I wasn't using the 1-liner is because I'm not sure how many parameters I'm going to need to bind, so I have a function that adjusts the query ($search) and parameters ($params) as required, then I use those. I'm really just trying to query the db with an unknown (1-3) amount of parameters. Am I going about it the wrong way? – V.C.4 Sep 09 '14 at 16:40
  • @V.C.4: if you're binding all the params as strings, you could use `call_user_func_array`, but add the following line of code: `$typeString = str_repeat('s', count($params));`, this adds a string like _"sss"_ if you're querying with 3 params, _"s"_ if it's just the one. Then, simply use `array_unshift($params, $typeString);` to prepend that string to the array of arguments – Elias Van Ootegem Sep 10 '14 at 07:19