mysqli error - bind_param: number of variables doe

2019-09-02 08:24发布

问题:

I am getting the following error but I have counted things over and over again and everything appears to be fine. Anyone have any ideas on it ?

Error:

Warning: mysqli_stmt::bind_param() [mysqli-stmt.bind-param]: Number of variables doesn't match number of parameters in prepared statement in /home/ambnews/public_html/invoice/response.php on line 204

Code:

// invoice customer information
    // billing
    $customer_name = $mysqli->real_escape_string($_POST['customer_name']); // customer name
    $customer_email = $mysqli->real_escape_string($_POST['customer_email']); // customer email
    $customer_address_1 = $mysqli->real_escape_string($_POST['customer_address_1']); // customer address
    $customer_address_2 = $mysqli->real_escape_string($_POST['customer_address_2']); // customer address
    $customer_town = $mysqli->real_escape_string($_POST['customer_town']); // customer town
    $customer_county = $mysqli->real_escape_string($_POST['customer_county']); // customer county
    $customer_postcode = $mysqli->real_escape_string($_POST['customer_postcode']); // customer postcode
    $customer_phone = $mysqli->real_escape_string($_POST['customer_phone']); // customer phone number

    //shipping
    $customer_name_ship = $mysqli->real_escape_string($_POST['customer_name_ship']); // customer name (shipping)
    $customer_address_1_ship = $mysqli->real_escape_string($_POST['customer_address_1_ship']); // customer address (shipping)
    $customer_address_2_ship = $mysqli->real_escape_string($_POST['customer_address_2_ship']); // customer address (shipping)
    $customer_town_ship = $mysqli->real_escape_string($_POST['customer_town_ship']); // customer town (shipping)
    $customer_county_ship = $mysqli->real_escape_string($_POST['customer_county_ship']); // customer county (shipping)
    $customer_postcode_ship = $mysqli->real_escape_string($_POST['customer_postcode_ship']); // customer postcode (shipping)

    $query = "INSERT INTO store_customers (
                    name,
                    email,
                    address_1,
                    address_2,
                    town,
                    county,
                    postcode,
                    phone,
                    name_ship,
                    address_1_ship,
                    address_2_ship,
                    town_ship,
                    county_ship,
                    postcode_ship
                ) VALUES (
                    '".$customer_name."',
                    '".$customer_email."',
                    '".$customer_address_1."',
                    '".$customer_address_2."',
                    '".$customer_town."',
                    '".$customer_county."',
                    '".$customer_postcode."',
                    '".$customer_phone."',
                    '".$customer_name_ship."',
                    '".$customer_address_1_ship."',
                    '".$customer_address_2_ship."',
                    '".$customer_town_ship."',
                    '".$customer_county_ship."',
                    '".$customer_postcode_ship."'
                );
            ";

    /* Prepare statement */
    $stmt = $mysqli->prepare($query);
    if($stmt === false) {
      trigger_error('Wrong SQL: ' . $query . ' Error: ' . $mysqli->error, E_USER_ERROR);
    }

    print_r($stmt->bind_param(
        'sssssssissssss',
        $customer_name,$customer_email,$customer_address_1,$customer_address_2,$customer_town,$customer_county,$customer_postcode,
        $customer_phone,$customer_name_ship,$customer_address_1_ship,$customer_address_2_ship,$customer_town_ship,$customer_county_ship,$customer_postcode_ship));

    /* Bind parameters. TYpes: s = string, i = integer, d = double,  b = blob */
    $stmt->bind_param(
        'sssssssissssss',
        $customer_name,$customer_email,$customer_address_1,$customer_address_2,$customer_town,$customer_county,$customer_postcode,
        $customer_phone,$customer_name_ship,$customer_address_1_ship,$customer_address_2_ship,$customer_town_ship,$customer_county_ship,$customer_postcode_ship);

    /* Execute statement */
    $stmt->execute();

    if($stmt->execute()){
        //if saving success
        echo json_encode(array(
            'status' => 'Success',
            'message' => 'Customer has been created successfully!'
        ));
    } else {
        // if unable to create invoice
        echo json_encode(array(
            'status' => 'Error',
            'message' => 'There has been an error, please try again.'
            // debug
            //'message' => 'There has been an error, please try again.<pre>'.$mysqli->error.'</pre><pre>'.$query.'</pre>'
        ));
    }

    //close database connection
    $mysqli->close();

回答1:

You need to take a look at the manual:

  1. You should not escape your values when you use a prepared statement as you will be adding literal backslashes in your data.
  2. You should not inject your variables in the query but use placeholders (question marks in mysqli) instead. These are bound to your values.

So your query would be:

$query = "INSERT INTO store_customers (
                name,
                email,
                // etc.
            ) VALUES (
                ?,
                ?,
                // etc.
            );
        ";

And you bind your values:

$stmt->bind_value(
    'sssssssissssss',
    $_POST['customer_name'],
    $_POST['customer_email'],
    // etc.
);

Note that I am using bind_value() instead of bind_param() as this seems to be used once only so there is no need to bind parameters, you can bind the values directly. It should not make a difference though.