
javascript array
AJAX communication between the client browser and web server is a handy method of transferring data without forcing the user to refresh the page. Typically, the data sent to the server is a simple set of form fields or flags. However, it is also possible to submit more complex structured data. This tutorial will demonstrate 3 different methods used to pass multidimensional javascript arrays using jQuery and AJAX to a PHP web server.
The Wrong Way
My first instinct was that multidimensional JS arrays could be passed directly to jQuery's AJAX functions. I expected that the array would be automatically preserved in the request, and show up in PHP's $_GET/$_POST variables. The following example shows this doesn't work.
The code below attempts to post a JS associative array ("data", line 9) to the web server using jQuery's $.ajax() function. The $.ajax() function is jQuery's lowest level AJAX function, but still provides a high level approach and lots of options.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">
<head profile="http://gmpg.org/xfn/11">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>jQuery AJAX arrays</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
sendAjax = function(){
var data = {
foo: 123,
bar: 456,
rows: [
{
column1 : 'hello',
column2 : 'hola',
column3 : 'bonjour',
},
{
column1 : 'goodbye',
column2 : 'hasta luego',
column3 : 'au revoir',
},
],
test1:{
test2: {
test3: 'baz'
}
}
};
$.ajax({
type: 'post',
cache: false,
url: './ajax/',
data: data
});
}
</script>
</head>
<body>
<input type="button" style="width: 130px; height: 60px" value="send AJAX" onclick="sendAjax();" />
</body>
</html>
When the button is clicked, the following data shows up in PHP's $_POST variable:
Array
(
[foo] => 123
[bar] => 456
[rows] => [object Object]
[test1] => [object Object]
)
As shown, the first level of the array data is preserved (keys "foo" and "bar"). However, jQuery simply calls .toString() on the nested arrays at keys "rows" and "test1", and they get passed to PHP with the useless values "[object Object]".
Method 1 - Form input arrays
It's possible to name the keys of the JS array as HTML form input arrays (ie. named with square brackets) so that PHP decodes the array's key names as nested arrays. I don't recommend this method because it does not maintain the JS array's original structure in the Javascript. However, it can be used if you just need to get the AJAX request working without using JSON.
The original JS "data" array can be renamed/restructured as:
sendAjax = function(){
var data = {
foo: 123,
bar: 456,
'rows[0][column1]': 'hello',
'rows[0][column2]': 'hola',
'rows[0][column3]': 'bonjour',
'rows[1][column1]': 'goodbye',
'rows[1][column2]': 'hasta luego',
'rows[1][column3]': 'au revoir',
'test1[test2][test3]': 'baz'
};
$.ajax({
type: 'post',
cache: false,
url: './ajax/',
data: data
});
}
And the data is correctly received in PHP's $_POST variable:
Array
(
[foo] => 123
[bar] => 456
[rows] => Array
(
[0] => Array
(
[column1] => hello
[column2] => hola
[column3] => bonjour
)
[1] => Array
(
[column1] => goodbye
[column2] => hasta luego
[column3] => au revoir
)
)
[test1] => Array
(
[test2] => Array
(
[test3] => baz
)
)
)
Method 2 - JSON string parameter
This method converts the JS array to a JSON string, and passes it as a POST or GET parameter, which can be manually decoded back into an array by PHP. Modern browsers (Firefox 3, IE 8) now have a native JSON object that can be used to stringify JS arrays to JSON strings. The following example uses the YUI JSON utility to convert the JS array to a string ( json2 is another populary lightweight utility for handling JSON).
sendAjax = function(){
var data = {
foo: 123,
bar: 456,
rows: [
{
column1 : 'hello',
column2 : 'hola',
column3 : 'bonjour',
},
{
column1 : 'goodbye',
column2 : 'hasta luego',
column3 : 'au revoir',
},
],
test1:{
test2: {
test3: 'baz'
}
}
};
data = YAHOO.lang.JSON.stringify(data);
$.ajax({
type: 'post',
cache: false,
url: './ajax/',
data: {myJson: data}
});
}
On the PHP side, it's necessary to use json_decode() to convert the JSON $_POST parameter string (named "myJson") to an array:
<?php $data = json_decode($_POST['myJson'], true); print_r($data);
And the array is good to go:
Array
(
[foo] => 123
[bar] => 456
[rows] => Array
(
[0] => Array
(
[column1] => hello
[column2] => hola
[column3] => bonjour
)
[1] => Array
(
[column1] => goodbye
[column2] => hasta luego
[column3] => au revoir
)
)
[test1] => Array
(
[test2] => Array
(
[test3] => baz
)
)
)
Method 3 - JSON content-type
My favorite method is to simply JSON stringify the JS array, and pass it as the AJAX request's body. This requires that the content-type of the request be changed from the default "application/x-www-form-urlencoded" to "application/json", and that $.ajax()'s processData parameter be set to false so that the JSON data is not converted into a query string. Also, the type of request must be POST, as the GET method does not support submitting data in the request body.
sendAjax = function(){
var data = {
foo: 123,
bar: 456,
rows: [
{
column1 : 'hello',
column2 : 'hola',
column3 : 'bonjour',
},
{
column1 : 'goodbye',
column2 : 'hasta luego',
column3 : 'au revoir',
},
],
test1:{
test2: {
test3: 'baz'
}
}
};
data = YAHOO.lang.JSON.stringify(data);
$.ajax({
type: 'post',
cache: false,
url: './ajax/',
data: data,
processData: false,
contentType: 'application/json'
});
}
On the PHP side, it's necessary to manually read the JSON string directly from the request body using the php://input stream. The returned string can then be decoded into an array:
<?php
$data = file_get_contents('php://input');
$data = json_decode($data, true);
print_r($data);
Which gives us the array:
Array
(
[foo] => 123
[bar] => 456
[rows] => Array
(
[0] => Array
(
[column1] => hello
[column2] => hola
[column3] => bonjour
)
[1] => Array
(
[column1] => goodbye
[column2] => hasta luego
[column3] => au revoir
)
)
[test1] => Array
(
[test2] => Array
(
[test3] => baz
)
)
)
Hopefully this tutorial has helped you get multidimensional array data passed to your webserver using AJAX. If you know of another method, please submit it in the comments - thanks!
Thanks for the article! It was really handy. I was trying to use the jquery $.post but I didnt realise I had to separately json encode the array separately.
Great article! Thanks.
hei when i try
echo ($_POST);
its just shown
"Array"
why??
i tried method 1
@walesa - no offense, but I'm guessing you're a n00b to php. Use the print_r() or var_dump() functions to view human readable contents of arrays and objects:
print_r($_POST);
Great write up/explanations. I found method 3 to be the quickest to implement.