PDO UPDATE query deletes value(s) instead of updating - php

Can anyone see what is wrong with this script? I have verified that the data is in the $_POST array and the query-string is also formed correctly, but for some reason when this gets executed, the column(s) to be updated get emptied in the database..?
/* Get the ID for the house to be modified by using a hidden-field 'hiddenDescription' */
$stmt = $db->prepare('SELECT id FROM talot WHERE kuvaus = :description');
$stmt->bindParam(':description', $_POST['hiddenDescription'], PDO::PARAM_STR);
$stmt->execute();
if($row = $stmt->fetch(PDO::FETCH_ASSOC)){
// The column names in the database
$col_names = array("kaupunki", "osoite", "pintaAla", "koko", "vuosi", "hinta", "otsikko", "kuvaus", "valittaja");
$comma = ",";
$i = 0;
$unprepared = 'UPDATE talot SET ';
/* Go through the POST -array and add the column name and :$key (for binding) into the query string. Also add comma */
foreach($_POST as $key => $value){
if(!empty($_POST[$key])){
// Skip hiddenDescription
if($key != 'hiddenDescription'){
$unprepared .= "$col_names[$i] = :$key".$comma;
}
// If $key was hiddenDescription decrement $i;
else{
$i--;
}
}
$i++;
}
// chop the last comma.
$prepared = chop($unprepared, ',');
$prepared .= ' WHERE id = :id';
$stmt = $db->prepare($prepared);
$i = 0;
/* Go through the POST -array and bind values that are not empty. Again skip hiddenDescription. */
foreach($_POST as $key => $value){
if(!empty($value)){
if($key != 'hiddenDescription'){
$stmt->bindParam(":$key", $value, PDO::PARAM_STR);
}
else{
$i--;
}
}
$i++;
}
// Bind the ID received in the first database query.
$id = (int)$row['id'];
$stmt->bindParam(":id", $id, PDO::PARAM_INT);
$result = $stmt->execute();
if($result){
echo 1;
}
Thanks!

Alright.. Solved this hehe.
This:
foreach($_POST as $key => $value){
if(!empty($value)){
if($key != 'hiddenDescription'){
$stmt->bindParam(":$key", $value, PDO::PARAM_STR);
}
else{
$i--;
}
}
$i++;
}
Changed to this:
foreach($_POST as $key => &$value){
if(!empty($value)){
if($key != 'hiddenDescription'){
$stmt->bindParam(":$key", $value, PDO::PARAM_STR);
}
else{
$i--;
}
}
$i++;
}
(bindParam needs &$variable):

Related

Update database with two array parameters

I´m trying to update my database with information that is send via a form.
My problem is that i don´t get how I can loop both arrays at the same. I have tried nesting foreach-loops with no success.
I then have this to work with
$display = $_POST["show"] ?? "";
$id = array_keys($_POST["show"]);
if ($action == "submit") {
foreach ($display as $key => $value) {
$stmt = $db->prepare("UPDATE picture SET display = ? WHERE id = ?");
$stmt->bindParam($display, $id)
$stmt->execute();
}
}
You can iterate over array and get keys and values at the same time:
$display = $_POST["show"] ?? [];
// Also you can check if `$display` is not empty
if ($action == "submit" && $display) {
// prepare statement ONCE
$stmt = $db->prepare("UPDATE picture SET display = ? WHERE id = ?");
foreach ($display as $key => $value) {
// execute statement as many times as you want with your params
$stmt->execute([$value, $key]);
}
}
If I saw correctly this is what you want:
<?php
try {
$display = isset($_POST['show']) ? $_POST['show'] : [];
if ($action === 'submit' && !empty($display)) {
$db->beginTransaction();
$stmt = $db->prepare('
UPDATE picture
SET display = :display
WHERE id = :id;
');
foreach ($display as $id => $show) {
$stmt->bindParam(':display', $show);
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->execute();
}
$db->commit();
}
} catch(PDOException $e) {
echo $e->getMessage();
$db->rollBack();
}

PDO Dynamic Query Building with prepared statements

i am basicly trying to update user information with a dynamic query.Everything good but when i try to execute query its return always false.
function updateUser($username, $email, $pass){
$arr = [];
$values = [];
$params = [];
if(isset($username))
{
array_push($arr, "userName = :username");
array_push($values, $username);
array_push($params, ":username");
}
if(isset($email))
{
array_push($arr, "userEmail = :email");
array_push($values, $email);
array_push($params, ":email");
}
if(isset($pass))
{
array_push($arr, "userPassword = :pass");
array_push($values, $pass);
array_push($params, ":pass");
}
$sql = "UPDATE users SET " . implode(", ", $arr) . " WHERE userId = :uId";
$query = $db->prepare($sql);
foreach ($params as $key) {
foreach ($values as $value) {
$query->bindValue($key, $value, PDO::PARAM_STR);
}
}
$query->bindValue(":uId", $_SESSION["userId"]);
if($query->execute() && $query->rowCount() > 0)
return true;
else
return false // always false return
}
this is my array datas:
this is funny. i can't answer my question.
i found the solution. it is because of double foreach loop.
$i = 0;
foreach ($params as $key) {
$query->bindValue($key, $values[$i], PDO::PARAM_STR);
$i++;}

execute foreach loop in PDO query

I'm trying to store serialize form data into mysql using PDO. DB table column name, field name everything is dynamic.
update.php
$data = $_POST['data'];
parse_str($_POST['data'], $searcharray);
foreach($searcharray['column_name'] as $key=>$value) {
echo $value;
}
foreach($searcharray['data_name'] as $k=>$v) {
echo $v;
}
Here this below foreach loop returns colname_1colname_2colname_3 (without comma)
foreach($searcharray['column_name'] as $key=>$value) {
echo $value;
}
and another foreach loop returns biketvssuzuki (without comma)
foreach($searcharray['data_name'] as $k=>$v) {
echo $v;
}
I want to update bike in colname_1 and tvs in colname_2 and suzuki in colname_2. How do I execute those above two foreach loops in PDO query?
try
{
$update_query = $dbh->prepare("UPDATE ".REQUIREMENTS_DB." SET colname_1 = ?, colname_2 = ?, colname_3 = ? WHERE id = :id");
$update_query->bindParam(':id', $id);
$update_query->execute();
echo "Updated Successfully";
}
catch (PDOException $e)
{
die('Error ' . $e->getMessage());
}
Are you looking for something like this?
$sql = "UPDATE ".REQUIREMENTS_DB." SET ";
for ($i = 0; $i < count($searcharray['column_name']); $i++) {
$sql .= $searcharray['column_name'][$i]." = ".$searcharray['data_name'][$i];
if ($i < (count($searcharray['column_name'])-1)) $sql .= ", "
}
$sql .= "WHERE id = :id";
$update_query = $dbh->prepare($sql);
...
This is very basic code and could/should be improved a lot.

PHP MySQLi function get user data can't work

i am using This code for showing user data record but this code is not work on my side
I want to echo out specific user data. I created a function where I insert multiple arguments (each argument represents a column in the database) and then echo whichever column I want with a simple line of code.
Index.php
include('function.php');
$conn = new MySQLi(localhost, root, password, database);
$user_id = $_SESSION['login_user']; // like 1
$user = user_data($conn, $user_id, 'login', 'pass', 'nikename', 'email');
if(empty($user)){
echo 'error'; // always showing this error
}else{
echo $user['nickename'];
}
Always Showing echo 'error';
function user_data($conn, $user_id){
$data = array();
$user_id = (int)$user_id;
$func_num_args = func_num_args();
$func_get_args = func_get_args();
if ($func_num_args > 1) {
unset($func_get_args[0]);
unset($func_get_args[1]);
$valid = array('login', 'pass', 'nikename', 'email');
$fields = array();
foreach($func_get_args as $arg) {
if(in_array($arg, $valid)) $fields[] = $arg;
}
$fields = '`' . implode ('`, `', $fields) . '`';
if($stmt = $conn->prepare("SELECT $fields FROM `users` WHERE `user_id` = ?")) {
$stmt->bind_param('si', $fields, $user_id);
$stmt->execute();
//here I am trying to convert the result into an array
$meta = $stmt->result_metadata();
while ($field = $meta->fetch_field()) {
$parameters[] = &$row[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $parameters);
while ($stmt->fetch()) {
foreach($row as $key => $val) {
$x[$key] = $val;
}
$results[] = $x;
}
return $results;
$stmt->close();
}
}
}
Seeing and analyzing your code several times, I think the below will solve your issue.
Add this before your while/fetch loop
$row = array();
stmt_bind_assoc($stmt, $row);
so your code will look like this
$row = array();
stmt_bind_assoc($stmt, $row);
while ($stmt->fetch()) {
foreach($row as $key => $val) {
$x[$key] = $val;
}
$results[] = $x;
}
Also make sure you read the full documentation of bind_param on php.net here
Thanks and Best Regards
I guess, instead of
if($stmt = $conn->prepare("SELECT $fields FROM `users` WHERE `user_id` = ?")) {
$stmt->bind_param('si', $fields, $user_id);
you should go with
if($stmt = $conn->prepare("SELECT $fields FROM `users` WHERE `user_id` = ?")) {
$stmt->bind_param('i', $fields, $user_id);
Bind parameters. Types: s = string, i = integer, d = double, b = blob
As far as you have one argument with type INT you need to pass 'i' as a first parameters.
Try debugging over line by line in that function where you will get exact flaw by var_dump().

insert array values in a separate row

Here, I'm inserting the dynamic array values into database table. it inserting the datas into database table perfectly. But, I need a little bit modification with this code.. it inserting the datas with ,. But, I want to store the array values in a separate row.
NOW I GOT
id field_name
1 aaa, bbb, ccc, ddd
BUT I NEED
id field_name
1 aaa
2 bbb
3 ccc
4 ddd
How can I achieve that?
$choose_general_rules = $_POST['choose_general_rules'];
$choose_no_of_questions = $_POST['choose_no_of_questions'];
$choose_mark_questions = $_POST['choose_mark_questions'];
$choose_question_name = $_POST['choose_question_name'];
$question = array();
foreach($choose_question_name as $value) {
$question[] = $value;
}
$result_question = implode(',', $question);
$answer_1 = $_POST['answer_1'];
$answer_one = array();
foreach($answer_1 as $value) {
$answer_one[] = $value;
}
$result_answer_one = implode(',', $answer_one);
$answer_2 = $_POST['answer_2'];
$answer_two = array();
foreach($answer_2 as $value) {
$answer_two[] = $value;
}
$result_answer_two = implode(',', $answer_two);
$answer_3 = $_POST['answer_3'];
$answer_three = array();
foreach($answer_3 as $value) {
$answer_three[] = $value;
}
$result_answer_three = implode(',', $answer_three);
$answer_4 = $_POST['answer_4'];
$answer_three = array();
foreach($answer_3 as $value) {
$answer_three[] = $value;
}
$result_answer_three = implode(',', $answer_three);
try
{
$stmt = $dbh->prepare("INSERT INTO choose_the_correct_answer ( reference_id, general_rules, no_of_questions, mark_each_questions, question, answer_option_one, answer_option_two, answer_option_three, answer_option_four ) VALUES ( :ref_id, :choose_general_rules, :choose_no_of_questions, :choose_mark_questions, :choose_question_name, :answer_1, :answer_2, :answer_3, :answer_4 )");
$stmt->bindParam(':ref_id', $lastid, PDO::PARAM_INT);
$stmt->bindParam(':choose_general_rules', $choose_general_rules, PDO::PARAM_STR);
$stmt->bindParam(':choose_no_of_questions', $choose_no_of_questions, PDO::PARAM_STR);
$stmt->bindParam(':choose_mark_questions', $choose_mark_questions, PDO::PARAM_STR);
$stmt->bindParam(':choose_question_name', $result_question, PDO::PARAM_STR);
$stmt->bindParam(':answer_1', $result_answer_one, PDO::PARAM_STR);
$stmt->bindParam(':answer_2', $result_answer_two, PDO::PARAM_STR);
$stmt->bindParam(':answer_3', $result_answer_three, PDO::PARAM_STR);
$stmt->bindParam(':answer_4', $result_answer_three, PDO::PARAM_STR);
$stmt->execute();
}
catch(PDOException $e)
{
echo "Error Inserting datas into database :" .$e->getMessage();
}
You should change everything in this code:
implode(',', $question);
into
implode("\n", $question);
Of course the same
implode(',', $answer_one);
into
implode("\n", $answer_one);
and so on

Categories