Search code examples
javascriptphparraysajax

Can't send a Multidimensional Array from JavaScript through AJAX to PHP


I saw a lot of problems regarding the exact same thing. But I tried so many things that I'm really not sure if what I'm doing even works anymore.

So, I have this multi-dim array, which I create by looping through an html table., I want to send it to PHP, so I can loop it, and create the objects I need to store it in a database.

But all I get from PHP when I try to loop it through a for each is

"Warning: Invalid argument supplied for foreach()"

function ReturnFamilyMembers() 
{
   var Family = [];
   var Table= document.getElementById('FamilyTable');
   var RowQuantity= Table.rows.length; 
   
   for (var i = 0; i < RowQuantity; i++)
   {
     var Columns= Table.rows.item(i).cells;
     var ColumnQuantity= Columns.length;
     Family[i] = [];
   
        for(var j = 0; j < ColumnQuantity; j++)
        {
          Family[i][j] = Columns.item(j).innerHTML;
        }
    }

    var headers =
    {
        'Content-type': 'application/x-www-form-urlencoded',
        'X-Requested-With': 'XMLHttpRequest'
    };
    
    var FamilyArray = encodeURIComponent( JSON.stringify( Family) );
    /*console.info( payload );*/

    var xhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");

    /* Add a callback function to process any response from target url ( Worker.php )*/
    xhttp.onreadystatechange = function()
                            {
                                if( xhttp.readyState == 4 && xhttp.status == 200 )
                                {
                                    cbReturnFamilyMembers.call( this, xhttp.response );
                                }
                            };
                                
    xhttp.open( 'POST', 'Worker.php', true ); 
    for( header in headers ) xhttp.setRequestHeader( header, headers[ header ] );
    xhttp.send( 'Family=' + FamilyArray );

}

function cbReturnFamilyMembers($resp,$response)
{
    alert($resp + $response);
}
}
     

And the PHP side...

$Family =  json_decode( $_POST['Family'],true);

foreach($Family as $Array)  ---> This line launches the error.
{
   foreach($Array as $Value) 
   {
    ///object creation
   }
}

Thank you in advance. I think I'm really stuck here, since I'm new to PHP, JS and AJAX, everything seems to happen magically. (Can't really say if I'm doing thing's the right way.) I hope I'm being clear enough, or tell me please if I can clarify anything.

--------------------------------------****--------------------------------------

EDIT: I'm sorry for the late reply and I thank you for your answers. I'm going to update the code, so you can see what I have done so far. (Basically I changed the Ajax Part, to be a POST action like you guys said). I guess I did not explain the whole thing pretty well, this array must be sent through submitting a form, this function is called on the "onSubmit" (sorry for the lack of explanation). I came to realize I did not have a member in the $_POST array from php that's called "Family", because I got an error of "Index not found", so, I hid an input in the form and called it that way in the NAME property. In spite of all that, I keep receiving a non-array like value on the php side, (Actually, when I echo it, it prints a one (1)). I'm starting to think of other way's of passing an array, but that's why I used JS and ajax in the first place. I'm doubting of the "xhttp.send( 'Family=' + Array );" part... is it really posting the array on the index ['Family'] of the $_POST array?, I wonder. Maybe the array passed as a value is overwritten by the input of the form (That has no value when submitted, actually)

EDIT,AGAIN****************

Changed the code, and worked perfectly.(Added the Cast to an Array object)

$Family =  (Array)json_decode( $_POST['Family']);

Solution

  • I didn't notice last night when I posted my initial comment some of the minor errors with your original function, though others have picked up on them and passed comment above - the function was supposedly sending via POST but there were no parameters sent in the send() method, only appended to the url as you would do for a GET request. Also, though not critical I believe, you were not setting any headers with the request and there also is no callback function.

    The altered code below does send the contents from a table as intended over POST

    <script type='text/javascript'>
        /* callback function to handle response data */
        function cbReturnFamilyMembers( response ){
            alert( response )   
        }
    
        function ReturnFamilyMembers() {
           var Family = [];
           var Table= document.getElementById('FamilyTable');
           var RowQuantity= Table.rows.length; 
    
           for ( var i = 0; i < RowQuantity; i++ ){
                var Columns= Table.rows.item(i).cells;
                var ColumnQuantity= Columns.length;
                Family[i] = [];
                for( var j = 0; j < ColumnQuantity; j++ ) Family[i][j] = Columns.item(j).innerHTML;
            }
    
            /* XHR headers to be set */
            var headers={
                'Content-type': 'application/x-www-form-urlencoded',
                'X-Requested-With': 'XMLHttpRequest'
            };
            var payload=encodeURIComponent( JSON.stringify( Family ) );
            /*console.info( payload );*/
    
            var xhttp=window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
    
            /* Add a callback function to process any response from target url ( Worker.php )*/
            xhttp.onreadystatechange=function(){
                if( xhttp.readyState==4 && xhttp.status==200 ){
                    cbReturnFamilyMembers.call( this, xhttp.response );
                }
            };
    
            xhttp.open( 'POST', 'Worker.php', true ); 
            for( header in headers ) xhttp.setRequestHeader( header, headers[ header ] );
            xhttp.send( 'Family='+payload );
        }
    </script>