I have an html form that has some disabled field depending of what kind of authorization the user have. When I press submit, the script should understand which form field are posted and which not, and then update only the related field in the database.
For example:
I can modify Birthday, Birth place and sex, but Name and Surname are disabled and so are not posted by the html form. Therefore have to be updated only Birthday, BirthPlace, Sex where id = $idperson. But if I have permission, I post Name and Surname too. And therefore I should update also these value.
Is there a fast way to do it with PDO? Or I have to create a long sequence of if/else?
Sorry for my bad english
The Best and easy way to do this,
First collect post data and check id is set
fetch all data from your table using id
loop your post data and check with collected details
if collected details value and post value changed update in collected details variable
update all your fields with new collected array
Check the below code for more understanding
function collect() {
if(isset($_POST['id'])) {
// validate id and get all details from table
$details = getDetails($_POST['id']);
foreach($_POST as $key=>$value) {
// loop your post data and check with collected details if value changed update in collected details
if(array_key_exists($key, $details)) {
$details[$key] = ($details[$key] != $_POST[$key]) ? $_POST[$Key] : $details[$key];
}
}
} else {
echo "id not found to update";
}
}
function getDetails($id) {
$query = "SELECT * FROM table_name WHERE id=:id";
$stmt = $conn->prepare($query);
$stmt->bindParam(':id', $id);
$stmt->execute();
return $stmt->fetch(PDO::FETCH_ASSOC);
}
function update($details) {
$query = "UPDATE table_name SET field_1=:field_1, field_2=:field_2, all_field=:all_field WHERE id=:id";
$stmt = $conn->prepare();
$stmt->bindParam(':field_1', $details['field_1']);
...
$stmt->bindParam(':id', $details[$id]);
return $stmt->execute();
}
Hope this code helps you, Happy coding.
Related
I am trying to set an int value from an sql query. In my ios app I can assign an int value to a photo ID, store it and retrieve it fine. The problem comes if I want to overwrite the photo with a new jpg but still using the existing IdPhoto and therefore the same filename, e.g. 1.jpg. I first check whether the user exists. If so I update the photo (this is where I need to set the IdPhoto) otherwise I create a photo with a new ID (works fine).
function uploadDetails($Name, $Location, $photoData, $IdPhoto) {
$uploads = query("SELECT Name, IdPhoto FROM users WHERE Name = '%s' limit 1",$Name);
if (count($uploads['result'])>0) {
$result = query("UPDATE users SET Name='$Name', Location='$Location', IdPhoto='$IdPhoto' WHERE Name = '%s'", $Name);
//Need to define IdPhoto from users table
if (move_uploaded_file($photoData['tmp_name'], "icons/".$IdPhoto.".jpg")) {
thumb("icons/".$IdPhoto.".jpg", 180);
//I can print out confirmation to the iPhone app
print json_encode(array('$IdPhoto'=>$IdPhoto));
} else {
//print out an error message to the iPhone app
errorJson('Upload on server problem');
};
}
else {
if ($photoData['error']==0) {
$result = query("INSERT INTO users(Name, Location) VALUES('%s','%s')", $Name, $Location);
if (!$result['error']) {
// fetch the active connection to the database (it's initialized automatically in lib.php)
global $link;
// get the last automatically generated ID in the table
$IdPhoto = mysqli_insert_id($link);
if (move_uploaded_file($photoData['tmp_name'], "icons/".$IdPhoto.".jpg")) {
thumb("icons/".$IdPhoto.".jpg", 180);
print json_encode(array('successful'=>1));
} else {
errorJson('Upload on server problem');
};
} else {
errorJson('Upload database problem.'.$result['error']);
}
}
}
}
So the problem lies in the first part of the code where I need to update the photo but still use the same IdPhoto
EDIT
The piece of code I needed was as follows:
$getID = mysqli_fetch_assoc(mysqli_query($link, "SELECT IdPhoto FROM users WHERE Name = '$Name'"));
$IdPhoto = $getID['IdPhoto'];
Although I got to the answer eventually myself, I appreciate feedback of how to phrase questions better in future. And writing out the full code probably helped me look at the bigger picture and see where I was going wrong.
Your question is extremely vague but I'm going to take the following assumptions:
Your query will only ever return a single record
You are using MySQLi
Once you have run the query and stored the results into $result you can use the following code to get the IdPhoto:
//Store a row from results into variable
$row = $result->fetch_assoc();
//Store IdPhoto into variable
$IdPhoto = $row['IdPhoto'];
Note: Also you are selecting Name from the database when you already have the Name since you're using it to fetch the record
I have a edit profile page in my social media website.
When users click submit on the form. I run an update query to obviously update the users field in the database.
How can I optimize this scenario to include the logging of which particular fields are updated?
So for e.g.
One scenario could be:
Chris updated his profile picture.
Another scenario would be:
Chris updated his profile, inc:
Email
Username
Address
Address 2
Can anyone offer a solution to this?
I feel there is no need for code as all it is, is an update query.
Thanks
When writing out the form, save the current states in the $_SESSION-variable. The check the submitted forms and compare with the data in the $_SESSION-variable. Then only make an update on the forms that have changed.
if($_SESSION['name'] != $myform['name']) { $sql[] = "name = '{$myform['name']}'"; }
if($_SESSION['img'] != $myform['img']) { $sql[] = "img = '{$myform['img']}'"; }
$sqlstring = "UPDATE mytable SET " . implode(",",$sql);
// run the sql
EDIT: to implement logging:
// populate the variables (name, img) from the db/session with the highest revision number.
// ie SELECT * FROM mytable where userid = $userid ORDER BY revision DESC LIMIT 1
$revision = $_SESSION['revision'] + 1;
$sql = "INSERT INTO mytable SET img = '$img', name='$name', revision='$revision'";
Did you put all that information in a $_SESSION or something? If so, you can unset the session and declare it again, with the new info.
You can use custom setters / getters to do this. Check the code below.
You can also add additional checks to make sure the values have changed, or use magic methods to make things more dynamic.
class MyObject
{
protected $modifiedFields = array();
public function setField($value) {
if (!in_array('field', $this->modifiedFields)) {
$this->modifiedFields[] = 'field';
}
}
}
If you have the modified fields, you can just run the update query to contain only these fields.
On one page I have a form which POSTs the data entered in the 1 field across to another page.
On this page which you are directed to after entered data in the form field is a connection to a sql database. It happily rePOSTs the form field data on the page. Then I have got the PHP for retrieving the information from the database. This works nicely when the WHERE part is fixed manually ('criteria') however I would like the WHERE criteria for this search to be the form data from the previous page.
is there a way to echo the data to it? The form data is successfully getting to the displaying page however need help with the WHERE part.
That line of code currently is...
$result = mysqli_query($con,"SELECT * FROM table WHERE field = 'formdata'");
Any help would be appreciated greatly.
Right now, query compares field to the actual string 'formdata'. You'll want to grab the formdata, if you're POSTing, like this:
$result = mysqli_query($con, "SELECT * FROM table
WHERE field = '" . $_POST['formdata'] . "'");
Although, note that you'll need to use prepared statements to make this secure. See here and here.
I use PDO, but mysqli should be roughly the same
$formdata = $_POST['input'];
$stmt = $con->prepare('SELECT * FROM table WHERE field = ?');
$stmt->bind_param('s', $formdata);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
// do something with $row
}
I have a form that I am trying to use to track batches of beer. Because the process of brewing takes several weeks or even months, I cannot complete the form all at once. When I first create a record for a beer, most of my values are set as NULL. When I retrieve the record and attempt to update it, it also updates all my NULL values to zeros. How can I send only changed values to the database from my form so the rest will be left as NULL?
Below is a sample of my update code (please forgive any PDO transgressions - it is my first foray into using PDO).
<?php
//Connect to Database
try {
$DBH = new PDO('mysql:host=localhost; dbname=dbname', 'user', 'password');
}
catch (PDOException $e) {
echo $e->getMessage();
exit();
}
//Build Update SQL Query
$update = "UPDATE brewlog
SET
BrewDate = :BrewDate,
EndOfPrimary = :EndOfPrimary,
EndOfSecondary = :EndOfSecondary,
PackagingDate = :PackagingDate,
AnticipatedOG = :AnticipatedOG,
WHERE ID = :ID";
//Prepare Query, Bind Parameters, Excute Query
$STH = $DBH->prepare($update);
$STH->bindParam(':ID', $_POST['ID'],PDO::PARAM_INT);
$STH->bindParam(':BrewDate', $_POST['BrewDate'],PDO::PARAM_STR,10);
$STH->bindParam(':EndOfPrimary', $_POST['EndOfPrimary'],PDO::PARAM_STR,10);
$STH->bindParam(':EndOfSecondary', $_POST['EndOfSecondary'],PDO::PARAM_STR,10);
$STH->bindParam(':PackagingDate', $_POST['PackagingDate'],PDO::PARAM_STR,10);
$STH->bindParam(':AnticipatedOG', $_POST['AnticipatedOG'],PDO::PARAM_INT);
$STH->execute();
?>
You would want to validate your data before you bind it. Say something like
if(!empty($_POST['EndOfPrimary'])) {
$eop = $_POST['EndOfPrimary'];
} else {
$eop = NULL;
}
Then bind
$STH->bindParam(':EndOfPrimary', $eop,PDO::PARAM_STR,10);
Edit:
You would also use this validation to check more than if the field was left blank. It looks like you probably want a date to be entered, so perhaps your would check if the user actually entered a date, and if not then send them back to the form with some type of helpful message about where they made the mistake. This is the regexp I use to validate a date.
function pcre_date($subject) {
return preg_match('/^[0-9]{1,2}\/[0-9]{1,2}\/[0-9]{4}$/', $subject);
/*
* matches 01/01/1984, 1/1/1984, but NOT 1/1/84
* wants mm/dd/yyyy
*/
} // returns 0 for non valid, 1 for valid
Then I would use this for the validation
if(!empty($_POST['EndOfPrimary'])) {
if(pcre_date($_POST['EndOfPrimary'])) {
$eop = $_POST['EndOfPrimary'];
} else {
$form_errors[] = "Please format date as mm/dd/yyyy.";
}
} else {
$eop = NULL;
}
To accomplish this cleanly, use two steps:
In the form presented to the user, maintain a list of changed fields. For example, when a user modifies the data in an input field, use Javascript to copy the contents of that field into a hidden form to be submitted. Then when the user clicks "submit", send only the contents of the hidden form, not the contents of the original form with all fields.
In your PHP script, build your query based on the fields provided. Your query will now include only the fields that were modified. This way, when you perform your UPDATE statement, the unchanged fields will be untouched.
Sorry george, I guess you are way far complicated of what he is trying to do.
Actually, when you use _POST['somevar'], if the field is blank, you get and EMPTY string.
and the empty string is saved to the database so the field is not NULL anymore
The simplest way to ensure the fields stay NULL in the database if there is no value captured is:
$STH->bindParam(':EndOfPrimary', isset($_POST['EndOfPrimary'])?$_POST['EndOfPrimary']:null ,PDO::PARAM_STR,10);
I am trying to make a database of Users. One user can have an indefinite number of phone numbers. So in the form I’ve created a js function that will give me new input fields and they put the information into a nestled array.
I am doing a double foreach loop to go through my array, and add SQL queries to it based on if the id already exists and just needs to be updated or if it's entirely new and needs to be inserted. I add these SQL queries to a variable $phoneSql . When I echo that variable, it does contain a valid SQL query which works if I try it directly in phpMyAdmin.
This is the foreach loop code:
$phoneSql = 'SELECT id FROM user WHERE id = '.$id.' INTO #id;';
foreach($_POST['phone'] as $key => $value) {
foreach($_POST['user'][$key] as $id => $number) {
if($id == 0 && !$number == ''){
$phoneSql .= 'INSERT INTO phone_number (id, user_id, number) VALUES (NULL, #id, "'.$number.'");';
} else if (!$number == '') {
$phoneSql .= 'UPDATE phone_numbers SET user_id = #id, number = "'.$number.'" WHERE id = '.$id.';';
}
}
}
I have one edit.php page with the form, which posts to update.php where I have the foreach loop from above and following code:
$db->updatePhoneNumber($phoneSql);
It also gets the $id from the user I’m editing at the moment. Then it gets sent to db.php and into this function:
public function updatePhoneNumbers($phoneSql) {
$ phoneSql = $ phoneSql;
$sth = $this->dbh->prepare($phoneSql);
$sth->execute();
if ($sth->execute()) {
return true;
} else {
return false;
}
}
But this is not working. Can I add a variable with sql queries into a function like that or do I have to do it some other way? I’m quite new to this so I’m not sure how to proceed. I’ve tried searching for a solution but haven’t found any. I’m thankful for any advice.
What you should be doing is using an INSERT ... ON DUPLICATE KEY UPDATE ... construct, saving you a lot of that logic.
e.g.
INSERT INTO phone_number (id, user_id, number) VALUES (...)
ON DUPLICATE KEY UPDATE user_id=VALUES(user_id), number=VALUES(number)
With this, no need to select, test, then insert/update. You just insert, and MySQL will transparently convert it into an update if a duplicate key error occurs.