Send multidimensional arrays to PHP with jQuery and AJAX

AJAX

javascript object

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 4 different methods used to pass multidimensional javascript arrays (aka. javascript objects) using jQuery and AJAX to a PHP web server.

UPDATE: The Easy Way... for jQuery 1.4.0+

Thanks to Pirumpi for pointing out that jQuery 1.4.0 now automatically serializes arrays and objects parameters for AJAX functions. That means it's super easy to pass them to PHP:

<!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="//ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.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 structured data shows up 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
                )

        )

)

This will only work with jQuery 1.4.0+. Otherwise jQuery simply calls .toString() on the nested array at key "rows" and nested object at key "test1", and they get passed to PHP with the useless values "[object Object]".

NOTE: The remainder of this article will demonstrate how to send objects and arrays for jQuery versions lower than 1.4.0.

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!

Comments

  1. 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.

  2. Great article! Thanks.

  3. hei when i try
    echo ($_POST);

    its just shown
    "Array"

    why??

    i tried method 1

  4. @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);

  5. Travis

    Great write up/explanations. I found method 3 to be the quickest to implement.

  6. Great article, Thanks for sharing your code

  7. monkey

    Good! I have found this for along time! Thanks!

  8. Linh Thi Nguyen

    Very good article, keep up the good work. Thanks you very much.

  9. Marcin

    good stuff - thnx dude!

  10. citanga

    Hole in one!!! This is just amazing!

  11. I love you bro again!

  12. Hi,
    Good article!
    I used first method and it is more useful.

    Thanks,

  13. rojkoong

    Good article. This is very useful for me.

  14. Method 3 "almost" works for me, and comes the closest out of the provided examples. However, my problem is that I'm sending requests to a script which also handles traditional form "post" requests.

    The client has a multi-select named "select[]". Submitting that in a form causes PHP to interpret $_POST['select'] as a PHP array.

    However, I need to also push that same data via AJAX. The scripts must work for both the form submission as well as the AJAX request.

    Any suggestions?

  15. Very nice article. Was very useful.

  16. luan

    thank a lot

  17. Hey method three works. HOwever I tried the function without setting the content type and processdata option. Im not sure why it still works though

  18. [...] White has written a very good article about [...]

  19. Pirumpi

    I hope people read this comment and don't make the mistake the author made on using any Yahoo plugging this is a real solution

    jQuery code:

    var work = new Array;

    $(document).ready(function(){
    work.push({
    'id':1,
    'name':'carlos'
    });
    work.push({
    'id':2,
    'name':'jenny'
    });
    work.push({
    'id':3,
    'name':'fatu',
    });
    work.push({
    'id':4,
    'name':'chay'
    });

    $("#coco").load('test.php',{
    'myArray':work
    });
    });

    PHP Code:
    $results = $_POST['myArray'];

    for($counter = 0; $counter < count($results); $counter++){
    echo $results[$counter]['name'] . "";
    }

  20. @Pirumpi - thanks, your solution is valid for jQuery 1.4.0+, and I have updated this article to reflect that.

  21. ali smith

    hi

    Your article is very useful

    Thank's Tim White

    ;)

  22. [...] Envío de arrays multidimensionales de PHP a jQuery haciendo uso de la tecnología AJAX [...]

  23. Rizwan

    Thank u boss

Leave a Comment