Insert into one table twice in same script? - php

I've asked this question before, but have changed my code since. I'm having trouble with this script which inserts form data into a table. The first insert creates a booking which stores the customer's contact details. The second insert takes the booking ref created in the first and creates a 'JOB' for the customer. The final insert is supposed to create a second 'JOB', the customer's return journey.
The first two inserts are running fine,
but it ignored the final one, the second JOB insert.
I have checked the table structures, and the data been passed to the script everything is okay, so the problem must be in the script (shown below) any help is greatly appreciated.
Is it correct to use one script to insert into the same table twice?
<?php
$customer_title = $_POST['customer_title'];
$customer_first_name = $_POST['customer_first_name'];
$customer_last_name = $_POST['customer_last_name'];
$billing_address = $_POST['billing_address'];
$customer_tel = $_POST['customer_tel'];
$customer_mobile = $_POST['customer_mobile'];
$customer_email = $_POST['customer_email'];
$passengers = $_POST['passengers'];
$cases = $_POST['cases'];
$return_flight_number = $_POST['return_flight_number'];
$price = $_POST['price'];
$pickup_date = $_POST['pickup_date'];
$pickup_time = $_POST['pickup_time'];
$pickup_address = $_POST['pickup_address'];
$destination_address = $_POST['pickup_destination'];
$return_date = $_POST['return_date'];
$return_time = $_POST['return_time'];
$return_pickup = $_POST['return_pickup'];
$return_destination = $_POST['return_destination'];
$booking_notes = $_POST['booking_notes'];
$booking_status = "Confirmed";
$authorised = "N";
$booking_agent = "ROOT_TEST";
$booking_date = date("Y/m/d");
if (isset($_POST['customer_title'])) {
include('../assets/db_connection.php');
$create_booking = $db->prepare("INSERT INTO bookings(customer_name, billing_address, contact_tel, contact_mob, contact_email, party_pax, party_cases, booking_notes, price, booking_agent, booking_date, booking_status, authorised)
VALUES(:customer_name, :billing_address, :contact_tel, :contact_mob, :contact_email, :party_pax, :party_cases, :booking_notes, :price, :booking_agent, :booking_date, :booking_status, :authorised );");
$create_booking->execute(array(
":customer_name" => $customer_title . ' ' . $customer_first_name . ' ' . $customer_last_name,
":billing_address" => $billing_address,
":contact_tel" => $customer_tel,
":contact_mob" => $customer_mobile,
":contact_email" => $customer_email,
":party_pax" => $passengers,
":party_cases" => $cases,
":booking_notes" => $booking_notes,
":price" => $price,
":booking_agent" => $booking_agent,
":booking_date" => $booking_date,
":booking_status" => $booking_status,
":authorised" => $authorised
));
$booking_ref = $db->lastInsertId('booking_ref'); // Takes Booking Ref generated in $create_booking
$scheduled = "N";
$create_job = $db->prepare("INSERT INTO jobs(booking_ref, pickup_date, pickup_time, pickup_address, destination_address, scheduled)
VALUES(:booking_ref, :pickup_date, :pickup_time, :pickup_address, :destination_address, :scheduled)");
$create_job->execute(array(
":booking_ref" => $booking_ref,
":pickup_date" => $pickup_date,
":pickup_time" => $pickup_time,
":pickup_address" => $pickup_address,
":destination_address" => $destination_address,
":scheduled" => $scheduled
));
$return = "Y";
$create_return = $db->prepare("INSERT INTO jobs(booking_ref, pickup_date, pickup_time, pickup_address, destination_address, scheduled, return)
VALUES(:booking_ref, :pickup_date, :pickup_time, :pickup_address, :destination_address, :scheduled, :return)");
$create_return->execute(array(
":booking_ref" => $booking_ref,
":pickup_date" => $return_date,
":pickup_time" => $return_time,
":pickup_address" => $return_pickup,
":destination_address" => $return_destination,
":scheduled" => $scheduled,
":return" => $return
));
}
?>

It is incorrect for sure, as inserting the same data twice violates one of most important database architecture laws - Database Normalization principle
However, there is no technical issues with it. There is some mistake which you have to catch using the error message from mysql. To have it, add this line after connecting to PDO.
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Please note that catching the actual error is the only way to debug SQL queries. Just watching the code makes no sense nor help.
return must be a mysql keyword. write it as
`return`
By the way, I can't stand such enormously huge code.
If I were you, I'd make it in 10 lines, not 50:
$allowed = array('customer_name', 'billing_address', 'contact_tel', 'contact_mob',
'contact_email', 'party_pax', 'party_cases', 'booking_notes', 'price');
$insert = $db->filterArray($_POST,$allowed);
$insert['booking_status'] = "Confirmed";
$insert['authorised'] = "N";
$insert['booking_agent'] = "ROOT_TEST";
$insert['booking_date'] = date("Y-m-d");
$db->query("INSERT INTO bookings SET ?u", $insert);

It looks like booking_ref is the primary key in the jobs table, your trying to insert the same key twice which is why the final query fails.
You should have a seperate field that is the primary key on jobs which is just an auto-incrementing number, then create an index on booking_ref.

There's no law against it. What you need to do is check the return value for the last INSERT query. My best guess is there's a unique index on the jobs table that you're violating with the double-insert.
It's not obvious if you're using mySQLi or PDO here, but both's execute functions return false on failure, so you should catch that and then call the respective object's error functions to get what went wrong.

Related

mySQL: UPDATE statement for 2 tables with a foreign key relation

I have created 2 tables with the following structure:
mitarbeiter
==================
maID (PK, AUTO_INCREMENT, NOT NULL)
maAnrede
maName
maVname
maDurchwahl
maEmail
maMobilfunkNr
maKartenanzahl
maFirma
mobilfunkkarten
==============================
mfkID (PK, AUTO_INCREMENT, NOT NULL)
mfkTarif
mfkStatus
mfkKartennr
mfkPin
mfkSuperpin
maID(FK)
Now I would like the web user to type in values into form fields. (I will let him edit his/her entries there, which will be saved in the mysql-database. So these entries are NOT new!) After clicking the "Save"-Button, the data will be saved into the corresponding 2 tables. My mySQL-Query looks like this (I am using symfony's php templating engine "twig"):
DatabaseLink::getInstance()->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if(isset($_POST["btnSaveMfk"]))
{
$stmt = DatabaseLink::getInstance()->prepare("UPDATE mitarbeiter SET
maAnrede = :maAnrede,
maVname = :maVname,
maName = :maName,
maMobilfunkNr = :maMobilfunkNr,
maKartenanzahl = :maKartenanzahl,
maEmail = :maEmail,
maFirma = :maFirma
WHERE mitarbeiter.maID = :maid;
UPDATE mobilfunkkarten SET mfkTarif = :mfkTarif,
mfkStatus = :mfkStatus,
mfkPin = :mfkPin,
mfkSuperpin = :mfkSuperpin");
$status = $stmt->execute(array(
":maid" => $_POST["txtMaId"],
":maAnrede" => $_POST["txtAnrede"],
..................,
..................,
..................
));
header("Location: Mobilfunkdaten"); //back to the PHP table that shows all entries
}
I believe that this won't work because the 2 tables are related with a foreign key and if I update both tables without this relation, the statement will result in an error or it will overwrite something unrelated. Am I right with this assumption?
Any solutions on how to solve this? I just can't think of any way on how to make sure that anything the user types into the form fields will be saved as 1 dataset into these 2 tables, i.e. the UPDATED data in the child table 'mobilfunkkarten' will be related to the Primary Key Number in the parent table 'mitarbeiter'.
mitarbeiter = workers mobilfunkkarten = mobile phone cards (SIM cards)
With update statements, the auto_increment value doesn't change. And, as I can see from your query, you're not updating the maID value, so it gives no reason for the MySQL parser to throw an error. Your query is correct, as far as I can see.
Just one small thing. Define the keys of the associative array without the : symbol. You use this symbol to indicate that this place is reserved for the value stored in the variable by the following name. For example, using
$stmt = DatabaseLink::getInstance()->prepare("update table_name set name=:name where id=:id");
$status = $stmt->execute(array("name" => "test", "id" => 2));
indicates to the parser that the name corresponding to ID 2 has to be updated to test.
But, you are already using the : along with the name of the key. So, in your example, your query looks for the value in a key called maAnrede in your script, but the key that you have defined is :maAnrede, and hence, the query doesn't work as expected.
Try this change. It'll surely work.
DatabaseLink::getInstance()->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if(isset($_POST["btnSaveMfk"]))
{
$stmt = DatabaseLink::getInstance()->prepare("UPDATE mitarbeiter SET
maAnrede = :maAnrede,
maVname = :maVname,
maName = :maName,
maMobilfunkNr = :maMobilfunkNr,
maKartenanzahl = :maKartenanzahl,
maEmail = :maEmail,
maFirma = :maFirma
WHERE mitarbeiter.maID = :maid;
UPDATE mobilfunkkarten SET mfkTarif = :mfkTarif,
mfkStatus = :mfkStatus,
mfkPin = :mfkPin,
mfkSuperpin = :mfkSuperpin");
$status = $stmt->execute(array(
"maid" => $_POST["txtMaId"],
"maAnrede" => $_POST["txtAnrede"],
..................,
..................,
..................
));
header("Location: Mobilfunkdaten"); //back to the PHP table that shows all entries
}
This situation happened with me as well, and this is the solution that worked for me!
I believe I fixed it. You need to add this line in the second SQL statement:
WHERE mobilfunkkarten.maID = :maid");
See below where I included it.
Fixed the issue for me but I am not entirely sure how safe this one is...any criticism on this approach? Other suggestions?
DatabaseLink::getInstance()->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if(isset($_POST["btnSaveMfk"]))
{
$stmt = DatabaseLink::getInstance()->prepare("UPDATE mitarbeiter SET
maAnrede = :maAnrede,
maVname = :maVname,
maName = :maName,
maMobilfunkNr = :maMobilfunkNr,
maKartenanzahl = :maKartenanzahl,
maEmail = :maEmail,
maFirma = :maFirma
WHERE mitarbeiter.maID = :maid;
UPDATE mobilfunkkarten SET mfkTarif = :mfkTarif,
mfkStatus = :mfkStatus,
mfkPin = :mfkPin,
mfkSuperpin = :mfkSuperpin
WHERE mobilfunkkarten.maID = :maid");
$status = $stmt->execute(array(
"maid" => $_POST["txtMaId"],
"maAnrede" => $_POST["txtAnrede"],
..................,
..................,
..................
));
header("Location: Mobilfunkdaten"); //back to the PHP table that shows all entries
}

Prevent duplicate rows from 2 crons job

I have a script that inserts into a database, the script is called from 2 cron jobs simultaneously so in many cases I can have the same data at the same time ( hour,minute,second ).
Actually I don't have control on the cron jobs but I have it on the script.
So is that any way to prevent duplicating rows ?
code :
function checkDuplicate($email) {
$return = 0;
if($email != "" ){
$sql = "SELECT d.id_data as nbre FROM data d WHERE d.email = '" . $email . "' ";
$nbreEmails = $db->run($sql);
$return = (sizeof($nbreEmails) > 0) ? 1 : 0;
}
return $return;
}
if(!checkDuplicate($email)){
$insert = array(
"id_client" => $id_client,
"email" => $email,
"valide" => 1,
"stat" => "valide",
"date_insert" => date("Y-m-d H:i:s"),
"date_refus" => null
);
$db->insert("data", $insert);
}
Thanks.
You should set your timestamp field as an unique.
If you can't set it, or there is more complicated conditions that should cofirm that script1 & script2 will never do insert (or whatever with this table) in the same time, you should use lock tables, I.e.:
// not sure waht do you use as $db
$db->execute('LOCK TABLES data WRITE;');
...// inserts
$db->execute('UNLOCK TABLES;');
or use transactions (for MySQL)
Suggest you to use PDO (PDO::beginTransaction)
Or update your post with framework name that you use, most of them should have a way to do it.

How to make foreign key updated automatically once the referenced key has been inserted with new value?

I have a 2 tables like this
I have put bmatricno as a referenced key for a foreign key called bmatricno_fk. Ok now i want to insert new data that contain bmatricno and bname for one table which is the first pic. And then i want the column for bmatricno_fk to be updated as well with the same value with the referenced key which is bmatricno. However i failed.
Then i try to insert manually with inserting on 2 tables. Then i have a problem with inserting multiple tables. I know about using transaction with commit because im using PDO. The problem is, since i have to use a code something like :bmatricno' => $_POST['bmatricno']. Therefore, i dont know how to use transaction that includes that kind of thing.
my code looks like this. (noob isnt it?)
$ses = $_SESSION['sBorrow'];
$query = "
INSERT INTO borrow (
bmatricno,
bname,
bdatetime
) VALUES (
:bmatricno,
:bname,
NOW()
)
;
INSERT INTO thesis(
bmatricno_fk
) VALUES (
:bmatricno
)
SELECT serialno, title
FROM thesis
WHERE serialno = :ses
";
$query_params = array(
':bmatricno' => $_POST['bmatricno'],
':bname' => $_POST['bname'],
':ses' => $_SESSION['sBorrow']
);
try
{
// Execute the query to create the user
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
That is my current code. So my question is does foreign key can be updated once referenced key got new value? If not, how to make transaction with the code i stated earlier?Please help me. I need to get this done.
NOTE: You notice that on second pic and column matricno_fk works well because i put an input to insert value, which means manually.
Well i did find the solution for my problems. frz3993 working but i just realized that one of my variables is an array. Therefore i use foreach on query. Since its an array, i'm not sure how to use foreach inside transaction since im in a rush. So i execute one by one query. and put foreach on my second statement like this.
$ses = $_SESSION['sBorrow'];
$query = "
INSERT INTO borrow (
bmatricno,
bname,
bdatetime
) VALUES (
:bmatricno,
:bname,
NOW()
)
";
$query_params = array(
':bmatricno' => $_POST['bmatricno'],
':bname' => $_POST['bname']
);
try
{
// Execute the query to create the user
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
//----------------------
$query = "
UPDATE thesis
SET
bmatricno_fk = :bmatricno,
bavailable = 'Unavailable'
WHERE
serialno = :ses
";
foreach($ses as $s){
$query_params = array(
':bmatricno' => $_POST['bmatricno'],
':ses' => $s
);
try
{
// Execute the query to create the user
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
}
//----------------------
I know this solution may not be best practical but well i need to complete it fast and i just have to present it on localhost anyway. Anyway, thanks for helping :)

Drupal 7 database API very slow compared to PHP mysqli_connect()

I am trying to loop over some data coming to me from a SOAP request and insert the records into a custom table in my Drupal install.
At first I created a custom module and used standard mysqli_connect() syntax to connect to the database and loop through the records and insert them. This was working great and fetched and inserted my remote data in about 2 seconds without a hitch.
I then remembered that Drupal has a database API (I am fairly new to Drupal) so I decided to do it right and use the API instead. I converted my code to how I think I should be doing it per the API docs, but now the process takes more like 5 or 6 seconds and sometimes even randomly hangs and doesn't complete at all and I get weird Session errors. The records end up inserting fine, but it just takes forever.
I'm wondering if I am doing it wrong. I would also like to wrap the inserts into a transaction, because I will first be deleting ALL of the records in the destination table first and then inserting the new data and since I am deleting first, I want to be able to roll back if the inserts fail for whatever reason.
I did not add transaction code to my original PHP only code, but did try to attempt it with the Drupal API, although completely removing the transaction/try/catch code doesn't seem to affect the speed or issues at all.
Anyway here is my original code:
$data = simplexml_load_string($jobsXml);
$connection = mysqli_connect("localhost","user","pass","database");
if (mysqli_connect_errno($connection))
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
exit();
}
// delete * current jobs
mysqli_query($connection,'TRUNCATE TABLE jobs;');
$recordsInserted = 0;
foreach ($data->NewDataSet->Table as $item) {
//escape and cleanup some fields
$image = str_replace('http://www.example.com/public/images/job_headers/', '', $item->job_image_file);
$specialty_description = mysqli_real_escape_string($connection, $item->specialty_description);
$job_board_title = mysqli_real_escape_string($connection, $item->job_board_title);
$job_board_subtitle = mysqli_real_escape_string($connection, $item->job_board_subtitle);
$job_state_code = ($item->job_country_code == 'NZ') ? 'NZ' : $item->job_state_code;
$sql = "
INSERT INTO jobs (
job_number,
specialty,
specialty_description,
division_code,
job_type,
job_type_description,
job_state_code,
job_country_code,
job_location_display,
job_board_type,
job_image_file,
job_board_title,
job_board_subtitle
) VALUES (
$item->job_number,
'$item->specialty',
'$specialty_description',
'$item->division_code',
'$item->job_type',
'$item->job_type_description',
'$job_state_code',
'$item->job_country_code',
'$item->job_location_display',
'$item->job_board_type',
'$image',
'$job_board_title',
'$job_board_subtitle'
)
";
if (!mysqli_query($connection,$sql))
{
die('Error: ' . mysqli_error($connection) . $sql);
}
$recordsInserted++;
}
mysqli_close($connection);
echo $recordsInserted . ' records inserted';
and this is my Drupal code. Can anyone tell me if maybe I am doing this wrong or not the most efficient way?
$data = simplexml_load_string($jobsXml);
// The transaction opens here.
$txn = db_transaction();
// delete all current jobs
$records_deleted = db_delete('jobs')
->execute();
$records_inserted = 0;
try {
$records = array();
foreach ($data->NewDataSet->Table as $item) {
$records[] = array(
'job_number' => $item->job_number,
'specialty' => $item->specialty,
'specialty_description' => $item->specialty_description,
'division_code' => $item->division_code,
'job_type' => $item->job_type,
'job_type_description' => $item->job_type_description,
'job_state_code' => ($item->job_country_code == 'NZ') ? 'NZ' : $item->job_state_code,
'job_country_code' => $item->job_country_code,
'job_location_display' => $item->job_location_display,
'job_board_type' => $item->job_board_type,
'job_image_file' => str_replace('http://www.example.com/public/images/job_headers/', '', $item->job_image_file),
'job_board_title' => $item->$job_board_title,
'job_board_subtitle' => $item->job_board_subtitle,
);
$records_inserted++;
}
$fields = array(
'job_number',
'specialty',
'specialty_description',
'division_code',
'job_type',
'job_type_description',
'job_state_code',
'job_country_code',
'job_location_display',
'job_board_type',
'job_image_file',
'job_board_title',
'job_board_subtitle'
);
$query = db_insert('jobs')
->fields($fields);
foreach ($records as $record) {
$query->values($record);
}
$query->execute();
} catch (Exception $e) {
// Something went wrong somewhere, so roll back now.
$txn->rollback();
// Log the exception to watchdog.
watchdog_exception('Job Import', $e);
echo $e;
}
echo $records_deleted . ' records deleted<br>';
echo $records_inserted . ' records inserted';
How big is the dataset you are trying to insert? If the dataset is very large then perhaps you might right into query size issues. Try looping over records and inserting each record one by one like you did with PHP.

PHP/SQL Update - update only if value has been change

I have following PHP loop + SQL Update query.
for ($i=0;$i<count($_POST['id']);$i++) {
if(!isset($_POST['live'][$i])){
$_POST['live'][$i] = "0";
} else { $_POST['live'][$i] = "1"; }
$id = ($_POST['id'][$i]);
$live = ($_POST['live'][$i]);
$usr2 = $_SESSION['usr'];
$updated = date("F j, Y, g:i a",time()+60*60);
$sql = "UPDATE news SET live = '$live', usr2 = '$usr2', updated = '$updated' WHERE id = $id";
$result = mysql_query($sql);
//echo $sql."<br />";
}
if($result) {
header("location: notes.php");
exit();
}else {
die("Query failed");
}
How does it work:
I'm submitting big form will ALL OF THE table rows.
receiving this in different file as an array
if $_POST['live'] is 'not set' - set it to '0', if 'set' set it to 1
update array data within for loop
How to UPDATE only the rows which have been actually been changed?
Those which value from $_POST['live'] is actually different from this saved in DB, as the condition would be change of our $live row.
I guess you're concerned about the updated field and that this value only changes when something has been altered. (If that's not the case forget about this answer.)
You can define an ON UPDATE CURRENT_TIMESTAMP clause for a timestamp field. Each time a record is updated without explicitly setting a value for this field mysql uses the current time as its new value...
...but only if the record is altered; if you "update" the fields with the same value as are already in that record nothing happens.
demo script:
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
setup($pdo);
$stmt = $pdo->prepare('UPDATE soNews SET somevalue=:v WHERE id=:id');
show('original', $pdo);
$stmt->execute( array(':id'=>1, ':v'=>'z') );
show('update with new=old & id=1', $pdo);
$stmt->execute( array(':id'=>2, ':v'=>'y') ); // new value=old value
show('update with new!=old & id=2', $pdo);
function setup($pdo) {
$pdo->exec('
CREATE TEMPORARY TABLE soNews (
id int auto_increment,
somevalue varchar(32),
updated TIMESTAMP DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP,
primary key(id)
)
');
$pdo->exec("INSERT INTO soNews (id,somevalue,updated) VALUES (1,'x', Now()-interval 47 hour),(2,'y', Now()-interval 47 hour)");
}
function show($label, $pdo) {
echo "------ $label --------\n";
foreach( $pdo->query('SELECT * FROM soNews', PDO::FETCH_ASSOC) as $row ) {
echo join(', ', $row), "\n";
}
}
prints
------ original --------
1, x, 2011-08-16 14:09:53
2, y, 2011-08-16 14:09:53
------ update with new=old & id=1 --------
1, z, 2011-08-18 13:09:53
2, y, 2011-08-16 14:09:53
------ update with new!=old & id=2 --------
1, z, 2011-08-18 13:09:53
2, y, 2011-08-16 14:09:53
As you can see as a result of the first update query the timestamp field has been updated while the second query setting new=old didn't affect the updated field.
Bobby tables will destroy your database. All your bits are belong to him (strictly speaking, this is an exaggeration, but you need to wrap all of your db inputs with mysql_real_escape_string or better yet, move to PDO's or MySQLi).
Long and the short? No, there is no reliable way to determine whether user input is the same as what is in the database without actually querying the database first or somehow storing the original output from the DB locally ($_SESSION or whatnot).
There are legitimate use cases for that, but it looks like you're better off just calling the updates. You can prevent them slightly by adding AND LIVE != '$live' AND UR2 != '$ur2', but you'll still need to run that many queries.
BTW -- I generally advise people not to use traditional for loops in PHP pretty much ever. PHP's foreach is better in almost every way. Instead of for ($i=0;$i<count();$i++), use foreach( $_POST['id'] as $i => $id ). You'll already have $id declared.
Actually, I think that a good way of doing is to:
1) Perform a query to get the old record from the db, then store the row contents in an associative array, with column names as keys.
2) Create a new array by checking the content of each "column" to be updated. If the content received is different from the value stored on the db, update the record data, else ignore and go ahead. Finally send back the updated data to the db with an UPDATE
function updateRecord(array $input_data) {
// Get the data associated to the record id we want to update.
$record_data = $yourDBWrapperClass
->where("id",$_GET['record_id'])
->get(TABLE_NAME);
// Process column by column and append data to the final array.
$final_data = [];
$ignored_columns = ['id', 'last_update'];
foreach ($record_data as $col_name => $value) {
// Update the record data, only when input data shows a difference
if(array_key_exists($col_name, $input_data)
&&
$record_data[$col_name] != $input_data[$col_name])
{
$final_data[$col_name] = $inputData[$col_name];
}
else if (array_key_exist($ignored_columns, $col_name) == FALSE && $record_data[$col_name] == $input_data[$col_name]
{
$final_data[$col_name] == $value;
}
}
// Finally, perform the db update.
$update_result = $yourDBWrapperClass
->where("id", $_GET['record_id'])
->update(TABLE_NAME, $final_data);
return $update_result ? "Record update success" : "Record update failed";
}
note: You don't need to send back the id, or last_update columns: their value is calculated automatically by the server. Sending a wrong value, will cause an error, or provide a wrong information. Think about the last_update column: it's better to leave to MySQL, which will call use the column default to get the value: NOW(); or CURDATE();
expected aspect of variables/arrays
$_GET['record_id'] = 123;
$record_data = [
"id" => 123,
"name" => "John",
"surname" => "Dahlback",
"age" => 31,
"last_update" => "2019-01-01 10:00:00"
];
$input_data = [
"age" => 32
];
$final_data = [
// "id" => 123,
"name" => "John",
"surname" => "Dahlback",
"age" => 32,
// "last_update" => CURDATE();
];

Categories