I’m completely new to PHP. Working with ajax, php and WordPress I’m sending an object with ajax:
let import_data = {
action: 'import_data',
data: {
first_array: [], // this one is empty
second_array: [], // this one too
third_array: [1,2,3] // this one is full
}
};
I’ve checked the import_data object many times right before it was sent. The php, however, always receives:
import_data = {
action: 'import_data',
data: {
third_array: [1,2,3]
}
}
The question is why is that happening and how can I achieve receiving all arrays, whether they are empty or not, i.e.
import_data = {
action: 'import_data',
data: {
first_array: [],
second_array: [],
third_array: [1,2,3]
}
}
I need to refactor a lot of code now due to this issue so I’m trying to solve it as easy as possible, but if there is a common known right way to deal with it I’ll use it. Thanks in advance!
P.S. In case you wondering, yes, if all arrays being sent are full, php will receive all of them.
UPD In the comments I got I might’ve wanted to add contentType or json.strngify my data. It didn’t help, but I might do it wrong, so I’ll try to partly show my code below:
var import_data = {
action: 'start_import',
sliced_batch: {
rows_to_add: [],
rows_to_delete: [],
rows_to_update: [1,2,3,4,5,...]
}
};
function ajax_call(import_data) {
// ... processes
jQuery.ajax({
url: start_import_ajax.url, // url from php file
type: 'POST',
contentType: "text; charset=utf-8", // sending string with cyrillic (ukrainian lng)
dataType: 'application/json', // want to recieve json
data: JSON.stringify(import_data),
success: function(response) {
// ... processes import_data ...
if(it is the end of data) return;
else ajax_call(import_data);
},
error: function(e) {
// here is where I end up
}
}
PHP side is now pretty shy, as I just made a pause and wanted to see my data in console:
function start_import_callback() {
echo json_decode($_POST);
echo $_POST;
echo json_decode($_POST['sliced_batch']);
echo $_POST['sliced_batch'];
wp_die();
}
I’ve tried all echo
‘s one by one, but always saw:
{
"readyState": 4,
"responseText": "0",
"status": 400,
"statusText": "error"
}
When NOT stringifying and NOT specifying contentType/dataType it returns:
{
action: 'import_data',
sliced_batch: {
rows_to_update:
{
"ID": "00000006125",
"CatalogueNumber": "bla, bla",
"Category": "bla, bla",
"Manufacturer": "bla",
"Nomenclature": "blablablablabla",
"NomenclatureUkrainian": "bla",
"StockStatus": "instock",
"Price": "2 315",
"Parent": "blabla",
"Sorting": "99"
},
{},...
]
}
}
So, rows_to_delete: [] and rows_to_add: [] are missing…
2
Answers
So, thanks once again to @vee for his explanation, but here's one more thing I'd like to share as it was crucial to get everything to work.
First, for json_decode method the JS object keys should be double-quoted, i.e. NOT
or
BUT
Second and most important! When dealing with WordPress it sets its own rules and shows focuses! Depending on what answer you'd like to get, you may want to use function
wp_unslash()
. Looking at the stringified data in console I saw somth like this:It is the dirty work of WooCommerce (as I read from another's people opinion) and it hinders parsing it the right way, so my full code is: JS
PHP
You are using jQuery
dataType
options wrong!The
dataType:
value should be'json'
not'application/json'
because your value will request with HTTPaccept: */*
but if you use'json'
it will beaccept: application/json
.Option 1
Use content type
application/json
.The
contentType:
should be'application/json'
or'application/json;charset=utf-8'
.By this content type you will be now able to receive POST data in JSON but you cannot access them with
$_POST
because the data is not validapplication/x-www-form-urlencoded
.Full code for client side:
Code for PHP:
Option 2
Use content type
application/x-www-form-urlencoded
.With this content type, you will be able to access
$_POST
properly.However, to use this request content type in header, the jQuery itself will be modify the value if it is empty jQuery will be just delete it!! So, you need to JSON string only
sliced_batch
property.Here is the JS code:
PHP: