0

I have an odd problem with bind_param() for mysqli in PHP.

Here's the code:

                $q = <<<SQL
INSERT INTO customers (name, company, email) 
VALUES (?, ?, ?)
SQL;

                $mysqli->QP(
                        $q,
                        "sss",
                        $this->name,
                        $this->company, $this->email);

    public function QP(string $s, string $h, $var1, ...$_): ?mysqli_result
    {
        $stmt = $this->mysqli->prepare($s);
        if (count($_) > 0) {
            $stmt->bind_param($h, $var1, $_); // line58
        } else {
            $stmt->bind_param($h, $var1);
        }

        $stmt->execute(); // line 58
        $result = $stmt->get_result();
        if ($result) {
            return $result;
        } else {
            Panic($s, $stmt->error);
        }
        return null;
    }

This function, by and large works, except in this one particular case with this query combination. I cannot use this number of variables, or more, though it looks like I can just use two variables. (?,?)

The code I inherited uses a sort of database wrapper which wraps everything up in functions and does the work, so I've tried to recreate that with bind_param by copying the header.

The number of variables passed appear to be OK, the SQL appears to be OK, the type string appears to be OK. I cannot figure out why I'm getting these two errors:

Warning: mysqli_stmt::bind_param(): Number of elements in type definition string doesn't match number of bind variables in db.php on line 53

Fatal error: Uncaught mysqli_sql_exception: No data supplied for parameters in prepared statement in db.php on line 58

Any advice?

user3783243
  • 5,368
  • 5
  • 22
  • 41
Simon
  • 1,385
  • 1
  • 11
  • 20
  • Not a mysqli user but can splat be used with individual variables? Maybe should be `$stmt->bind_param($h, array_merge($var1, $_));` – user3783243 Sep 30 '22 at 12:22
  • 1
    does it not make sense to accept $_ as an array in the function sig and then ...$_ in the bind_param function? – MHewison Sep 30 '22 at 12:23
  • The error is obvious: Number of elements in type definition string "sss" is **three** while number of bind variables ($var1, $_) is visibly **two.** Regardless, I don't see why it should be done such complicated way. Why here is $var1, why not to use just a single array for any number of variables? Also, if I am not mistaken, this code will panic for no reason, just for the present query for example. – Your Common Sense Sep 30 '22 at 12:32
  • @user3783243 you are making it one variable where expected three – Your Common Sense Sep 30 '22 at 12:32
  • Also, I **strongly** advise against `...$_` in the function definition. The day you will need a new parameter for the function you will deeply regret the day when you decided to save yourself typing of two square braces. – Your Common Sense Sep 30 '22 at 12:47
  • Ahh. Ok. Makes sense. QP() was essentially going to be a wrapper for bind_param() to retain the original structure of the program. Hence I tried to recreate the header of bind_param() - the definition of which shows public function bind_param($types, &$var1, &...$_) {} ...$ in the QP def actually does then receive all of the n+1 params as one array. – Simon Sep 30 '22 at 13:26
  • You're all right, and you're all wrong, and this is and isn't a duplicate of creating a wrapper. The problem was here was my lack of understanding of the splt/three dots (...) functionality. So while we were packing the incoming variables, we weren't unpacking the variables to pass to bind_param. Which means after removing $var1 from the function definition but keeping ...$_, our call to bind_param can be simplified to $stmt->bind_param($h, ...$_) (which unpacks our packed variables). Cute. – Simon Sep 30 '22 at 14:18

0 Answers0