mikeyjhavoc
mikeyjhavoc

Reputation: 55

PDO query execute invaid, issue with bindValue not matching

in PDO and PHP, I worked out with some research what I thought would be a working solution for a query statement function. Right now it errors out with the statement

PHP Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in /var/www/html/php/php_tools/private/functions.php on line 39

which is on line 15 of my scratch file to make this easier to read instead of working through multiple files, it still works the same, I checked.

 <?php

try {
  $db = new PDO("mysql:host=$host;dbname=$base;", $user, $pass);
}catch(Exception $e){
     echo $error = $e->getMessage();
}

function execute_query($con, $query, $statements) {

$query_string = $con->prepare($query);

foreach ($statements as $statement) {

    $query_string->bindValue(1, $statement['string'], PDO::PARAM_STR);
    $query_string->bindValue(2, $statement['value'], PDO::PARAM_STR);
    $query_string->bindValue(3, $statement['type'], PDO::PARAM_STR);// I believe this is the culprit?

    }

$query_string->execute();


return $query_string->fetchAll();
 }

   $multi_item_query = "SELECT t.t_id as id, t.item_code as code, 
 t.item_name as name,
 t.retail_price as retail, t.sale_price as price,
 t.item_pieces as  pieces, t.qty as quantity,
 t.sold as sold, t.description as description,
 b.brand as brand, c.category as category,
 tt.tool_type as sections, i.image as image
 FROM Tools as t
 INNER JOIN Brands as b on t.b_id = b.b_id
 INNER JOIN Categories as c ON t.c_id = c.c_id
 INNER JOIN Images AS i ON t.t_id = i.t_id
 LEFT OUTER JOIN Types AS tt ON t.tt_id = tt.tt_id
 WHERE tt.tool_type = :tool";

if ( isset($_GET['cat']) ) {
     if ( $_GET['cat'] == 'wrenches') {
        $page_name = 'Wrenches';
        $section = 'wrenches';
        $param = 'wrenches';
    } elseif ( $_GET['cat'] == 'blades') {
         $page_name = 'Blades';
        $section = 'blades';
        $param = 'blades';
    } else {
        $page_name = 'Full Catalog';
         $section = null;
    }
}
 $con = $db;
 $statement = array(); // Prepare a statement array.
$id = array(
     'string' => ':tool',
     'value' =>  $param,
     'type' => PDO::PARAM_STR
 );

 $statement[] = $id;

 ?>

<?php  $items = execute_query($con, $multi_item_query, $statement); ?>

right at "bindValue" is where it breaks now within the foreach loop. and as I study more. Do more research I believe I the bottom "bindValue" is the culprit? but I am unsure what I would use as the PDO::? item to announce it as.. ? any help or guidance would be benfefical.. sinceI might be way off..being still new, also any feed back on please?

Upvotes: 2

Views: 258

Answers (3)

Your Common Sense
Your Common Sense

Reputation: 157910

You made your function so overly complicated, that you failed to use it yourself. Make it much simpler, like this:

function execute_query($con, $query, $variables) {
    $stmt = $con->prepare($query);
    $stmt->execute($variables)
    return $stmt;
}

and so you'll be able to run it this way

$con = $db;
$variables['tool'] = $param;
$items = execute_query($con, $multi_item_query, $variables)->fetchAll();

Upvotes: 4

aynber
aynber

Reputation: 23001

You're trying to pass all parts of the binding in, but trying to bind them individually. You need to pass all parts of the statement into one bind value:

foreach ($statements as $statement) {

    $query_string->bindValue($statement['string'], $statement['value'], $statement['type']);

}

Upvotes: 2

Professor Abronsius
Professor Abronsius

Reputation: 33813

surely it would be

foreach ($statements as $statement) {
    $query_string->bindValue($statement['string'], $statement['value'],$statement['type'] );
}

And the execute method inside the loop

foreach ($statements as $statement) {
    $query_string->bindValue($statement['string'], $statement['value'],$statement['type'] );
    $query_string->execute();
}

Upvotes: 2

Related Questions