PHP Update query is being executed, but the credentials are not updated - php

I have a form tag on my site that leads to the PHP page with email and/or/without description. Based on that the code generates a query, the query needs to update these credidentials. That part of the code works and has been tested. The problem is that the database is not updating the e-mail credidential, but if i put it to update the description it does so. The code has 3 checks, if the user puts only his email, if he puts only his description or puts both. Based on that the code works like this :
<?php
session_start();
include_once 'connection.php';
$id = $_SESSION['user_id'];
if(isset($_POST['emailChange']) || isset($_POST['descChange'])){
$desc = $_POST['descChange'];
$email = $_POST['emailChange'];
if(empty($email)){
$query = "UPDATE users SET description = :descr WHERE user_id= :id ;";
$stmt = $conn->prepare($query);
$stmt->bindParam(":descr", $desc);
} else if(empty($desc)){
$query = "UPDATE users SET user_email= :email WHERE user_id= :id ;";
$stmt = $conn->prepare($query);
$stmt->bindParam(":email", $email);
} else{
$query = "UPDATE users SET description = :descr AND user_email = :email WHERE user_id= :id;";
$stmt = $conn->prepare($query);
$stmt->bindParam(":email", $email);
$stmt->bindParam(":descr", $desc);
}
if(!filter_var($email, FILTER_VALIDATE_EMAIL)){
header("Location: ../profile.php?error=invalidEmail");
exit();
}
$stmt->bindParam(":id", $id);
$stmt->execute();
}
The form itself looks like this :
<form action="assets/upload.php" method="POST">
<input type="text" name="emailChange" class="inputs" id="changeEmail" placeholder = "Enter your new E-mail">
<input type="text" name="descChange" class="inputs" id="changeDesc" placeholder="Enter your description">
<button type="submit" id="btnconfirmCreds" name="changeCreds">Confirm Changes</button>
</form>
The names in the database looks like this :
[user_id][user_username][user_email][user_password][role_id][user_image][description][num_of_posts]

You should set up PDO error logging.
From Comments; paraphrased for clarity:
My user_id column is int(11) auto_increment
Your problem is you are trying to insert a string value into a numerical column in MySQL.
user_id / id in database parlance is usually a numerical value, but you have not set the value type in your SQL, so it defaults to string.
Because your :id value is a numeric value in PHP you need to do this:
$stmt->bindParam(":id", $id, 'i'); // i = integer type.
It is highly recommended to explicitly set the value of the data type supplied each and every time .
If the data given to the PDO does not match the value-type given, then the PDO transaction will void and will not complete. This is a security measure.
For example:
$id = 3;
$stmt->bindParam(":id", $id);
This is the same as saying:
$stmt->bindParam(":id", 3, 's'); // default type value is 's' for string.
Obviously the value 3 is not a string so this transacion ($stmt) is never performed.
i assume it's because it views the description as a special word, if that is true then i should change the name in my database. Thoughts?
"description" is neither a Keyword or a reserved word in MySQL 5.5-->5.7 (in MySQL 8.0.4 DESCRIPTION is a keyword but is not a reserved word)
You can view a list of MySQL Keywords and Reserved words .

Some notes about the logic:
if(isset($_POST['emailChange']) || isset($_POST['descChange']))
{
$desc = $_POST['descChange'];
$email = $_POST['emailChange'];
...
First you check, if at lease one parameter exists, but then you access both. You can argue, that the form send always both, but never believe user input: Manipulating data is so easy!
Either change your if(...) to:
if( isset($_POST['emailChange']) && isset($_POST['descChange']) )
The following line is a shorter form with identical semantics:
if( isset( $_POST['emailChange'], $_POST['descChange'] ) )
The other ways is to change the 2 other lines, for example by:
$desc = isset($_POST['descChange']) ? $_POST['descChange'] : '';
$email = isset($_POST['emailChange']) ? $_POST['emailChange'] : '';

Related

update specific field data on sql database

so i have a table of data in web ui
as soon as I click the button. all of the field data in "Status Email" changed. not just selected field that i meant.
this is the sintaks sql
if($mail->Send())
{
$query = "UPDATE nearly_inactive SET EmailSent = 'Sudah Kirim Email' WHERE EmailSent = 'Belum Kirim Email'";
$update = $con->prepare($query);
$update->execute();
}
how can i get the "update" only the data that I click on the button??
Get specific field
In order to get the specific field from a MYSQL database
Select column FROM databse WHERE x = y
Example:
SELECT id, firstname, lastname FROM MyGuests WHERE lastname='Doe'
The issue
It's best to get a unique identifier, which no other user has used. For example a 10 digit user id code. Check that this code doesn't exist, for it to be unique.
UPDATE:
Easily use the UNIQUE SQL tag to resolve this issue.
CREATE TABLE X (
ID INT UNIQUE
)
Example:
SELECT id, firstname, lastname FROM MyGuests WHERE id=ryan9273__2
Update a specific field
Now that we have fixed the issue we can easily
UPDATE x SET y=z WHERE id=b
Lets fix your code:
UPDATE nearly_inactive SET EmailSent = 'Sudah Kirim Email' WHERE EmailSent = 'Belum Kirim Email'
Lets make it more dynamic
UPDATE nearly_inactive SET :email = :emailaddr WHERE EmailSent = :id
final code:
$query = $con->prepare("UPDATE nearly_inactive SET :email = :emailaddr WHERE EmailSent = :id");
$query->bindParam(':email', $email, PDO::PARAM_STR);
$query->bindParam(':emailaddr', $emailaddr, PDO::PARAM_STR);
$query->bindParam(':id', $id, PDO::PARAM_STR);
$update->execute();
Security Matters
You are using PDO, so use bindParam aswell. Secret code enthusiast answer isn't as secure as the current code i provided!
Practice Makes Perfect
Please don't copy my code right away. learn from it and code it again ! Make it better. Also check the official PHP documentation for more info on these topics
Stay safe !
Regards,
Ryan
you need to determine which record need to be changed based on their unique ID. usually it's the primary key of the table. so, If your primary key is enroller_id, then pass the value of enroller_id, and put it inside your sql.
if($mail->Send())
{
//prepare your query
$statement = $this->mysqli->prepare("UPDATE nearly_inactive SET EmailSent = 'Sudah Kirim Email' WHERE enroller_id = ?");
//check for statement preparation
if ($statement === false) {
trigger_error($this->mysqli->error, E_USER_ERROR);
return;
}
//bind the value
$statement->bindParam("i", $id);
//get id for the query
$id = your_field_enroller_id;
//execute the statement
$statement->execute();
}
where enroller_id is your table primary key, and $id is the value of that field primary key.
<?php
$servername="localhost";
$username="root";
$password="";
$dbname="demon";
//CREATE CONNECTION
$conn=new mysqli($servername,$username,$password,$dbname);
//CHECK CONNECTION
if ($conn->connect_error)
{
die("connection failed:".$conn->connect_error);
}
$sql="UPDATE student set NAME='JohnRambo' where STUDENT_ID=1000";
$result=$conn->query($sql);
if ($result===TRUE)
{
echo"NEW RECORD CREATED SUCCESSFULLY";
}
else
{
echo "ERROR:".$sql."<br>".$conn->error;
}
$conn->close();
?>

UPDATE a single specific MySQL Cell wont work

im fairly new to PHP/MySQL but i found no answers in the net for my problem:
I've got a form with 4 textfields
<form method="post" action="updateuserdatatest.php">
<input type="text" value="Hans" name="username">
<input type="text" value="1234" name="password">
<input type="text" value="desired cell" name="desiredcell">
<input type="text" value="desired value" name="desiredvalue">
<input type="submit">
</form>
I want to update the named "desired cell" with the "desired value".
So i have to type in the username, his password, a column name (i.e. "streetname","postcode" or "city") and after that the stringvalue which shall be submitted to the database.
I use this code:
$pdo = new PDO(everything is OK here! - Checked this out many times);
$sql = 'UPDATE user SET :desiredcell = :desiredvalue WHERE username = :username AND password = :password';
$stmt = $pdo->prepare($sql);
$stmt->bindValue(":desiredcell", $_POST['desiredcell'], PDO::PARAM_STR);
$stmt->bindValue(":desiredvalue", $_POST['desiredvalue'], PDO::PARAM_STR);
$stmt->bindValue(":username", $_POST['username'], PDO::PARAM_STR);
$stmt->bindValue(":password", $_POST['password'], PDO::PARAM_STR);
$stmt->execute();
if ($stmt->errno) { echo "FAILURE!!! " . $stmt->error;
}
else echo "Updated {$stmt->affected_rows} rows";
$response = array();
$response['success'] = true;
echo json_encode($response);
?>
This does not work!
But when i change the sql query to a specific columnname like 'UPDATE user SET streetname = :desiredvalue WHERE username = :username AND password = :password';
then it works! why?
i want to type in the cellname which has to be updated manually!
i tried this with mysqli queries before like UPDATE user SET ?=? WHERE password=? AND username=? same problem there
What am i doing wrong?
Thanks in advance.
EDIT:
seems that i cant post images in a comment, so i make another answer:
this is my dummy table,
when i try to insert the column variable like your example nothing happens inside the table, but i still get the success response.
$column = in_array($_POST['desiredcell'], ['streetname', 'postcode','state']) ? $_POST['desiredcell'] : 'streetname';
$sql = 'UPDATE user SET $column = :desiredvalue WHERE username = :username AND password = :password';
$stmt = $pdo->prepare($sql);
$stmt->bindValue(":desiredvalue", $_POST['desiredvalue'], PDO::PARAM_STR);
$stmt->bindValue(":username", $_POST['username'], PDO::PARAM_STR);
$stmt->bindValue(":password", $_POST['password'], PDO::PARAM_STR);
$stmt->execute();
any tips? =/
EDIT:
Found the solution:
$sql = 'UPDATE user SET '.$column.' = :desiredvalue WHERE username = :username AND password = :password';
thank you guys.
As it mentioned it the comments, you can't bind column names. You should use a variable and make sure the input is a real column name (for security reasons)
Example:
<?php
$column = in_array($_POST['desiredcell'], ["column1", "column2"]) ? $_POST['desiredcell'] : "column1";
$sql = "UPDATE user SET $column = :desiredvalue WHERE username = :username AND password = :password'";
Also bear in mind that storing a plain text passwords in a database is a real bad idea. Check password_hash function.

Update MYSQL row with non null value only

i have a table contain huge number of rows and i need to update row with specific ID, for example assume i have a row with below details:
Id= 1
Name= lessa
Address = USA
now i used below PHP code to update the row:
<?php
$con = mysqli_connect("localhost","MyUserName","MyPassword","DB");
$id = '1';
$name = "";
$address = "UK";
// update only non value items
$r=mysqli_query($sql);
mysqli_close($con);
?>
now my issue since the value of address is changed from USA to UK i need to update this value only, also since the name value is nothing the name should be remain so after update the row should be like below:
ID=1
Name = lessa
Address = UK
Also if in another time the name value changed and address remain the same i need to update the name only.
also assume i have 100 column not only three as this example.
any help for write the update statement will be appreciated.
Update:
I use below code but no update happen:
<?php
$con = mysqli_connect(DB info);
$id = 'jo_12';
$name = "";
$address = "UK";
$sql = "UPDATE info
SET name = IF(? = '', name, ?),
address = IF(? = '', address, ?)
WHERE id = ?";
$stmt = $con->prepare($sql);
$stmt->bind_param("ssssi", $name, $name, $address, $address, $id);
$stmt->execute();
mysqli_close($con);
?>
Put tests in the UPDATE query:
$sql = "UPDATE yourTable
SET name = IF(? = '', name, ?),
address = IF(? = '', address, ?)
WHERE id = ?";
$stmt = $con->prepare($sql) or die ($con->error);
$stmt->bind_param("sssss", $name, $name, $address, $address, $id);
$stmt->execute();
The IF() tests assign the old value of the column back to it if the variable is empty.
Try to use this SQL query:
UPDATE table_name SET Address='UK' WHERE ID=1
You can of course substitute ID=1 for any other number.

PDO DELETE also creates a new INSERT

I have a strange problem where every time I do a simple DELETE query to delete WHERE email =. For some reason after deletion it also does a new INSERT with the same email? There is no INSERT anywhere and there are no triggers... Does anybody know why this happens? The table has a email and a nr with auto_increment.
$check_email = $_POST['email'];
$query = "SELECT `email` FROM `newsletter` WHERE email = '$check_email';";
$sth = $dbh->prepare($query);
$sth->execute();
$row = $sth->fetch(PDO::FETCH_ASSOC);
$check_users_email = $row['email'];
if($check_users_email != ''){
$query_update = "DELETE FROM `newsletter` WHERE email = '$check_users_email';";
}
$sth = $dbh->prepare($query_update);
$sth->execute();
Before deletion: email=test#email.com | nr=1
After deletion: email=test#email.com | nr=2
it might be in your sql string, since you're using prepared statements.
in PDO you should use named or unnamed placeholders. then after preparing the query, you pass the prams as an array when you execute the statement.
If you're using PDO, no need to use single quotes. just the column name and for the search value just use placeholders and then pass on the values on execution as an array.
NOTE: i renamed the PDO object $sth inside the 'if' statement, just to avoid name clash. also i moved the last 2 lines inside the 'if' statement, because you need the value of the sql string '$query_update' which will not be available if that statement returned false.
also to check if the variable $check_users_email is empty, you can use empty() or strlen().
try this:
$check_email = $_POST['email'];
$query = "SELECT email FROM newsletter WHERE email = :check_email";
$sth = $dbh->prepare($query);
$sth->execute(array(':check_email' => $check_email));
$row = $sth->fetch(PDO::FETCH_ASSOC);
$check_users_email = $row['email'];
if($check_users_email != ''){
$query_update = "DELETE FROM newsletter WHERE email = :check_users_email";
$sth2 = $dbh->prepare($query_update);
$sth2->execute(array(':check_users_email' => $check_users_email));
}

PDO - passing a field name as a variable

I'm just migrating my code from mysql_query style commands to PDO style and I ran into a problem. THe old code looked like this :
$query_list_menu = "SELECT ".$_GET['section_name']." from myl_menu_hide_show WHERE id='".$_GET['id']."'";
And the updated code looks like below. Apparently it's not working. I store in $_GET['section_name'] a string that represents a field name from the database. But I think there is a problem when I pass it as a variable. Is the below code valid ? Thanks.
$query_list_menu = "SELECT :section_name from myl_menu_hide_show WHERE id=:id";
$result_list_menu = $db->prepare($query_list_menu);
$result_list_menu->bindValue(':section_name', $_GET['section_name'] , PDO::PARAM_STR);
$result_list_menu->bindValue(':id', $_GET['id'] , PDO::PARAM_INT);
$result_list_menu->execute();
If $_GET['section_name'] contains a column name, your query should be:
$query_list_menu = "SELECT " . $_GET['section_name'] . " from myl_menu_hide_show WHERE id=:id";
Giving:
$query_list_menu = "SELECT :section_name from myl_menu_hide_show WHERE id=:id";
$result_list_menu = $db->prepare($query_list_menu);
$result_list_menu->bindValue(':id', $_GET['id'] , PDO::PARAM_INT);
$result_list_menu->execute();
The reason is that you want the actual name of the column to be in the query - you'd changed it to be a parameter, which doesn't really make much sense.
I'll also add that using $_GET['section_name'] directly like this is a massive security risk as it allows for SQL injection. I suggest that you validate the value of $_GET['section_name'] by checking it against a list of columns before building and executing the query.
There is no good and safe way to select just one field from the record based on the user's choice. The most sensible solution would be to select the whole row and then return the only field requested
$sql = "SELECT * from myl_menu_hide_show WHERE id=?";
$stmt = $db->prepare($query_list_menu);
$stmt->execute([$_GET['id']]);
$row = $stmt->fetch();
return $row[$_GET['section_name']] ?? false;

Categories