Home > Software engineering >  AJAX post data is not received in PHP
AJAX post data is not received in PHP

Time:11-05

I've recently started learning PHP from the very basics. After following some tutorials I'm trying to learn something and here I'm facing a problem and after visiting different URLs for similar issues but couldn't solve mine.

I have a page where user enters data in form and that data is added in a grid (table) by using Add button. On Save button the table data is sent to the PHP using Ajax. Along with this table data there are 3 text fields on the same form whose data is not added in that table and those text fields data also being sent to the PHP by using Ajax Call. Here is my Save button code.

$("#save").on("click", function (e) {
        e.preventDefault();
        debugger
        if (!iQuantity || !iDiscount) { // This is checking validation.
            $("#message").fadeIn(1000).html(`<div >Please fill all the fields</div>`);
            $("#message").fadeOut(3000);
        } 
              
        if ($("#amountPayable").val() === "" || $("#amountPayable").val() == 0 || $("#amountPaid").val() === "" || $("#amountPaid").val() == 0 
            || $("#discountGiven").val() === "" ) {

            $("#message").fadeIn(1000).html(`<div >Please fill all the fields</div>`);
            $("#message").fadeOut(3000);

        } else {

                var tableData = [];
                $('#addTable tbody tr').each(function () {
                    debugger
                    var rowData = {
                        itemId: $(this).find('td:eq(0)').text(),    // first column in row is trainee  (on index 0)
                        saleId: $(this).find('td:eq(1)').text(),   // second column in row is title
                        qty: $(this).find('td:eq(3)').text(),   // 4th column in row is attend
                        amount: $(this).find('td:eq(4)').text(),  // 5th column in row is trainer                        
                    };
                    tableData.push(rowData);
                });

            var formFields = {   // This takes text fields data
                amountPayable: $("#amountPayable").val(),
                amountPaid: $("#amountPaid").val(),
                discountGiven: $("#discountGiven").val(),
            };

            // Here I'm making object of both above objects.
            var dataToSend = {
                td: JSON.stringify(tableData), // Grid data
                ff: JSON.stringify(formFields), // Text fields data
            };
            

            console.log("ok");
            $("#message").html("");
            debugger
            $.ajax({
                url: "../add-pages/add-orders.php",
                type: "POST",
                data: dataToSend,
                processData: false,
                contentType: false,
                
                success: function (receivedData) {
                    debugger
                    var dt = receivedData;
                    $('#message').fadeIn(1000).html(receivedData);
                    $("#message").fadeOut(3000);

                    // --------------------------------------------- For Claring the Form Fields, ---------------------------------------------
                    $(':input', '#addOrdersData')
                        .not(':button, :submit, :reset, :hidden')
                        .val('')
                        .prop('checked', false)
                        .prop('selected', false);
                    
                    $("#update").attr("disabled", true);
                }
            });
        }
    });

And here is my PHP code where I'm receiving the code:


    <?php
     date_default_timezone_set('Asia/Karachi');

     $tableData = json_decode($_POST['td']); // Grid data
     $ff = json_decode($_POST['ff']); // Grid data
   ?>

The error I received in PHP is:

Warning: Undefined array key "td" in C:\xampp\htdocs\superStore\add-pages\add-orders.php on line 4

Please guide me where the mistake is happening.

Thank you very much, SOF.

CodePudding user response:

    data: dataToSend,
    processData: false,
    contentType: false,

You've told jQuery not to process the data (so XHR is going to convert your object to the string [object Object], which is useless) and to not override the Content-Type (so XHR is going to set it to text/plain and PHP won't even try to parse the data).

Don't do that.


Aside:

var dataToSend = {
    td: JSON.stringify(tableData), // Grid data
    ff: JSON.stringify(formFields), // Text fields data
};

If you send PHP URL Encoded Form Data with the right naming conventions (e.g. td[foo][bar][3]) then PHP will automatically parse that into associative arrays inside $_POST.

If you pass jQuery.ajax a nested object then it will automatically convert the data structure to that PHP naming convention.

You can skip all your JSON encoding and decoding.

CodePudding user response:

As mentioned in the comments, contentType: false tells jQuery to not send any Content-Type header at all - so PHP has no reason to assume this was actually a application/x-www-form-urlencoded request, and will therefor not populate $_POST. And processData: false tells jQuery not to automatically convert the provided data into form-url-encoded format either, so it will just send the stringified version of your object, which by default in JS is [object Object] - and that is clearly no use to PHP. Generally those two options are only useful when trying to upload files and/or raw FormData objects.

But even we fixed that, putting JSON inside a url-encoded variable really doesn't make a lot of sense either. Why mix different data formats and risk encoding issues etc. when you could just use one format very easily?

If you want to send JSON then it's better to set the application/json content-type and send one JSON string, by itself containing all the data, in the request body. Then you can adjust your PHP code to receive the JSON-encoded data.

For example:

JavaScript:

var dataToSend = JSON.stringify({
    td: tableData, 
    ff: formFields,
});

$.ajax({
  url: "../add-pages/add-orders.php",
  method: "POST",
  contentType: "application/json",
  data: dataToSend,
  success: function (receivedData) {
    var dt = receivedData;
    $('#message').fadeIn(1000).html(receivedData);
    $("#message").fadeOut(3000);

    //--------------------------------------------- For Claring the Form Fields, ---------------------------------------------
    $(':input', '#addOrdersData')
      .not(':button, :submit, :reset, :hidden')
      .val('')
      .prop('checked', false)
      .prop('selected', false);
                    
    $("#update").attr("disabled", true);
  }
});

PHP:

$data = json_decode(file_get_contents('php://input'), true);
print_r($data); //just for debugging purposes

//and then, for example, if you need to:
$tableData = $data["td"];
$ff = $data["ff"];

References:

  • Related