For my project, I'm using this:
var arr = new Map(); to create a map with JS.
After each click on elements, I'm using this to populate the map.
arr.set(roomid + '_' + date, {
status: updatedStatus,
date: date,
roomid: roomid
});
After few clicks, on the console panel, I have:
[Log] Map {"48_2019-03-09" => {status: "Open", date: "2019-03-09", roomid: 48}, "48_2019-03-19" => {status: "Open", date: "2019-03-19", roomid: 48}} (2) (app.js, line 93)
So, this is what I want.
Now I need to pass this datas to PHP via Ajax like this:
$.ajax({
type: 'POST',
data: { datas: arr },
url : 'update.php',
success: function(responseText){
...
}
});
On my PHP page, I have the following code:
$arr = $_POST;
print_r($arr);
But this code output:
Array
(
)
But this doesn't work because my PHP page print an empty array.
What I'm doing wrong please ?
Thanks.
you need to convert the map to a json object. Easiest way I know to do this is to stringify and then parse to a JSON object.
JSON.parse(JSON.stringify([...arr]))
$.ajax({
type: 'POST',
data: { datas: JSON.parse(JSON.stringify([...arr])) },
url : 'update.php',
success: function(responseText){
...
}
});
Ref: http://2ality.com/2015/08/es6-map-json.html
Ajax expects an object, not a Map. So you need to convert your Map to an object before passing it to the ajax request.
function mapToObject(map) {
var obj= {}
map.forEach(function(value, key) {
obj[key] = value
}
return obj
}
....
$.ajax({
type: 'POST',
data: { datas: mapToObject(arr) },
url : 'update.php',
success: function(responseText){
...
}
});
EDIT: just noticed, if you need to pass a full JS object to PHP you need to convert it to JSON.
So the real ajax call should be:
$.ajax({
type: 'POST',
data: JSON.stringify({ datas: mapToObject(arr) }),
url : 'update.php',
success: function(responseText){
...
}
});
and on your server:
$data = file_get_contents("php://input");
print_r(json_decode($data, true));
Related
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...
You are using jQuery dataType options wrong!
The dataType: value should be 'json' not 'application/json' because your value will request with HTTP accept: */* but if you use 'json' it will be accept: 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 valid application/x-www-form-urlencoded.
Full code for client side:
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: 'test.php', // url from php file
type: 'POST',
contentType: "application/json;charset=utf-8", // sending string with cyrillic (ukrainian lng)
dataType: 'json', // want to recieve json
data: JSON.stringify(import_data),
success: function(response) {
// ... processes import_data ...
},
error: function(e) {
// here is where I end up
}
});
}
Code for PHP:
$data = json_decode(file_get_contents('php://input'), true);
// use $data['sliced_batch'] to access `rows_to_add`, `rows_to_delete` etc.
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:
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
// modify `sliced_batch` property to be JSON string to prevent jQuery remove empty properties.
import_data.sliced_batch = JSON.stringify(import_data.sliced_batch);
jQuery.ajax({
url: 'test.php', // url from php file
type: 'POST',
// just remove contentType option. It is no need.
//contentType: "application/json;charset=utf-8", // sending string with cyrillic (ukrainian lng)
dataType: 'json', // want to recieve json
data: import_data,
success: function(response) {
// ... processes import_data ...
},
error: function(e) {
// here is where I end up
}
});
}
PHP:
$sliced_batch = ($_POST['sliced_batch'] ?? '');
$sliced_batch = json_decode($sliced_batch, true);
// you can now access $sliced_batch['rows_to_add'], etc...
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
$bad_json = '{ bar: "baz" }';
json_decode($bad_json); // null
or
$bad_json = '{ 'bar': "baz" }';
json_decode($bad_json); // null
BUT
$bad_json = '{ "bar": "baz" }';
json_decode($bad_json); // array("bar" => "baz")
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:
"\u0421\u0435\u0440\u0432\u0435\u0440: \u0424\u0430\u0439\u043b\u0456\u0432 av_imp_p_WEB.csv \u0456 av_imp_p_WEB_previous.csv \u043d\u0435 \u0431\u0443\u043b\u043e \u0432\u0438\u044f\u0432\u043b\u0435\u043d\u043e. \u041f\u043e\u0447\u0438\u043d\u0430\u044e \u0456\u043c\u043f\u043e\u0440\u0442 \u0432\u0441\u044c\u043e\u0433\u043e
// it is more common for contentType: "application/x-www-form-urlencoded"
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
var import_data = {
"action": "start_import",
"sliced_batch": {
"rows_to_add": my_data1,
"rows_to_delete": my_data2,
"rows_to_update": my_data3
}
};
function ajax_call(import_data) {
// ... processes
jQuery.ajax({ // ajax to php to save the file to uploads and move it to the plugin's folder
url: start_import_ajax.url, // url from php file
type: 'POST',
//contentType: "application/json;charset=utf-8", // what you send
dataType: 'JSON', // what you would like as a response
data: {
"action": import_data.action,
"sliced_batch": JSON.stringify(import_data.sliced_batch)
},
success: function(response) {
//response = JSON.parse(response); // if you'd like to console.log what you've sent
console.log(response);
}
....
PHP
$sliced_batch = wp_unslash($_POST['sliced_batch']);
$sliced_batch = json_decode($sliced_batch, true);
$result = start_import($sliced_batch);
if($result == 0) {
echo json_encode(["status" => 0]);
} else echo json_encode(["status" => 1]);
I am trying to send an array with ajax to PHP. Could someone please
suggest a way to achieve it ?
My Code :
guardarRuta: function(){
console.log('Guardando ruta...');
for (var i = 0; i < marcadores.length; i++) {
latLngMarcadores.push({'tipo': 'parada', 'latitud': marcadores[i].position.lat(), 'longitud': marcadores[i].position.lng()});
}
latLngOrigenDestino.push({'tipo': origenDestino[0].tipo, 'latitud': origenDestino[0].marker.position.lat(), 'longitud': origenDestino[0].marker.position.lng()});
latLngOrigenDestino.push({'tipo': origenDestino[1].tipo, 'latitud': origenDestino[1].marker.position.lat(), 'longitud': origenDestino[1].marker.position.lng()});
Ext.Ajax.request({
url: 'http://becea.mx/dabbawalas_valeria/adm/save_route_adm.php',
method: 'POST',
params: {
nombre: 'RutaNueva',
data: {"marcas" : JSON.stringify(latLngMarcadores)},
},
reader: {
type: 'json',
rootProperty: 'status'
},
success: function(response) {
//Ext.Viewport.setMasked(false);
Ext.Msg.alert('Listo', 'Ruta guardada con éxito!');
},
failure: function() {
//Ext.Viewport.setMasked(false);
Ext.Msg.alert('ERROR', 'Error de servidor');
}
});
}
<?php
$elements = json_decode($_POST['marcas']);
echo($elements[0]);
?>
First, as pointed by #Burak Öztürk, you must directly send data as is (not using JSON.stringify()), like this:
params: {
nombre: 'RutaNueva',
data: {"marcas" : latLngMarcadores},
},
Then data is an object of objects, not an array.
Currently in PHP you're decoding it with:
$elements = json_decode($_POST['marcas']);
This keeps objects as objects! Instead use:
$elements = json_decode($_POST['marcas'], TRUE);
This way, objects become associative arrays and you can access and iterate them as expected.
I have a little issues with my JS code.
I have a AJAX and I want to get the variable in PHP.
All works fine except the "param" data.
here is the code:
$('#signup_submit').click(function (event){
param = jQuery('input').filter(function() {
return this.name.match(/param/);
}).serialize();
event.preventDefault();
$.ajax({
type: "POST",
url: result.php,
data: {
action: 'submit_ajax',
email: $('#email').val(),
send_welcome: true,
listId: $('#listid').val(),
param: param
},
success: function(msg) {
console.log('ok');
}
});
});
The result var_dump for the param (PHP):
param%5Bconfirmation%5D=1
it should be something like:
array(1){ 'confirmation'=>1 }
Any idea to fix it?
thanks
Your posted $param var looks like param[confirmation]=1
And you need parse_str function to get serialized data:
parse_str($param, $output);
Output
var_dump($output);
array(1) {
["param"]=>
array(1) {
["confirmation"]=>
string(1) "1"
}
}
Or get specific index directly:
parse_str($param);
echo $confirmation; // 1
Use serializeArray instead of serialize.
param = jQuery('input').filter(function() {
return this.name.match(/param/);
}).serializeArray();
The output is because param is being dual-encoded, once by .serialize():
param = jQuery('input')....serialize();
console.log(param);
// "param%5Bconfirmation%5D=1"
And, again for data:, which is run through $.param() by $.ajax():
console.log($.param({
param: param
}));
// "param=param%255Bconfirmation%255D%3D1"
While the 1st round of encoding is decoded for $_POST:
var_dump($_POST['param']);
// string(25) "param%5Bconfirmation%5D=1"
You'll have to manually decode the 2nd round with parse_str():
$param = array();
parse_str($_POST['param'], $param);
var_dump($param);
// array(1) { ["confirmation"]=> int(1) }
You can also try to avoid the dual-encoding by concatenating param with the other encoded data:
data: param + '&' + $.param({
action: 'submit_ajax',
email: $('#email').val(),
send_welcome: true,
listId: $('#listid').val()
}),
%5B is [
%5D is ]
you could use this function to fix the encoding before you submit
function fixedEncodeURI (str) {
return encodeURI(str).replace(/%5B/g, '[').replace(/%5D/g, ']');
}
Like so:
$('#signup_submit').click(function (event){
param = jQuery('input').filter(function() {
return this.name.match(/param/);
}).serialize();
event.preventDefault();
$.ajax({
type: "POST",
url: result.php,
data: {
action: 'submit_ajax',
email: $('#email').val(),
send_welcome: true,
listId: $('#listid').val(),
param: fixedEncodeURI(param)
},
success: function(msg) {
console.log('ok');
}
});
});
I want to sent some JSON data with ajax this is my script
$(document).ready(function () {
jsonObj = [];
$('.img-bg').map(function () {
var self = this;
var next = $(this).nextAll('.rectangle');
if (next.length > 0) {
next.map(function () {
item = {};
item.src = self.src;
item.left = $(this).css('left');
item.height = $(this).css('height');
jsonObj.push(item);
});
}
});
var data={ "firstName" : "Ray" };
jsonString = JSON.stringify(jsonObj);
$.ajax({
url: 'testajax.php',
type: 'post',
dataType: 'json',
data: jsonString,
success: function(response) {
console.log(response);
}
});
});
</script>
And jsonObj gives
[Object, Object, Object]
0: Object
height: "341px"
left: "10px"
src: "http://localhost/docAuto/test.jpg"
__proto__: Object
1: Object
height: "321px"
left: "54px"
src: "http://localhost/docAuto/image.jpg"
Output of jsonString
[{"src":"http://localhost/docAuto/test.jpg","left":"10px","height":"341px"},
{"src":"http://localhost/docAuto/image.jpg","left":"54px","height":"321px"},
{"src":"http://localhost/docAuto/image.jpg","left":"43px","height":"295px"}]
Both var is not send, but if I send data it's working. My Json file is wrong?
You need to pass the options to data as an object. Here's a fixed $.ajax call:
$.ajax({
url: 'testajax.php',
type: 'post',
dataType: 'json',
data: { json : jsonString },
success: function(response) {
console.log(response);
}
});
Your testajax.php should now see the jsonString in URL variable json.
edit: fixed my response. I misread your code due to the problems with indentation.
You don't need to use JSON.stringify to send a json object via the jQuery $.ajax() method... jQuery will take care of that conversion behind the scenes. Just use jsonObj as your data parameter.
You need to use POST in upper case.
I think your JSON is missing the key part. When I added the key: 'first', it worked. You got one mighty Json Array there:
JSON.stringify({ first: [{"src":"http://localhost/docAuto/test.jpg","left":"10px","height":"341px"},
{"src":"http://localhost/docAuto/image.jpg","left":"54px","height":"321px"},
{"src":"http://localhost/docAuto/image.jpg","left":"43px","height":"295px"}] })
JSFiddle link http://jsfiddle.net/jyrkim/suvG7/1/
Json Arrays, syntax etc link
I created array like this ["9", "ques_5", "19", "ques_4"]. Now I want to send it from JS to PHP but I'm not getting proper results. My JS code is:
$(".button").click(function(e) {
e.preventDefault();
$.ajax({
type : 'post',
cache : false,
url : 'test/result.php',
data : {result : stuff},
success: function(resp) {
alert(resp);
}
});
});
In the above code stuff is an array which contains records. How can I send this array with above code and then in PHP I want to process this array like ques_5 is the key and 9 become the value for that key.
You can pass the data to the PHP script as a JSON object. Assume your JSON object is like:
var stuff ={'key1':'value1','key2':'value2'};
You can pass this object to the php code in two ways:
1. Pass the object as a string:
AJAX call:
$.ajax({
type : 'POST',
url : 'result.php',
data : {result:JSON.stringify(stuff)},
success : function(response) {
alert(response);
}
});
You can handle the data passed to the result.php as :
$data = $_POST["result"];
$data = json_decode("$data", true);
//just echo an item in the array
echo "key1 : ".$data["key1"];
2. Pass the object directly:
AJAX call:
$.ajax({
type : 'POST',
url : 'result.php',
data : stuff,
success : function(response) {
alert(response);
}
});
Handle the data directly in result.php from $_POST array as :
//just echo an item in the array
echo "key1 : ".$_POST["key1"];
Here I suggest the second method. But you should try both :-)
If you want to send key value pairs, which is what I am seeing, it would be better to use a PHP JSON library (like this one... http://php.net/manual/en/book.json.php)
Then you can send actual key value pairs, using JSON format like...
{"ques_5" : "19", "ques_4": "19"}
Try this
var array = ["9", "ques_5", "19", "ques_4"];
console.log(array.join(","));
above code will output string with comma separated like 9,ques_5,19,ques_4then paste it to ajax call.
And then in php explode that string.
Other possible solutions.
First
var obj = { 'item1': 'value1', 'item2': 'value2' };
$.ajax(
{
type: 'post',
cache: false ,
url: 'test/result.php',
data: { result : JSON.stringify(obj) },
success: function(resp)
{
alert(resp);
}
});
Second
var a = $.JSON.encode(obj);
$.ajax(
{
type: 'post',
cache: false ,
url: 'test/result.php',
data: { result : a },
success: function(resp)
{
alert(resp);
}
});
In PHP File
<?php
$json = $_POST["data"]
var_dump(json_decode($json));
?>
You can send the array in json format to the php and then use json_decode function to get back the array like
In ajax call you have to send json for that you need to first make array of the values so that you get it in right form
so that you json look like {"ques_5":"9","ques_4":19}
and use in ajax call
data: JSON.stringify(`your created json`),
contentType: "application/json; charset=utf-8",
dataType: "json",
IN PHP it look like
<?php
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
var_dump(json_decode($json));
?>
I would like to share a complete example that works for me in order to avoid making each JavaScript function for each PHP function
// on the HTML side a simple JavaScript call from a link
<a href="javascript:CargaZona('democonllamada', 'tituloprin', {'key1':'value1','key2':'value2'})" >test</a>
<div id='tituloprin' >php function response here!</div>
// on JavaScript side
function CargaZona(fc, div, params) {
var destino = "#" + div;
var request = $.ajax({
url : "inc/phpfunc.php",
type : "POST",
data : {
fc : fc,
params : JSON.stringify(params)
},
dataType : "html"
});
request.done(function (msg) {
$(destino).html(msg);
});
request.fail(function (jqXHR, textStatus) {
alert("Request failed: " + textStatus);
});
}
// on phpfunc.php page
<?php
$params = "{'key1':'value1','key2':'value2'}";
$fc = 'def';
if (isset($_POST['fc'])) { $fc = $_POST['fc']; }
if (isset($_POST['params'])) { $params = $_POST['params']; }
switch ($fc) {
default:
call_user_func($fc,$params);
}
function democonllamada($params) {
$params = json_decode("$params", true);
echo "ok llegaron".$params['key1'];
}
?>