PDO: Invalid parameter number: number of bound variables does not match number of tokens - pdo

I've been breaking my head over the following.
What you can see below is the result of a dynamically build INSERT together with its BINDS. The column names and tokens are being pulled from the table. I do not know them in advance. So I use build in functions to know what they are. The values are posted to me via a form. I put both together using an associative array which I use to build the INSERT command.
The array looks like this:
Array
(
[id] => 0
[datum] => 1968-05-13 16:58:02
[titel] => test 369
[categorie] => catEGORIE
[tekst] => tekst
[zichtbaar_bijlage] => 1
[zichtbaar_foto_1] => 1
[zichtbaar_foto_2] => 1
[zichtbaar_foto_3] => 1
[zichtbaar_foto_4] => 1
[zichtbaar_foto_5] => 1
[zichtbaar_foto_6] => 1
[zichtbaar_foto_7] => 1
[zichtbaar_foto_8] => 1
[zichtbaar_foto_9] => 1
[zichtbaar_foto_10] => 1
[bijlage] => verkeersbord.jpg
[foto_1] => hummel.jpg
[foto_2] => reinoutgerolf.jpg
[foto_3] => hummel.jpg
[foto_4] => verkeersbord.jpg
[foto_5] => verkeersbord.jpg
[foto_6] => 20140511vlaggen.jpg
[foto_7] => verkeersbord.jpg
[foto_8] => 20140511vlaggen.jpg
[foto_9] => verkeersbord.jpg
[foto_10] => 50-euro-1024x545.jpg
)
A dump of the INSERT command and the BINDS looks like this:
INSERT INTO some_DB.some_table (NIE_id, NIE_datum, NIE_titel, NIE_categorie, NIE_tekst, NIE_zichtbaar_bijlage, NIE_zichtbaar_foto_1, NIE_zichtbaar_foto_2, NIE_zichtbaar_foto_3, NIE_zichtbaar_foto_4, NIE_zichtbaar_foto_5, NIE_zichtbaar_foto_6, NIE_zichtbaar_foto_7, NIE_zichtbaar_foto_8, NIE_zichtbaar_foto_9, NIE_zichtbaar_foto_10, NIE_bijlage, NIE_foto_1, NIE_foto_2, NIE_foto_3, NIE_foto_4, NIE_foto_5, NIE_foto_6, NIE_foto_7, NIE_foto_8, NIE_foto_9, NIE_foto_10) VALUES (:id, :datum, :titel, :categorie, :tekst, :zichtbaar_bijlage, :zichtbaar_foto_1, :zichtbaar_foto_2, :zichtbaar_foto_3, :zichtbaar_foto_4, :zichtbaar_foto_5, :zichtbaar_foto_6, :zichtbaar_foto_7, :zichtbaar_foto_8, :zichtbaar_foto_9, :zichtbaar_foto_10, :bijlage, :foto_1, :foto_2, :foto_3, :foto_4, :foto_5, :foto_6, :foto_7, :foto_8, :foto_9, :foto_10)
$STH3->bindValue(':id', 0);
$STH3->bindValue(':datum', 1968-05-13 16:58:02);
$STH3->bindParam(':titel', test 369, PDO::PARAM_STR);
$STH3->bindParam(':categorie', catEGORIE, PDO::PARAM_STR);
$STH3->bindParam(':tekst', tekst, PDO::PARAM_STR);
$STH3->bindParam(':zichtbaar_bijlage', 1, PDO::PARAM_STR);
$STH3->bindParam(':zichtbaar_foto_1', 1, PDO::PARAM_STR);
$STH3->bindParam(':zichtbaar_foto_2', 1, PDO::PARAM_STR);
$STH3->bindParam(':zichtbaar_foto_3', 1, PDO::PARAM_STR);
$STH3->bindParam(':zichtbaar_foto_4', 1, PDO::PARAM_STR);
$STH3->bindParam(':zichtbaar_foto_5', 1, PDO::PARAM_STR);
$STH3->bindParam(':zichtbaar_foto_6', 1, PDO::PARAM_STR);
$STH3->bindParam(':zichtbaar_foto_7', 1, PDO::PARAM_STR);
$STH3->bindParam(':zichtbaar_foto_8', 1, PDO::PARAM_STR);
$STH3->bindParam(':zichtbaar_foto_9', 1, PDO::PARAM_STR);
$STH3->bindParam(':zichtbaar_foto_10', 1, PDO::PARAM_STR);
$STH3->bindParam(':bijlage', verkeersbord.jpg, PDO::PARAM_STR);
$STH3->bindParam(':foto_1', hummel.jpg, PDO::PARAM_STR);
$STH3->bindParam(':foto_2', reinoutgerolf.jpg, PDO::PARAM_STR);
$STH3->bindParam(':foto_3', hummel.jpg, PDO::PARAM_STR);
$STH3->bindParam(':foto_4', verkeersbord.jpg, PDO::PARAM_STR);
$STH3->bindParam(':foto_5', verkeersbord.jpg, PDO::PARAM_STR);
$STH3->bindParam(':foto_6', 20140511vlaggen.jpg, PDO::PARAM_STR);
$STH3->bindParam(':foto_7', verkeersbord.jpg, PDO::PARAM_STR);
$STH3->bindParam(':foto_8', 20140511vlaggen.jpg, PDO::PARAM_STR);
$STH3->bindParam(':foto_9', verkeersbord.jpg, PDO::PARAM_STR);
$STH3->bindParam(':foto_10', 50-euro-1024x545.jpg, PDO::PARAM_STR);
The INSERT command is generated by the following:
$command = "INSERT INTO $_SESSION[database].$table ($fields) VALUES ($arguments)";
echo $command;
$STH3 = $DBH->prepare($command);
foreach($binds_array as $key => $value)
{
if ($key == "id")
{
$STH3->bindValue(':id', 0);
echo "<br>--- STH3->bindValue(':id', 0);<br>";
}
elseif ($key == "datum")
{
$STH3->bindValue(':$key', $value);
echo "--- STH3->bindValue(':$key', $value);<br>";
}
else
{
$STH3->bindParam(':$key', $value, PDO::PARAM_STR);
echo "--- STH3->bindParam(':$key', $value, PDO::PARAM_STR);<br>";
};
};
For some reason this is resulting in an error:
Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter
number: number of bound variables does not match number of tokens
I've been reading up on whatever I could find on this problem but I'm not able to pinpoint the problem. As far as I can see (but I might be blind) the number of tokens and the number of variables is the same.
Any ideas?

The logic of the code, given I understood it correctly, seems fine. There is however one little problem in your code, namely your bindValues.
Both $STH3->bindValue(':$key', $value); and $STH3->bindParam(':$key', $value, PDO::PARAM_STR); suffer from the same problem: $key is enclosed in single quotes, which causes the variable not te be evaluated, but to be interpreted as is (as a string).
For variables inside a string to be evaluated in PHP, they need to be in double quotes, so the two lines of code above must become $STH3->bindValue(":$key", $value); and $STH3->bindParam(":$key", $value, PDO::PARAM_STR);.

#PLPeeters: you solved part of the problem. Many thanks for that! As mentioned in my comment to your answer I shortened the code even more to achieve more flexibility.
foreach($binds_array as $key => $value)
{
$arguments[] .= ":$key";
};
$arguments = implode(',',$arguments);
I deleted a part of the code which was default code to get the columns and put them in $fields.
$command_add = "INSERT INTO some_database.some_table ($fields) VALUES ($arguments)";
$STH3 = $DBH->prepare($command_add);
$STH3->execute($binds_array)

Related

Magento Soap api get all products sku, names, short description and image

My code is working fine but take so much time for show result because i have above 1500 products.
So any one modify my code or best way to show results
$results = $proxy->catalogProductList($sessionId);
$productData = new stdClass();
$productData->additional_attributes = array('short_description','cost');
foreach($results as $value){
$results_product = $proxy->catalogProductInfo($sessionId,$value->product_id,null,$productData);
$pro_imag = $proxy->catalogProductAttributeMediaList($sessionId, $value->product_id);
echo "";
echo "".$sno++."".$value->product_id."".$value->sku."".$value->name."".$results_product->additional_attributes[0]->value."".abs($results_product->additional_attributes[1]->value)."".abs($results_product->price)." url."' width='80px' height='80px'> ";
echo "";
}
Try the following code and use magento site for easy api examples like following, example SOAP V2 (Complex Filter)
<?php
$client = new SoapClient('http://magentohost/api/v2_soap/?wsdl');
$session = $client->login('apiUser', 'apiKey');
$complexFilter = array(
'complex_filter' => array(
array(
'key' => 'type',
'value' => array('key' => 'in', 'value' => 'simple,configurable')
)
)
);
$result = $client->catalogProductList($session, $complexFilter);
var_dump ($result);

How to SORT a SET and GET the full HASH

I'm new to Redis and I have to say I love it till now :)
I'm bumping into an issue I'm not sure how to solve it in the more efficient way.
I have a SET of HASH. Each HASH describe a post.
Here is the code to create and store the HASH:
// Create the HASH
$key = 'post:'.$post->getId();
$this->redis->hSet($key, 'created', $post->getCreated());
$this->redis->hSet($key, 'author', $post->getAuthor());
$this->redis->hSet($key, 'message', $post->getMessage());
// Store the HASH in the SET
$this->redis->sAdd('posts', $post->getId());
Now, previously I was storing all the post's attributes in a data field of the HASH (json_encoded) and I was fetching the information like this:
$key = 'posts';
$data = $this->redis->sort($key, array(
'by' => 'nosort',
'limit' => array($offset, $limit),
'get' => 'post:*->data '
));
if (!is_array($data)) {
return array();
}
foreach ($data as &$post) {
$post = json_decode($post, true);
}
It was working great, I had all the posts information :)
But I had conflicts when updating the post in Redis (concurrent updates), so I've decided to have all the post's attributes in separated fields of the HASH and it fixed my issue of conflicts.
Now the problem I have is to fetch the HASH from my SET. Do I have to specify every single fields like this:
$key = 'posts';
$data = $this->redis->sort($key, array(
'by' => 'nosort',
'limit' => array($offset, $limit),
'get' => array('post:*->created', 'post:*->author', 'post:*->message')
));
Or is there another way to fetch the full HASH directly within the SET?
I heard about pipeline but I'm not sure it's what I'm looking for and if I can use it with phpredis
Cheers, Maxime
UPDATE
I'm not sure I explained myself clearly. I have some elements in a set (post_id).
I want to get the first 10 posts of the SET, which means I want 10 hash (with all their fields and value) in order to build a post object.
I was previously storing all the object information in one field of the hash (data), now I have one field per attribute of the object.
before:
myHash:<id> data
now:
myHash:<id> id "1234" created "2010-01-01" author "John"
Before I was using SORT to fetch the top 10 posts (and paginate easily), like this:
$key = 'posts';
$data = $this->redis->sort($key, array(
'by' => 'nosort',
'limit' => array(0, 10),
'get' => 'post:*->data '
));
Now that I have X members to my hash I'm wondering what is the best solution.
Is it:
$key = 'posts';
$data = $this->redis->sort($key, array(
'by' => 'nosort',
'limit' => array($offset, $limit),
'get' => 'post:*->data '
));
Or maybe:
$key = 'posts';
$data = $this->redis->sort($key, array(
'by' => 'nosort',
'limit' => array($offset, $limit),
'get' => '#'
));
foreach($data as $post_id) {
$posts[] = $this->redis->hGetAll('post:'.$post_id);
}
Or finally:
$key = 'posts';
$data = $this->redis->sort($key, array(
'by' => 'nosort',
'limit' => array($offset, $limit),
'get' => '#'
));
$pipeline = $this->redis->multi();
foreach ($data as $post_id) {
$pipeline->hGetAll('post:'.$post_id);
}
return $pipeline->exec();
Or something else that I don't know yet?
What is the best, faster way to do this?
If you have read redis's source , you'll find that is not possible. There is a workaround that using lua script to combine 'sort' and 'hgetall' commands in a single redis invocation.
The 'get pattern' is processed by function 'lookupKeyByPattern'.
https://github.com/antirez/redis/blob/unstable/src/sort.c#L61
If you start with the redis.io documentation on hashes you'll find there are commands which allow you to get multiple hash members. In particular "HGETALL" for pulling all fields and values, or "HMGET" for pulling a set of fields with their values.
Additionally, for setting them I would recommend setting them in one pass with "HMSET"

Insert statement not working using execute(array()) of PDO Extension

$stmt = $conn->prepare("INSERT INTO user VALUES ('',:username,md5(:password),'',1,'','',:email,'',0,0,'',:cover,:dateofbirthYear:dateofbirthMonth:dateofbirthDay,NOW(),:sex,:country)");
$stmt->execute(array(
':username' => $username,
':password' => $password,
':email' => $email,
':cover' => $cover,
':dateofbirthYear' => $dateofbirthYear,
':dateofbirthMonth' => $dateofbirthMonth,
':dateofbirthDay' => $dateofbirthDay,
':sex' => $sex,
':country' => $country
));
For some reason this insert statement is not working. I am very new in PDO so I do not know much about it. What am I doing wrong?
this statment gives me this error :
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens' in /home/manga/public_html/new/register.php:80 Stack trace:
#0 /home/manga/public_html/new/register.php(80): PDOStatement->execute(Array)
#1 {main} thrown in /home/manga/public_html/new/register.php on line 80
You have prepared your query in the wrong way
INSERT INTO user VALUES ('',:username,md5(:password),'',1,'','',:email,'',0,0,'',
:cover,:dateofbirthYear:dateofbirthMonth:dateofbirthDay,NOW(),:sex,:country
// ^ These need to either single or separated
For what you are trying, you can do it this way
//Prepare the date of birth earlier
$dob = $dateofbirthYear.$dateofbirthMonth.$dateofbirthDay;
//Then pass it as a single $variable
$stmt = $conn->prepare("INSERT INTO user VALUES ('',:username,md5(:password),'',1,'','',:email,'',0,0,'',:cover,:dob,NOW(),:sex,:country)");
$stmt->execute(array(
':username' => $username,
':password' => $password,
':email' => $email,
':cover' => $cover,
':dob' => $dob, // <-- Problem solved
':sex' => $sex,
':country' => $country
));
// Then it will execute
The exact error message you have is:
SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens
This means that the number/names of parameters you have passed (the array() in execute) does not match with the number/names of parameters you have in the prepare() SQL-query.
If you compare that with the other questions that contain SQLSTATE[HY093] you will see that it is often related to code that is large and bad formatted which is hard to read. That makes it hard to count. And then you have an oversight of something and then the error happened.
Just fix it and done, for example you can not make one parameter out of three names:
,:dateofbirthYear:dateofbirthMonth:dateofbirthDay,
Instead just pass one parameter for the birthday:
, :dateofbirth,
You can also make your code a bit more readable:
$stmt = $conn->prepare(
"INSERT INTO user
VALUES (
'', :username, md5(:password), '', 1, '', '', :email, '', 0, 0, '',
:cover, :dateofbirth, NOW(), :sex, :country
)"
);
$stmt->execute(array(
':username' => $username,
':password' => $password,
':email' => $email,
':cover' => $cover,
':dateofbirth' => $dateofbirthYear . $dateofbirthMonth . $dateofbirthDay,
':sex' => $sex,
':country' => $country
));
And then you have a security problem with the password hash:
md5(:password)
Instead do proper password hashing, see the PHP FAQ about Safe Password Hashing.
Corrected prepared query:
$stmt = $conn->prepare("INSERT INTO user VALUES ('',:username,md5(:password),'',1,'','',:email,'',0,0,'',:cover,:dateofbirthYear,:dateofbirthMonth:,dateofbirthDay,NOW(),:sex,:country)");
//:dateofbirthYear,:dateofbirthMonth:,dateofbirthDay place holders are seprated
$stmt->execute(array(
':username' => $username,
':password' => $password,
':email' => $email,
':cover' => $cover,
':dateofbirthYear' => $dateofbirthYear,
':dateofbirthMonth' => $dateofbirthMonth,
':dateofbirthDay' => $dateofbirthDay,
':sex' => $sex,
':country' => $country
));

WP_Query() and ordering items

I have to order items from wp_post by their menu_order (pages only).
I've written this line:
$query = new WP_Query();
$all = $query -> query(array('post_type' => 'page', 'posts_per_page' => -1, 'orderby' => 'menu_order', 'order' => 'DESC'));
$children = get_page_children($id, $all);
foreach ($children as $child) {
if ($child -> ID == get_the_id()) {
echo '<li class="active">' . $id . $child -> post_title . '</li>';
I see the items but they are not ordered.
Thanks.
FZ
I would say that the issue relates to the fact you are passing the $all object through get_page_children before using it in a loop.
Why don't you just forget get_page_children and add 'post_parent' to your list of WP_Query arguments?
$all = $query->query(array('post_type' => 'page', 'post_parent' => $id, 'posts_per_page' => -1, 'orderby' => 'menu_order', 'order' => 'DESC'))
A helpful thread on Wordpress Stack Exchange;
https://wordpress.stackexchange.com/questions/35123/wp-get-all-the-sub-pages-of-the-parent-using-wp-query
EDIT.
To expand on comments. Sometimes there's confusion about menu_order - it does not relate to wp_nav_menus but to the Page Attributes Order input box, as shown below;

Blank page with multiple table select

Having these queries, but on running it gives me blank pages. Maybe bacause the $query->result function is not good for "him"? (It's ExpressionEngine)
$query = $DB->query("SELECT fr.uri AS smth, ch.uri
FROM exp_static_page_caching_uris AS fr,
exp_static_page_caching_queue AS ch
WHERE fr.uri != ch.uri");
foreach($query->result as $row) {
$DB->query($DB->insert_string('exp_static_page_caching_queue',
array('site_id' => '1',
'uri' => $row['smth']),
TRUE));
}
Try $query->result_array() instead of $query->result