I am editing a pre-made script for iDEAL payments which is available here. What I’m trying to do is add a few fields to the form and database. The extra fields show up fine in the email template, but they are not entered into the database. The script works with PHPmailer.
I think this is where the problem is:
$stmt = $db->prepare("INSERT INTO tbl_ideal_payments SET
ID = ?, datumtijd = NOW(),
naamfrom = ?, emailfrom = ?,
naamto = ?, emailto = ?,
bedrag = ?, descr = ?,
mailsubject = ?, mailtekst = ?,
ipadres = ?,
heenreis = ?,
terugreis = ?,
postcode = ?,
factuurnummer = ?,
status = 'open'");
//var_dump($stmt);
$stmt->bind_param('sssssdssss', $session, $naamfrom, $emailfrom, $contact, $emailto, $bedrag, $paydecr, $subject, $mailmsg, $heenreis, $terugreis, $postcode, $factuurnummer, $_SERVER['REMOTE_ADDR']);
The fields that I'm trying to add are heenreis, terugreis, postcode, and factuurnummer.
Full code for the config, form, and above script can be found here (seems a bit much to paste in this post).
What am I doing wrong?
Count the data type parameters 'sssssdssss' and then count the parameters place holders ?, and then count the columns in the SET clause, they should all be the same number.
Also this situation will have generated an error, but you are not testing for errors
While developing, specially if you are developing on a LIVE server where error reporting should be turned off add these lines at the top of the script, to turn on error reporting.
<?php
ini_set('display_errors', 1);
ini_set('log_errors',1);
error_reporting(E_ALL);
// if you are using the MYSQLI_ database extension add this also
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$stmt = $db->prepare("INSERT INTO tbl_ideal_payments SET
ID = ?, datumtijd = NOW(),
naamfrom = ?, emailfrom = ?,
naamto = ?, emailto = ?,
bedrag = ?, descr = ?,
mailsubject = ?, mailtekst = ?,
ipadres = ?,
heenreis = ?,
terugreis = ?,
postcode = ?,
factuurnummer = ?,
status = 'open'");
// also add error test
if ( !$stmt ) {
echo $db->error;
exit;
}
// now add the 4 missing data type parameters
// I have assumed they are all string !!!
// You should check with your schema what datatype they actually are
$stmt->bind_param('sssssdssssssss', $session,
$naamfrom,
$emailfrom,
$contact,
$emailto,
$bedrag,
$paydecr,
$subject,
$mailmsg,
$heenreis,
$terugreis,
$postcode,
$factuurnummer,
$_SERVER['REMOTE_ADDR']
);
Related
When I'm updating an item (ativo) of an employee (colaborador) I need to check if an employee that the user input exists or not in the DB, and if it doesn't - give an error message. I don't know how can I do it, can you guys point me to some tutorial that explains it? Thanks in advance!
This is my query btw:
$pdo = Database::connect();
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "UPDATE ativos SET ativo = ?, comentario = ?, data_aquisicao = ?,
localizacao = ?, fabricante = ?, modelo = ?,
imei = ?, numero_serie = ?, ativo_sap = ?,
anexo_a = ?, evento = ?, data_evento = ?,
id_colaborador = (SELECT id_colaborador
FROM colaboradores
WHERE nome = ?
LIMIT 1
)
WHERE id_ativo = ?";
$q = $pdo->prepare($sql);
$q->execute(array($ativo,$comentario,$data_aquisicao,$localizacao,
$fabricante,$modelo,$imei,$numero_serie,$ativo_sap,
$anexo_a,$evento,$data_evento,$id_colaborador,$id));
And this is the input (i don't know if it's needed to validate if the row exist)
<input autocomplete="off" name="id_colaborador" type="text" placeholder="Nome do Colaborador" value="<?php echo !empty($nome)?$nome:'';?>" class='auto'>
Your query is not considering the possibility of homonyms. So, you'd better use some auto_complete field to get the 'id_colaborador' based on the name and keep it in a hidden input field and then execute the update with the exact values.
Tried everything I can think of and I've narrowed down to the "?" placeholders.
I've tried replacing the "?" placeholders with random text and all works well (except of course it keeps overwriting the same row).
The error I get:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
produ' at line 2
Here is my code (I would provide more but it all works well except for this bug, and if I remove the "?" placeholders then all works perfectly except that the values are not dynamic, but please ask if you suspect the issue is elsewhere):
// Create MySQL connection to ds_signifyd_api
$mysqli = mysqli_connect( $db_server_name, $db_username, $db_password, $db_name );
// Check connection
if ($mysqli->connect_error) {
exit( $mysqliFailedBody );
}
$mainProdQueryStmt = "INSERT INTO products (`product_id`, `title`, `body_html`, `vendor`, `product_type`, `created_at`, `handle`, `updated_at`, `published_at`, `template_suffix`, `published_scope`, `tags`)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
product_id = VALUES(product_id),
title = VALUES(title),
body_html = VALUES(body_html),
vendor = VALUES(vendor),
product_type = VALUES(product_type),
created_at = VALUES(created_at),
handle = VALUES(handle),
updated_at = VALUES(updated_at),
published_at = VALUES(published_at),
template_suffix = VALUES(template_suffix),
published_scope = VALUES(published_scope),
tags = VALUES(tags)";
$product_id = $product_title = $body_html = $vendor = $product_type = $created_at = $handle = $updated_at = $published_at = $template_suffix = $published_scope = $tags = "";
foreach ($dss_product_db_array as $product) {
$product_id = $product['id'];
//... more variables here...
$tags = mysqli_real_escape_string($mysqli, $tags);
if (!mysqli_query($mysqli, $mainProdQueryStmt)) {
printf("Errormessage: %s\n", mysqli_error($mysqli));
}
$mainProdQuery->bind_param("isssssssssss", $product_id, $product_title, $body_html, $vendor, $product_type, $created_at,
$handle, $updated_at, $published_at, $template_suffix, $published_scope, $tags);
$mainProdQuery->execute();
// $mainProdQuery->close();
}
UPDATE
Implemented the fixes mentioned here:
1. Stopped using mysqli_real_escape_string
2. Binding variables outside loop
3. Using only the object oriented method, as opposed to mixing them as in the case of mysqli_query($mysqli, $mainProdQueryStmt) VS $mysqli->prepare($mainProdQueryStmt) as it should have been -- this solved the "?" placeholders syntax error being incorrectly reported
Now everything works perfectly, no errors.
Updated Code:
$mainProdQueryStmt = "INSERT INTO dss_products (`product_id`, `title`, `body_html`, `vendor`, `product_type`, `created_at`, `handle`, `updated_at`, `published_at`, `template_suffix`, `published_scope`, `tags`)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
product_id = VALUES(product_id),
title = VALUES(title),
body_html = VALUES(body_html),
vendor = VALUES(vendor),
product_type = VALUES(product_type),
created_at = VALUES(created_at),
handle = VALUES(handle),
updated_at = VALUES(updated_at),
published_at = VALUES(published_at),
template_suffix = VALUES(template_suffix),
published_scope = VALUES(published_scope),
tags = VALUES(tags)";
$mainProdQuery = $mysqli->prepare($mainProdQueryStmt);
if ($mainProdQuery === FALSE) {
die($mysqli->error);
}
$product_id = $product_title = $body_html = $vendor = $product_type = $created_at = $handle = $updated_at = $published_at = $template_suffix = $published_scope = $tags = "";
$mainProdQuery->bind_param("isssssssssss", $product_id, $product_title, $body_html, $vendor, $product_type, $created_at,
$handle, $updated_at, $published_at, $template_suffix, $published_scope, $tags);
if ($mainProdQuery) {
foreach ($dss_product_db_array as $product) {
$product_id = $product['id'];
$product_title = $product['title'];
$body_html = $product['body_html'];
$vendor = $product['vendor'];
$product_type = $product['product_type'];
$created_at = $product['created_at'];
$handle = $product['handle'];
$updated_at = $product['updated_at'];
$published_at = $product['published_at'];
$template_suffix = $product['template_suffix'];
$published_scope = $product['published_scope'];
$tags = $product['tags'];
if (!$mysqli->prepare($mainProdQueryStmt)) {
printf("Errormessage: %s\n", $mysqli->error);
}
$mainProdQuery->execute();
}
}
When you use placeholders you have to use mysqli_prepare(), you can't use mysqli_query(). It looks like you intended to do that, but somehow that code got lost, since you use a variable $mainProdQuery that you never assigned.
You should prepare the query and bind the parameters just once, outside the loop. Then call execute() inside the loop.
$mainProdQueryStmt = "INSERT INTO products (`product_id`, `title`, `body_html`, `vendor`, `product_type`, `created_at`, `handle`, `updated_at`, `published_at`, `template_suffix`, `published_scope`, `tags`)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
product_id = VALUES(product_id),
title = VALUES(title),
body_html = VALUES(body_html),
vendor = VALUES(vendor),
product_type = VALUES(product_type),
created_at = VALUES(created_at),
handle = VALUES(handle),
updated_at = VALUES(updated_at),
published_at = VALUES(published_at),
template_suffix = VALUES(template_suffix),
published_scope = VALUES(published_scope),
tags = VALUES(tags)";
$mainProdQuery = $mysqli->prepare($mainProdQueryStmt);
$mainProdQuery->bind_param("isssssssssss", $product_id, $product_title, $body_html, $vendor, $product_type, $created_at,
$handle, $updated_at, $published_at, $template_suffix, $published_scope, $tags);
foreach ($dss_product_db_array as $product) {
$product_id = $product['id'];
//... more variables here...
$mainProdQuery->execute();
}
You're running the query before it's properly prepared, and then, after the fact, attempting to bind to something that's not the right type, it's not a statement handle but a result set. You need to structure it this way:
$mainProdQueryStmt = "INSERT INTO products (`product_id`, `title`, `body_html`, `vendor`, `product_type`, `created_at`, `handle`, `updated_at`, `published_at`, `template_suffix`, `published_scope`, `tags`)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
product_id = VALUES(product_id),
...
tags = VALUES(tags)";
// Prepare the statement to get a statement handle
$stmt = $mysqli->prepare($mainProdQueryStmt);
foreach ($dss_product_db_array as $product) {
// Bind to this statement handle the raw values (non-escaped)
$stmt->bind_param("isssssssssss",
$product['id'], $product['title'], ...);
// Execute the query
$stmt->execute();
}
Try to avoid creating heaps of throw-away variables an just bind directly to the values in question, like those in $product. The variables do nothing useful and only introduce opportunities for silly mistakes.
Try using PDO(PhP Data Objects) prepared statements. It's less painful to work with and cross database i.e can be used with any RDBMS. See PDO Official Documentation or here
I can conect to my database just fine, but whenever I try to insert data I get a "Call to a member function bind_param() on a non-object" error, which I know means that I must have mistyped the name of a slot, or something, but I just can't see it, I'm connecting locally, do I have to set up something in MyPhP to allow data to be added from a php file? Thanks in advance.
<?php
include 'connect.php';
if (isset($_POST['Slot1'])) {
$Slot1 = $_POST['Slot1'];
}
if (isset($_POST['Slot2'])) {
$Slot2 = $_POST['Slot2'];
}
if (isset($_POST['Slot3'])) {
$Slot3 = $_POST['Slot3'];
}
if (isset($_POST['Slot4'])) {
$Slot4 = $_POST['Slot4'];
}
if (isset($_POST['Slot5'])) {
$Slot5 = $_POST['Slot5'];
}
if (isset($_POST['Slot6'])) {
$Slot6 = $_POST['Slot6'];
}
if (isset($_POST['Slot7'])) {
$Slot7 = $_POST['Slot7'];
}
$stmt = $db->prepare("INSERT INTO `tabel` (Slot1, Slot 2, Slot3, Slot4,Slot5,
Slot6, Slot7)
VALUES (?, ?, ?, ?, ?, ?,?");
$stmt->bind_param('sssssss',$Slot1,$Slot2,$Slot3,$Slot4,$Slot5,$Slot6,$Slot7);
$stmt->execute();
$stmt->close();
header("Location: Display.php")
?>
You have missed one end parenthese
Replace
$stmt = $db->prepare("INSERT INTO `tabel` (Slot1, Slot 2, Slot3, Slot4,Slot5,
Slot6, Slot7)
VALUES (?, ?, ?, ?, ?, ?,?");
To
$stmt = $db->prepare("INSERT INTO `tabel` (Slot1, Slot 2, Slot3, Slot4,Slot5,
Slot6, Slot7)
VALUES (?, ?, ?, ?, ?, ?,?)");
Try to change your query to
$stmt = $db->prepare("INSERT INTO `tabel` (Slot1, Slot 2, Slot3, Slot4,Slot5,Slot6, Slot7)VALUES (?, ?, ?, ?, ?, ?,?)");
I'm having trouble trying to get the following to work:
$stmt = $mysqli->prepare("INSERT INTO member_data (member_id, name, address, telephone, mobile) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE member_data SET name = ?, address = ?, telephone = ?, mobile = ? WHERE member_id = ?");
$stmt->bind_param('ssssssssss', $_SESSION['user_id'], $_POST['new_name'], $_POST['new_address'], $_POST['new_telephone'], $_POST['new_mobile'], $_POST['new_name'], $_POST['new_address'], $_POST['new_telephone'], $_POST['new_mobile'], $_SESSION['user_id']);
$stmt->execute();
$stmt->close();
It doesn't seem to be able to update or insert any values.
I'm sure I've done something wrong, but I've searched and haven't found anything relevant to my issue. Is this the right approach?
EDIT: Working code:
$stmt = $mysqli->prepare("INSERT INTO member_data (member_id, name, address, telephone, mobile) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE name = ?, address = ?, telephone = ?, mobile = ?");
$stmt->bind_param('sssssssss', $_SESSION['user_id'], $_POST['new_name'], $_POST['new_address'], $_POST['new_telephone'], $_POST['new_mobile'], $_POST['new_name'], $_POST['new_address'], $_POST['new_telephone'], $_POST['new_mobile']);
I am receiving error 'Number of variables doesn't match number of parameters in prepared statement'
$stmt = $this->conn->prepare( "INSERT INTO user
(
st1, u1, e1, sa1,
h1, roles_id, name_titles_id, first_name,
last_name, phone, mobile, address_road,
address_area, address_region, post_code, city,
country_id, creation_date, activated_at, modified_date_time,
created_by, referred_by, gender, ad1, status
)
VALUES
(
?, ?, ?, ?,
?, ?, ?, ?,
?, ?, ?, ?,
?, ?, ?, ?,
?, ?, ?, ?,
?, ?, ?, ?, ?
)"
)
$stmt->bind_param('i',$st1);
$stmt->bind_param('s',$u1);
$stmt->bind_param('s',$e1);
$stmt->bind_param('s',$sa1);
$stmt->bind_param('s',$h1);
$stmt->bind_param('i',$roles_id);
$stmt->bind_param('i',$name_titles_id);
$stmt->bind_param('s',$first_name);
$stmt->bind_param('s',$last_name);
$stmt->bind_param('s',$phone);
$stmt->bind_param('s',$mobile);
$stmt->bind_param('s',$address_road);
$stmt->bind_param('s',$address_area);
$stmt->bind_param('s',$address_region);
$stmt->bind_param('s',$post_code);
$stmt->bind_param('s',$city);
$stmt->bind_param('i',$country_id);
$stmt->bind_param('s',$creation_date);
$stmt->bind_param('s',$activated_at);
$stmt->bind_param('s',$modified_date_time);
$stmt->bind_param('i',$created_by);
$stmt->bind_param('i',$referred_by);
$stmt->bind_param('s',$gender);
$stmt->bind_param('s',$ad1);
$stmt->bind_param('i',$status);
Edit:
Just make a small test and it confirms, we can't use multiple bind_param with mysqli.
Not work:
$stmt->bind_param('s',$a);
$stmt->bind_param('s',$b);
Work:
$stmt->bind_param('ss',$a, $b);
Hopefully it'll be useful for future searches.
Your problem is simple. You are trying to do the thing manually, while the number of data asks for the automated process. You have to make a program to create a query for you.
Suppose You have an array with data already. All you need is to define the list of fields to insert
$fields = "st1,u1,e1,sa1,h1,roles_id,name_titles_id,first_name,last_name,phone,";
$fields .= "mobile,address_road,address_area,address_region,post_code,city,";
$fields .= "country_id,creation_date,activated_at,modified_date_time,";
$fields .= "created_by,referred_by,gender,ad1,status" ;
$fields = explode(",",$fields);
and then use some programming. Luckily, it's already done:
include 'safemysql.class.php';
$db = new safeMysql();
$insert = $db->filterArray($_POST,$fields);
$db->query("INSERT INTO user SET ?u", $insert);
And yeah, you are using bind_param wrong way. Correct usage can be seen in the manual page.