Unable Update row in mysql database - php

I'm not sure what am I doing wrong, however when I try to make an update with my API to my database the data is not being updated, I already checked if the name of my table or the name of the columns match and everything looks ok, I also checked if the data it's being received and yes, it is, however it is not updating, do you guys see the error in my code?
$msg['message'] = '';
$storeId = $data->storeId;
$id = $data->id;
//UPDATE CLIENT BY ID
$db_connection = new Database();
$conn = $db_connection->dbConnection();
$update_post = "UPDATE `client` SET name = :name, lastName = :lastName, phoneNumber = :phoneNumber, contactEmail = :contactEmail, address = :address, taxId = :taxId WHERE id = :id";
$update_post_stmt = $conn->prepare($update_post);
//DATA BINDING
$update_post_stmt->bindValue(':name', $data->name,PDO::PARAM_STR);
$update_post_stmt->bindValue(':lastName', $data->lastName,PDO::PARAM_STR);
$update_post_stmt->bindValue(':phoneNumber', $data->phoneNumber,PDO::PARAM_STR);
$update_post_stmt->bindValue(':contactEmail', $data->contactEmail,PDO::PARAM_STR);
$update_post_stmt->bindValue(':address', $data->address,PDO::PARAM_STR);
$update_post_stmt->bindValue(':taxId', $data->taxId,PDO::PARAM_STR);
$update_post_stmt->bindValue(':id', $data->id,PDO::PARAM_INT);
if($update_post_stmt->execute()){
$msg['message'] = 'Updated Successfully';
}else{
$msg['message'] = 'Unable to Update';
}
$closeConnection = $db_connection->closeInstance($conn);
// ECHO MESSAGE IN JSON FORMAT
echo json_encode($msg);
By the way, I'm getting the "Updated Successfully" message

First thing that stands out to me on this is you are declaring your "type" for each field as a PDO::Param_Int, meaning that it is trying to take in your "name", "lastname", "emailaddress", and "address" as an integer instead of a string. This would likely lead to a type-casting error in your code. Try replacing those fields with PDO::PARAM_STR, and you should be closer to a resolution. I believe the data binding will wrap things in the appropriate strings for you as well.

Related

How to make PHP POST request work properly in CRUD API as layer for connecting to MySQL database?

I cannot POST values to database via Postman.
Recently I started building CRUD api for practicing purposes. I have found few good tutorials on how to make connection to database with PHP. I managed to build MySQL DB with phpMyAdmin and to connect it with PHP. Also GET request is returning values from database:
http://ivanzarkovic.com/movies/fetch_all_movies.php
In Postman I have tried to add
http://ivanzarkovic.com/movies/add_movie.php?movie_name=SomeName&genre=SF&year=2005&rating=4.6
or bulk in JSON form.
I though that I am making mistake with type of data, so I've changed type in DB to string (VARCHAR), but it didn't solved problem.
if(isset($_POST['movie_name'])&&isset($_POST['genre'])&&isset($_POST['year'])&&isset($_POST['rating'])){
$movieName = $_POST['movie_name'];
$genre = $_POST['genre'];
$year = $_POST['year'];
$rating = $_POST['rating'];
//Query to insert a movie
$query = "INSERT INTO movies( movie_name, genre, year, rating) VALUES (?,?,?,?)";
//Some code here
}else{
//Mandatory parameters are missing
$response["success"] = 0;
$response["message"] = "missing mandatory parameters";
}
I am expecting to commit new entry to a database, but it is stuck to "missing mandatory parameters". isset($_POST['movie_name']) is returning false.
The example URL you provided has the data as query parameters.
This means you should be accessing $_GET, not $_POST.
Your code is correct for accepting the data via post, is can you share you postman request?
Example:
if (isset($_GET['movie_name']) && isset($_GET['genre']) && isset($_GET['year']) && isset($_GET['rating'])) {
$movieName = $_GET['movie_name'];
$genre = $_GET['genre'];
$year = $_GET['year'];
$rating = $_GET['rating'];
//Query to insert a movie
$query = "INSERT INTO movies( movie_name, genre, year, rating) VALUES (?,?,?,?)";
//Some code here
} else {
//Mandatory parameters are missing
$response["success"] = 0;
$response["message"] = "missing mandatory parameters";
}

how to update multiple data using php

i am a newbie in here and i have a problem that me myself cannot find the exact solution... here it is... i need to build a system that will update all the staff information. through this system, a staff in human resource department will enter all the staffs information. i have been create this code to update the staffs information but it seems not function with what i really want.... i just want to update by rows however, it turns to update all rows in the database...
<?php
session_start();
include ("includes/database.php");
include ("includes/security.php");
include ("includes/config.php");
$nama=$_SESSION["nama"];
$pwd=$_SESSION["status"];
$nama=$_POST["st_nama"];
$siri1=$_POST["st_siri"];
$siri2=$_POST["st_siri2"];
$siri3=$_POST["st_siri3"];
$jawatan=$_POST["st_jawatan"];
$gred=$_POST["st_gred"];
$gredh=$_POST["st_gredh"];
$gelaran=$_POST["st_gelaran"];
$elaun=$_POST["st_elaun"];
$id=$_GET["id"];
$dataPengguna2= mysql_query("SELECT * FROM tbl_rekod where id='$id'");
mysql_query("UPDATE tbl_rekod set st_nama='$nama', st_siri='$siri1', st_siri2='$siri2', st_siri3='$siri3', st_jawatan='$jawatan', st_gred='$gred', st_gredh='$gredh', st_gelaran='$gelaran', st_elaun='$elaun' WHERE id='$id'") or die (mysql_error());
$status = "REKOD BERJAYA DIKEMASKINI!<br/><a href = 'stafflogin.php'><strong>KEMBALI KE LAMAN UTAMA</strong></a>";
?>
This will help fix your sql injection issue, and may also fix update 1 vs multiple rows issue. This method uses the PDO library in PHP. You can see more info on using PDO on the PHP site. It replaces the mysql_ set of commands which are no longer included in the PHP releases.
// Below replaces the mysql_connect() so it requires db credentials filled in
try {
$host = 'hostname';
$db = 'databasename';
$user = 'username';
$pass = 'password';
$con = new PDO("mysql:host=$host;dbname=$db",$user,$pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));
}
// This replaces the die("error message") potion of a mysql_connect() set-up
catch (Exception $e) {
$_errors['connect']['message'] = $e->getMessage();
$_errors['connect']['error_code'] = $e->getCode();
}
$nama = $_SESSION["nama"];
$pwd = $_SESSION["status"];
$nama = $_POST["st_nama"];
$siri1 = $_POST["st_siri"];
$siri2 = $_POST["st_siri2"];
$siri3 = $_POST["st_siri3"];
$jawatan = $_POST["st_jawatan"];
$gred = $_POST["st_gred"];
$gredh = $_POST["st_gredh"];
$gelaran = $_POST["st_gelaran"];
$elaun = $_POST["st_elaun"];
$id = $_GET["id"];
// You should do just a preliminary check that the id is a numeric value
// No sense in continuing if someone tries to foil the natural
// order of your code
if(is_numeric($id)) {
// The next 3 lines would be equivalent to the mysql_query("statement here")
// as well as a more robust version of mysql_real_escape_string(). It does more,
// but for sake of explanation it does that and more.
$dataPengguna2 = $con->prepare("SELECT * FROM tbl_rekod where id=:id");
// Binding paramaters basically sanitizes the value being inserted into your query
$dataPengguna2->bindParam(':id',$id);
$dataPengguna2->execute();
// There is no indication of what you are doing with the select above
// Set up the update statement
$query = $con->prepare("UPDATE tbl_rekod set st_nama=:st_nama, st_siri=:st_siri, st_siri2=:st_siri2, st_siri3=:st_siri3, st_jawatan=:st_jawatan, st_gred=:st_gred, st_gredh=:st_gredh, st_gelaran=:st_gelaran, st_elaun=:st_elaun WHERE id=:id");
// Bind all the values to sanitize against injection
// You could do a function that loops through an array of values,
// but this is one way to do it manually
$query->bindParam(':st_nama',$nama);
$query->bindParam(':st_siri',$siri1);
$query->bindParam(':st_siri2',$siri2);
$query->bindParam(':st_siri3',$siri3);
$query->bindParam(':st_jawatan',$jawatan);
$query->bindParam(':st_gred',$gred);
$query->bindParam(':st_gredh',$gredh);
$query->bindParam(':st_gelaran',$gelaran);
$query->bindParam(':st_elaun',$elaun);
$query->bindParam(':id',$id);
$query->execute();
// Print out error info. There may be something of value here
// that may help you figure out why it's trying to update all your rows
// instead of just the one.
print_r($query->errorInfo());
$status = "REKOD BERJAYA DIKEMASKINI!<br/><a href = 'stafflogin.php'><strong>KEMBALI KE LAMAN UTAMA</strong></a>";
} ?>

Having problems going from mysqli_query to mysqli_prepare

I'm new to PHP and made a simple php site that allows me to submit a form and delete data stored in a database. I was told it was better to use prepared statements to avoid SQL Injection.
I updated my delete and it still works, not sure if it's totally right:
<?php
include("dbconnect.php");
$getid = $_GET["id"];
$delete = mysqli_prepare($database,"DELETE FROM contacts WHERE id IN ($getid)");
mysqli_stmt_execute($delete);
header("Location:http://localhost/address-book");
exit;
?>
But I can't seem to get the add to database feature to work. I tried a variety of different ways to write it, but I'm sure that I'm missing something simple. Here's the unsafe code that I originally wrote:
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
include("inc/dbconnect.php");
// assigns form data to table columns
$assign = "INSERT INTO contacts(firstName,lastName,email,phone,birthday) VALUES ('$_POST[firstName]','$_POST[lastName]','$_POST[email]','$_POST[phone]','$_POST[birthday]')";
//execute query
if (mysqli_query($database,$assign)) {
header("Location:http://localhost/address-book/");
exit;
} else {
exit;
}
?>
If someone could guide me in the right direction I'd be thankful. I'm new to all of this.
UPDATED: I've updated my original code and came up with this instead for delete:
<?php
include("dbconnect.php");
$getid = $_GET["id"];
$delete = mysqli_prepare($database,"DELETE FROM contacts WHERE id IN (?)");
mysqli_stmt_bind_param($delete, 's', $getid);
mysqli_stmt_execute($delete);
header("Location:http://localhost/address-book");
exit;
?>
and the add feature:
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
include("inc/dbconnect.php");
$firstName = "$_POST[firstName]";
$lastName = "$_POST[lastName]";
$email = "$_POST[email]";
$phone = "$_POST[phone]";
// assigns form data to table columns
$assign = mysqli_prepare($database,"INSERT INTO contacts(firstName,lastName,email,phone) VALUES (?,?,?,?)");
mysqli_stmt_bind_param($assign, 'ssss', $firstName, $lastName, $email, $phone);
mysqli_stmt_execute($assign);
exit;
}
?>
A simple Prepare statement is something along the lines of
$query = $this->db->prepare("Query here WHERE something = ?") - note this example is taken from my site so you'll likely have something else instead of $this->->prepare.
The key thing is that the "= something " is denoted as a question mark.
You then bind the value of that question mark to the query
$query->bindValue(1, passed in parameter)
As a fully working example:
//function to add 1 to downloads each time a file is downloaded
public function addToDownload($filename){
$query = $this->db->prepare('UPDATE trainingMaterial SET downloads = downloads + 1 WHERE filename = ?');
$query->bindValue(1, $filename);
try{
$query->execute();
}catch(PDOException $e){
die($e->getMessage());
}
}
Your query `$assign = "INSERT INTO contacts(firstName,lastName,email,phone,birthday) VALUES ('$_POST[firstName]','$_POST[lastName]','$_POST[email]','$_POST[phone]','$_POST[birthday]')";
would be
$assign = "INSERT INTO contacts(firstName,lastName,email,phone,birthday) VALUES ?,?,?,?,?)";
$assign->bindValue(1, '$_POST[firstName]')
$assign->bindValue(2, '$_POST[lastName]')
etc etc

PHP Activating account with UPDATE SQL

OK I have this code to send an email account verification link
$verifyemail = $clean['email'];
$to = $verifyemail;
$subject = 'Virtual Pierz Close | Verify Your Account';
$message = "Thanks for registering with VPC, on clicking the verification link below, your account will be confirmed, you can then go ahead buy Virtual Properties, donating £5 each time to the worthwhile charity.
http://www.cambrianvacation.co.uk/vpc/registered.php?
email='$verifyemail'&hash='$hash1' ";
$headers = 'From:noreply#cambrianvacation.co.uk'; // Set from headers
mail($to, $subject, $message, $headers);
And then I have this code, that is trying to activate the account by setting active = 1 in the database, which will then be part of the access control logic at login, without active = 1, there is no login, amongst other protection
if(isset($_GET['email']) && !empty($_GET['email']) AND isset($_GET['hash']) && !empty($_GET['hash'])){
// Verify data
$accountemail = $_GET['email'];
$accounthash = $_GET['hash'];
}
$accountActive = 1;
$notactive = 0;
$username = '';
$password2 = '';
$username = 'xxxxxxx';
$password2 = 'xxxxxxx';
$db1 = new PDO('mysql:host=localhost;dbname=xxxxxxxxxxxxx', $username, $password2, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$db1->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db1->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try{
$search = $db1->prepare("SELECT email, hash, active FROM users WHERE email = :email AND hash= :hash AND active = :active");
$search->bindParam(':email', $accountemail);
$search->bindParam(':hash', $accounthash);
$search->bindParam(':active', $notactive);
$search->execute();
$colcount = $search->columnCount();
}catch(PDOException $e) {
$e->getMessage();
}
print_r($colcount);
if($colcount === 3){
//try{
$update = $db1->prepare("UPDATE users SET active=:active WHERE email=:email AND hash=:hash AND active = :active");
$update->bindParam(':active', $accountActive);
$update->bindParam(':email', $accountemail);
$update->bindParam(':hash', $accounthash);
$update->bindParam(':active', $notactive);
$update->execute();
//}catch(PDOException $e) {
// $e->getMessage();
//}
However I cannot get the active column to update.
I've also thought about using the GET['email'] could be subject to semantic url attacks, however the logic won't activate the account without the matching hash, which is randomly generated with crypt().........
If anyone can see any security holes in the code, please tell me.........
There really is no reason to make two separate queries here. Why not just have one query to update the record based on hash and email and active = 0? If the count of modified rows = 1, then you had a success, else you had a failure. You probably don't care why it failed, as it would be bad from a security perspective to indicate back to the user why update failed (i.e. bad email, bad hash, already active user, etc.).
That being said, your problem actually lies in the fact that your update uses ? style bindings, while you are using bindParam() with :param style bindings. This won't work since those values are not present in the prepared statement.
So just use this one single query:
UPDATE users SET active = 1 WHERE email = :email AND hash = :hash AND active = 0
Obviously if you think you are going to change the value for active/non-active then feel free to use a parameter for those as well, but my guess is you would want to treat that as a boolean-style tinyint field with only allowable values of 0 and 1, so there is really no point in having the parametrization there.
What you could do, is not include "email" at all.
You could try to gen the url by doing this:
$secret = "1032940fdjsjdkf##$!##%djsfisd";
$hash = md5($email.$secret);
$url = "http://www.cambrianvacation.co.uk/vpc/registered.php?hash=".$hash;
In the update query, you are using "?" for parameters, but then you try to set them as named with bindParam(). You should use
$update->execute(array($accountActive, $accountemail, $accounthash, $notactive));
Or modify the update query this way:
$update = $db1->prepare("UPDATE users SET active=:active WHERE email=:email AND hash=:hash");
Your new parameters are not bound correctly, change:
$update = $db1->prepare("UPDATE users SET active=? WHERE email=? AND hash=? AND active = ?");
To:
$update = $db1->prepare("UPDATE users SET active=:active WHERE email=:email AND hash=:hash");
EDIT - Full Update Code:
$update = $db1->prepare("UPDATE users SET active=:active WHERE email=:email AND hash=:hash");
$update->bindParam(':active', $accountActive);
$update->bindParam(':email', $accountemail);
$update->bindParam(':hash', $accounthash);
$update->execute();

Why isn't the mysql database updating in this case?

I have this PHP script:
require_once('global.php'); //connects to db and various functions used
//select the user's information
$statement = $db->prepare("SELECT * FROM user WHERE id=1");
$statement->execute();
$result = $statement->fetchObject();
//get the chat
$string = $result->chats;
$from = $_REQUEST['from'];
$msg = $_REQUEST['msg'];
$sent = $_REQUEST['sent'];
//see what we should do with the recieved data
if($string == "") {
//there isnt any chats right now, we must add the first ever contact
$string = "<ResultSet><chats><chat><messages><sms><from>{$from}</from><msg>{$msg}</msg><sent>{$sent}</sent></sms></messages><contact>{$from}</contact></chat></chats></ResultSet>";
//send the data back to the user's row in the database
$statement = $db->prepare("UPDATE user SET chats='{$string}' WHERE id=1");
$statement->execute();
} else if($from == $result->name) {
//the user is sending a message to a contact. we now need to get the "to" value.
$to = trim(str_replace("_", " ", $_REQUEST['to']));
//add the sms to the contact's chat
$string = str_replace("</sms></messages><contact>{$to}</contact>", "</sms><sms><from>{$from}</from><msg>{$msg}</msg><sent>{$sent}</sent></sms></messages><contact>{$to}</contact>", $string);
//send the data back to the user's row in the database
$statement = $db->prepare("UPDATE user SET chats='{$string}' WHERE id=1");
$statement->execute();
} else if(strstr($string, "<contact>".$from."</contact>")) {
//The contact that sent the message already exists in this user's row, add the message to the contact's chat
$string = str_replace("</sms></messages><contact>{$from}</contact>", "</sms><sms><from>{$from}</from><msg>{$msg}</msg><sent>{$sent}</sent></sms></messages><contact>{$from}</contact>", $string);
//send the data back to the user's row in the database
$statement = $db->prepare("UPDATE user SET chats='{$string}' WHERE id=1");
$statement->execute();
} else {
//Person who sent the message doesnt exist in the chats, add him.
$string = str_replace("</chats>", "<chat><messages><sms><from>{$from}</from><msg>{$msg}</msg><sent>{$sent}</sent></sms></messages><contact>{$from}</contact></chat></chats>", $string);
//send the data back to the user's row in the database
$statement = $db->prepare("UPDATE user SET chats='{$string}' WHERE id=1");
$statement->execute();
}
The problem is in this else if code:
else if($from == $result->name) {
//the user is sending a message to a contact. we now need to get the "to" value.
$to = trim(str_replace("_", " ", $_REQUEST['to']));
//add the sms to the contact's chat
$string = str_replace("</sms></messages><contact>{$to}</contact>", "</sms><sms><from>{$from}</from><msg>{$msg}</msg><sent>{$sent}</sent></sms></messages><contact>{$to}</contact>", $string);
//send the data back to the user's row in the database
$statement = $db->prepare("UPDATE user SET chats='{$string}' WHERE id=1");
$statement->execute();
}
I am sure the code is running through this else, I have echo'd and confirmed. When I use the $string = str_replace(), I printed the $string and it had indeed replaced. But when I submit the data to the row in the database, nothing happens when I refresh my db. Why does it not work for this else but does for the rest of the if statement (and the if before it)?
It doesn't make sense to me. The code I tried my best to comment it appropriately, if you need something explained just ask.
In case $db is not an instance of MySQLi or PDO but a db wrapper, look at the class that is instantiated as $db and make sure it doesn't start a transaction. If there is a transaction initiated, you will need to commit the transaction so that the changes to the database are applied/saved.
I'm not sure why but I had to change my code up so Iwould send the variables in the execute function instead of in the query. In the query I would put "?" where I want the variables, and in the execute() function I would put an array like
$statement->execute(array($string, 1));
That seems to have fixed my problem.

Categories