0

I am trying to submit an AJAX request to update a row in my MySQL database. Whenever I try to submit the request via AJAX the row is not updating, but whenever I test the query and parameter values directly in the database the row is updated.

This is what the markup and AJAX look like:

$('body').on('change', '.cb_exempt', function() {
  var checked = this.checked;
  var business_id = $(this).attr('data-id');
  var jqxhr = $.post("php/update_exempt.php", {
      exempt: checked,
      business_id: business_id
    })
    .done(function(data) {
      alert("The business successfully updated");
    })
    .fail(function(jqXHR, textStatus, errorThrown) {
      alert(errorThrown);
    });
});
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js"></script>
<table id="table_businesses" role="grid" aria-describedby="table_businesses_info">
  <thead>
    <tr role="row">
      <th aria-controls="table_businesses">Name</th>
      <th aria-controls="table_businesses">Active</th>
      <th aria-controls="table_businesses">Exempt from Billing</th>
      <th aria-controls="table_businesses">Billing History</th>
    </tr>
  </thead>
  <tbody>
    <tr role="row" class="odd">
      <td>[removed]</td>
      <td><input class="mx-auto cb_active" checked="checked" data-id="1" type="checkbox"></td>
      <td><input class="mx-auto cb_exempt" data-id="1" type="checkbox"></td>
      <td><a href="business.php?business_id=1">View Billing History</a></td>
    </tr>
  </tbody>
</table>

And this is what my PHP looks like:

<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST' || empty($_POST['exempt']) || empty($_POST['business_id'])) {
  // Get the database object from the configuration file
  $db;
  try {
    $db = include('config_consumer_database.php');
  } catch(PDOException $ex) {
    throw new Exception('Database exception.');
  }

  // Update the business' exempt status
  $stmt = $db->prepare('UPDATE IGNORE `business` SET `is_exempt` = :exempt WHERE `business_id` = :business_id;');

  // Execute the query passing the new exempt value and the business_id
  $stmt->execute(array(
    ':exempt' => $_POST['exempt'],
    ':business_id' => $_POST['business_id']
  ));
} else {
  throw new Exception('The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated.');
}
?>

As I mentioned, it will not work whenever I try to use the AJAX request, but I've echoed the query String as well as the $_POST so that I could copy/paste the output directly in my MySQL database to confirm that the query would run and it does.

UPDATE

I did notice an issue with my PHP code in that I was using OR statements instead of AND statements in my conditional statement, so I changed that. This did not solve my issue.

I also took the advice to use isset or strlen($_POST['...']) > 0 instead of empty. I tried both, neither of which solved my issue.

I also tried to use regular parameters instead of named parameters and passing my $_POST directly into the execute like the following:

// Update the business' exempt status
$stmt = $db->prepare('UPDATE IGNORE `business` SET `is_exempt` = ? WHERE `business_id` = ?;');

// Execute the query passing the new exempt value and the business_id
$stmt->execute(array_values($_POST));

This did not solve my issue either.

Whenever I check my JavaScript console log, nothing shows up after I submit the AJAX request. Whenever I check my error.txt log (xampp > apache > logs > error.txt), nothing shows up after I submit the AJAX request.

The parameters sent in the $.POST request are as I expect them to be.

David
  • 5,877
  • 3
  • 23
  • 40
  • 1
    Look at your developer console then, see what shows up in there. – Funk Forty Niner Aug 02 '18 at 18:04
  • @FunkFortyNiner - Nothing appears in the console. – David Aug 02 '18 at 18:05
  • There's two logs to check: JavaScript (console) and your PHP server-side where any number of things could be going wrong. Verify you're receiving the parameters correctly, with the names you expect, before digging deeper. Verify that the `$.post` call is correctly initiated, actually makes a request, and doesn't get a 500-type error. These won't always show up in the console, but will show up in the network activity inspector. – tadman Aug 02 '18 at 18:07
  • @tadman - The names and values returned from `print_r($_POST)` and the Network > POST > Params are as expected. Nothing appears in neither the JavaScript console nor the error.txt file in xampp > apache > logs. The POST request returns a status of 200. – David Aug 02 '18 at 18:17
  • @Akshay - No it isn't. Check my response to your answer. – David Aug 02 '18 at 18:22
  • 1
    Btw; I noticed a checkbox and a conditional for it. Don't use `empty()` for those, use `isset()`. – Funk Forty Niner Aug 02 '18 at 18:30
  • @FunkFortyNiner - The idea is that a user can change a checkbox which will submit an AJAX request to update the respective business' `is_exempt` column. So in my initial conditional statement in the PHP file, I changed it from `empty()` to the code provided by Akshay and it didn't work. I also tried changing it from `empty()` to `isset()` and that didn't work either. – David Aug 02 '18 at 18:33
  • you also have what seem to appear to be 2x data-id's of the same "id". That could also be part of the issue here. If this is a JS issue, I'm not the guy for this. ID's though, are supposed to be unique, should this be the case. – Funk Forty Niner Aug 02 '18 at 18:33
  • @FunkFortyNiner - The data-id is on two separate elements. The only time that the AJAX request is submitted is when the input with the class `cb_exempt` changes, the value that it gets is the DOM element that triggered the event's data-id and checked value. The values that are being passed to the PHP file via the POST request are correct as verified by both printing the $_POST and checking the parameters in the Network tab. – David Aug 02 '18 at 18:36
  • use inspect, and attention on network request, you could see whats going on, then try it in postman to make sure that all string required are available – Iqbal Rizky Aug 02 '18 at 19:19

3 Answers3

1

did you check mysql query log to ensure what is the query being executed.

you can check sql log file by query:

show variables like '%log%';

you can enable sql log by executing:

set global general_log=1;

Can set log file by:

set global general_log_file='/var/log/mysql/mysql.log';

please check sql log once.

Abhishek Sharma
  • 300
  • 2
  • 7
  • I've checked the error log and the only thing that appears in it for today are [Note]'s from whenever I initially started xampp. – David Aug 02 '18 at 19:25
  • 1
    when you enable sql query log, and whenever any query executed on your db, it will be log in mysql query log instead of error log. So check mysql query log whether your code is reachable to code piece where update sql query is written. – Abhishek Sharma Aug 02 '18 at 19:30
  • My apologies, I wasn't aware of the general log. It is executing, but for whatever reason the values passed are Strings: 931 Prepare UPDATE IGNORE `business` SET `is_exempt` = ? WHERE `business_id` = ? 931 Execute UPDATE IGNORE `business` SET `is_exempt` = 'true' WHERE `business_id` = '1' 931 Close stmt 931 Quit – David Aug 02 '18 at 19:42
1

I was able to figure out my problem and it has to deal with PHP being a loosely typed language. To fix the issue, I used bindValue explicitly converting the $_POST values by using boolval and intval, and then I also specified the PDO parameter type:

// Update the business' exempt status
$stmt = $db->prepare('UPDATE IGNORE `business` SET `is_exempt` = :exempt WHERE `business_id` = :business_id;');

// Add the parameters
$stmt->bindValue(':exempt',      boolval($_POST['exempt']),     PDO::PARAM_INT);
$stmt->bindValue(':business_id', intval($_POST['business_id']), PDO::PARAM_INT);

// Execute the query passing the new exempt value and the business_id
$stmt->execute();

I would not have figured this out without Abhishek Sharma's suggestion of checking the SQL's general log and recognizing that SQL was actually passing String values rather than Integer values:

Execute UPDATE IGNORE `business` SET `is_exempt` = 'true' WHERE `business_id` = '1'

UPDATE

Actually, boolval didn't work. I had to use this solution to convert the $_POST values: https://stackoverflow.com/a/38616262/1920035

David
  • 5,877
  • 3
  • 23
  • 40
  • 1
    Hey David. I revisited the question today and noticed you found what was causing all this. I'm glad to see that you were able to resolve this; *cheers* – Funk Forty Niner Aug 03 '18 at 19:28
0

generally you should use empty for only array. Use strlen($_POST['exempt']) > 0 instead of empty($_POST['exempt]) in you condition.

Akshay
  • 211
  • 1
  • 14
  • This does not resolve the issue. The same thing occurs where the POST request runs, but the query does not execute. Even if that was the issue, the Exception would be thrown from the Else statement which would trigger the POST request's fail callback. – David Aug 02 '18 at 18:21
  • try to print the db object. see what it says. – Akshay Aug 02 '18 at 18:24
  • I used the following code after my Try/Catch: `var_dump($db); print_r($db->errorInfo());` and the following is returned: `object(PDO)#1 (0) { } Array ( [0] => 00000 [1] => [2] => )` – David Aug 02 '18 at 18:28