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);
Related
Im not trying to use a loop. I just one one value from one column from one row. I got what I want with the following code but there has to be an easier way using PDO.
try {
$conn = new PDO('mysql:host=localhost;dbname=advlou_test', 'advlou_wh', 'advlou_wh');
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
$userid = 1;
$username = $conn->query("SELECT name FROM `login_users` WHERE username='$userid'");
$username2 = $username->fetch();
$username3 = $username2['name'];
echo $username3;
This just looks like too many lines to get one value from the database. :\
You can use fetchColumn():
$q= $conn->prepare("SELECT name FROM `login_users` WHERE username=?");
$q->execute([$userid]);
$username = $q->fetchColumn();
You could create a function for this and call that function each time you need a single value. For security reasons, avoid concatenating strings to form an SQL query. Instead, use prepared statements for the values and hardcode everything else in the SQL string. In order to get a certain column, just explicitly list it in your query. a fetchColumn() method also comes in handy for fetching a single value from the query
function getSingleValue($conn, $sql, $parameters)
{
$q = $conn->prepare($sql);
$q->execute($parameters);
return $q->fetchColumn();
}
Then you can simply do:
$name = getSingleValue($conn, "SELECT name FROM login_users WHERE id=?", [$userid]);
and it will get you the desired value.
So you need to create that function just once, but can reuse it for different queries.
This answer has been community edited addressing security concerns
Just like it's far too much work to have to get into your car, drive to the store, fight your way through the crowds, grab that jug of milk you need, then fight your way back home, just so you can have a milkshake.
All of those stages are necessary, and each subsequent step depends on the previous ones having been performed.
If you do this repeatedly, then by all means wrap a function around it so you can reuse it and reduce it down to a single getMyValue() call - but in the background all that code still must be present.
I have a contact list that I made with PHP, jQuery and Datatables, where I have inline editing, and as soon as you click outside of a cell it updates via Ajax. Everything about the update of field values work fine, but now I wanted to save who last updated a record, by saving the username from the current session, so I've done that and sent it to the update file as a $_POST, but it won't save. When I dump it out or echo it, I can see the value, so I know it does get posted, but it just won't save in the database and I can't figure out why.
Since I don't code a lot and have learned what I know by reading and copying stuff from Stackoverflow, I'm sure I'm missing something obvious, but I still need help and I want to learn.
I've tried all kinds of "' variants, and typing in "test" or something in the query or in the variable does save it, so I feel like something is wrong with the $_POST or sql syntax, but since I can dump it and echo it, I have no idea what's wrong.
Worth mentioning is that the first part of the SQL works fine, and updates the cell it's supposed to, so the query runs, but randomly returns either "Uppdaterad!" or "Invaild requests" every other time, but the value saves either way. If I remove the whole "new part" with "last updated by", it works every time and returns "Uppdaterad!" without any problems.
<?php
if(!empty($_POST))
{
// Database settings
include "config.php";
foreach($_POST as $field_name => $val)
{
// Clean post values
$field_contactid = strip_tags(trim($field_name));
$val = strip_tags(trim(mysqli_real_escape_string($con, $val)));
$currentuser = strip_tags(trim(mysqli_real_escape_string($con, $_POST['currentuser'])));
//var_dump($currentuser);
// From the fieldname:contact_id we need to get contact_id
$split_data = explode(':', $field_contactid);
$contact_id = $split_data[1];
$field_name = $split_data[0];
if(!empty($contact_id) && !empty($field_name))
{
// Update the values
mysqli_query($con, "UPDATE contactlist SET $field_name = '$val', `last_updated_by` = '$currentuser' WHERE id = $contact_id") or mysqli_error($con);
//mysqli_query($con, "UPDATE contactlist SET $field_name = '$val' WHERE id = $contact_id") or mysqli_error($con);
echo "Uppdaterad!";
} else {
echo "Invalid Requests";
}
}
} else {
echo "Empty POST!";
}
?>
I have a huge multistep form with data for multiple tables in mysql db. For every field my html is like-
input type="text" name="names" value="" // value set using php echo
On submit at php I am doing this for all the fields of my form-
$name=$_POST['names'] ?? ' '
to avoid unidentified index and unidentified variable
Then i update my first table and write log that its updated.
$query=mysqli_query($con,"UPDATE teacherpersonal set name='$name' ... where id=$id");
write_mysql_log("teacherpersonal updated", "facultydetails", $id).
I have defined write_mysql_log.
And similarly i update all the remaining tables with either the updated values or blank ("") values.
Since you can see that update query always executes even if the fields are not changed. Hence it is always logged that the tables are updated. But that's not what I want. I want to update only those fields in the table which are changed and remaining stay intact and log only those tables which are thus updated. Many tables won't be updated this way as the user might change only few details.
Using jquery and php.
My write_mysql_log is
function write_mysql_log($message, $db, $faculty_id)
{
$con=mysqli_connect("localhost","root","");
mysqli_select_db($con,"facultydetails");
// Construct query
$sql = "INSERT INTO my_log (message, faculty_id) VALUES('$message', '$faculty_id')";
$query=mysqli_query($con, $sql);
// Execute query and save data
if($query) {
echo 'written to the database';
}
else {
echo 'Unable to write to the database';
}
}
This you can achieve in 2 different ways.
1) With the help of jQuery check the values which are updated, post only those values to the php script
2)At the time of updating the check the current values with the updated one based on that criteria update the db tables.
solution 1 is less time taking process compare to the other.
You need to update only the user edited value, by doing this you can achieve it;
$oldvalue = array("username" => "green", "email" => "green#mail.com","dob" => "111");
$newvalue = array( "email" => "green#mail.com","dob" => "111","username" => "blue");
$updates = array_diff($newvalue, $oldvalue);
$implodeArray = implode(', ', $updates);
$sql = ("UPDATE user WHERE userID=$userID SET $implodeArray");
mysql_query($sql,$this->_db) or die(mysql_error());
mysql_close();
Output:
$updates = array_diff($newvalue, $oldvalue);
will have:
Array ( [username] => blue )
which is changed one
Ok after considering many options like-
create json object for old and new data and then compare and check which values changed and update that table and log it.
Or create a php array with old and new data and check diff then do the same (as suggested by Ram Karuppaiah)
Or a bad idea to have a flag on every input and then mark which ones have changed using onkeyup jquery event then try to update only those fields tables.
So finally what i did is that i let the form get submitted with all the data. As earlier i am taking the data in php as $name=$_POST['names'] ?? ' ' (blank if nothing is submitted or if something submitted then its value).
Before update statement in php, i am querying the table and comparing the database values with the values i got, if all same i dont do anything. If not then i update the table with the new values and log the change.
i want to insert multiple values into a single field, i don't know how to achieve this i'm using a long-text data type field. And also tell me how to fetch these a value only one separate value at a time.
Insert Mutliple values in a single Field:
For inserting the flat no's in a single field, use implode and the values separated by comma.
$r=implode(",",$available);
$insert=mysql_query("insert into flatdetails(available) value ('$r')")
For retrieve the values from database use, explode to separate out all the values..
For Retrieve the values using
$i=explode(",",$r);
<?php
$select_tbl=mysql_query("select * from flatdetails",$conn);
while($fetch=mysql_fetch_object($select_tbl))
{
$r=$fetch->available;
$i=explode(",",$r);
echo $i[0]."</br>";
}
?>
As far as my knowledge goes, MySQL does not have any data types that could help your use case. Well, actually it has a "set" data type, but it only allows for up to 60-something members if I recall correctly.
You can try using BLOB as your column type and store serialized data in there (i.e. JSON, protocol buffers).
However, I would recommend that you re-evaluate your DB's design. You're breaking the first normal form, and it's a sign that you're doing something wrong.
Use json_encode to encode the content and then store it in db field and when you retrieve the value then use json_decode ( Same like wordpress )
Its not a good idea to store multiple values into a single column. If you really want to do that store your strings as coma separated. And when reading back from database you can use php explode function. Php explode
I'll give you another option to store
Assume your strings are str1,str2,str3
First if you use your method it will be like below. which is not a good idea i think.
I think following is the good method
I think you should use Array and Implode functionality of PHP. Create an array and implode it by comma. For example---
Suppose you have three fields then get values of these input fields and make an array.
$arr = array(); // Declare an array
$arr[] = $_POST['FirstField'];
$arr[] = $_POST['SecondField'];
$arr[] = $_POST['ThirdField'];
// As more as you have input fields.
Then make it a string like
$insertValue = implode(',',$arr); // This will create a string containing all your fields values and you can save it in single field.
Just use this single variable in your insert query.
Hope this will help you.
db connect file with PDO save as config.php
<?php
$dbhost = 'localhost';
$dbname = 'clsrepair';
$dbuser = 'root';
$dbpass = '';
try {
$db = new PDO("mysql:host={$dbhost};dbname={$dbname}",$dbuser,$dbpass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
echo "Connection error: ".$e->getMessage();
}
?>
then in you desire file:
if(isset($_POST['your_form']))
{
try {
$leavingEquipment = implode(', ', $_POST['leavingEquipment']);
$statement = $db->prepare("INSERT INTO orderForm (orderNo,leavingEquipment) VALUES (?,?)");
$statement->execute(array($_POST['orderNo'],$leavingEquipment));
$success_message = "Order's has been inserted successfully.";
}
catch(Exception $e) {
$error_message = $e->getMessage();
}
}
try adding additional field to your apartmat table wher you writte for example 1 for rented (not available)
0 for available
query all apartments accordint to 0 and you got your list of all available appartments.
I have 4 tables named wheels, tires, oil_change, other_servicing.
Now, I have an order form for the person that comes for a car checkup. I want to have all of these 4 options in a form. So say someone comes for new wheels but not for tires, oil change, and other servicing and they will leave the other fields blank. And then you might have a scenario where all four fields are filled up. So how do i submit each to their respective tables from that one form?
The form will submit to a single php script. In the php you must do 4 separate queries to put the data into the correct tables. For example if you have this in php:
$wheels = $_REQUEST['wheels'];
$tires = $_REQUEST['tires'];
$oil_ch = $_REQUEST['oil_change'];
$other = $_REQUEST['other_servicing'];
mysql_query("INSERT INTO wheels (wheels) VALUES $wheels");
mysql_query("INSERT INTO tires (tires) VALUES $tires");
mysql_query("INSERT INTO oil_change (oil_change) VALUES $oil_ch");
mysql_query("INSERT INTO other_servicing (other_servicing) VALUES $other");
Of course I don't know the schemas of your tables but this is just an example of how you have to split it into 4 queries.
However, I would suggest to you that rather than have 4 tables for this, just have one table and make each of these a column instead. There may be other details I don't know about which would necessitate separate tables but with the info you have given seems like it would be simpler.
This shouldn't present any problem. The PHP page that receives the form data can run as many queries as you want. The skeleton for the code would be something like:
if($_POST['wheels']) { //if they filled in the field for wheels...
mysql_query("insert into wheels...");
}
if($_POST['tires']) { //if they filled in the field for tires...
mysql_query("insert into tires...");
}
if($_POST['oil_change']) { //if they filled in the field for oil_change...
mysql_query("insert into oil_change...");
}
... etc
for each form you would have something like this:
if($_POST['wheels']){mysql_query("INSERT INTO wheel_table (column1) VALUES (" . 'mysql_real_escape_string($_POST['wheels']) . "')")
this checks if the form element has been set, or has a value, and if it does, it creates a new row in the corresponding table.
if the form element's name is not 'wheels', you'll have the change $_POST['wheels'] to $_POST['form_element_name'] and if the table's name is not wheel_table, you'll have to change that and same with the column name.
this all has to be wrapped in a
In the form action you will specify the php file that will process the form.
In the php script file you will make tests of what parts of the forms are used and inserted in the respective table.
Try to separate the tests and the inserts of each table, to be easier for you.
This could be useful
if(isset($_POST['submit'])) // assuming you have submit button with name 'submit'
{
$fields['wheels'] = isset($_POST['wheels']) ? $_POST['wheels'] : null;
$fields['tires'] = isset($_POST['tires']) ? $_POST['tires'] : null;
$fields['oil_change'] = isset($_POST['oil_change']) ? $_POST['oil_change'] : null;
$fields['other_servicing'] = isset($_POST['other_servicing']) ? $_POST['other_servicing'] : null;
$q="";
foreach($fieldsas $key=>$val)
{
if($val!==null)
{
$q="insert into ".$key." values('".mysql_real_escape_string($val)."')";
mysql_query($q);
}
}
if($q==="") echo " Please fill up at least one field !";
}
This is just the core idea, using this you can execute multiple queries if user submits more than one fields at once and you may have to add other values (i.e. user_id).