EzAnalyst EzAnalyst -4 years ago 121
PHP Question

Posting Array to PHP using ajax

I'm having issues posting an Array to a PHP page using AJAX. I've been using this question as guidance, but for whatever reason I still can't get it to work. From what I can tell by using

print_r($_POST)
, I am posting an empty Array, but on the HTML/Javascript page I use an alert to see that the Array has been filled. The post is working because it inputs blank values into a MySQL database on post, but I can't figure out why it is passing an empty Array. The code is as follows:

Javascript:

<script type="text/javascript">
var routeID = "testRoute";
var custID = "testCustID";
var stopnumber = "teststopnumber";
var customer = "testCustomer";
var lat = 10;
var lng = 20;
var timeStamp = "00:00:00";


var dataArray = new Array(7);
dataArray[0]= "routeID:" + routeID;
dataArray[1]= "custID:" + custID;
dataArray[2]= "stopnumber:" + stopnumber;
dataArray[3]= "customer:" + customer;
dataArray[4]= "latitude:" + lat;
dataArray[5]= "longitude:" + lng;
dataArray[6]= "timestamp:" + timeStamp;
var jsonString = JSON.stringify(dataArray);
function postData(){
$.ajax({
type: "POST",
url: "AddtoDatabase.php", //includes full webserver url
data: {data : jsonString},
cache: false,

success: function(){
alert("OK");
}
});
window.location = "AddtoDatabase.php"; //includes full webserver url
}
alert(JSON.stringify(dataArray))
</script>


PHP:

<?php
print_r($_POST);


$routeID = $_POST['routeID'];
$custID = $_POST['custID'];
$stopnumber = $_POST['stopnumber'];
$customer = $_POST['customer'];
$latitude = $_POST['latitude'];
$longitude = $_POST['longitude'];
$timestamp = $_POST['timestamp'];

$mysqli= new mysqli("fdb5.biz.nf","username","password","database");

mysqli_select_db($mysqli,"database");

$sql = "INSERT INTO Locations (routeID, custID, stopnumber, customer, latitude, longitude, timestamp) VALUES " .
"('$routeID','$custID','$stopnumber','$customer','$latitude','$longitude','$timestamp')";
mysqli_query($mysqli, $sql);

$error = mysqli_error($mysqli);
echo $error;
?>


print_r($_POST)
only displays Array() on the php page while the jsonString alert on the javascript page shows
["routeID:testRoute",
"custID:testCustID",
"stopnumber:teststopnumber",
"customer:testCustomer",
"latitude:10",
"longitude:20",
"timestamp:00:00:00"]


Anyone see what I'm doing wrong?

Answer Source

Note: The main cause for your code to output array() is the fact that you're redirecting the client before the asynchronous (AJAX) request has been sent/processed
Basically move window.location = "AddtoDatabase.php"; to the success callback, as mentioned further down.

First problem: Instead of using an array, you should use an object literal (~= assoc array in php).

To do so, change this bit:

var dataArray = new Array(7);//<== NEVER do this again, btw
dataArray[0]= "routeID:" + routeID;
dataArray[1]= "custID:" + custID;
dataArray[2]= "stopnumber:" + stopnumber;
dataArray[3]= "customer:" + customer;
dataArray[4]= "latitude:" + lat;
dataArray[5]= "longitude:" + lng; 
dataArray[6]= "timestamp:" + timeStamp; 

And write this, instead:

var dataObject = { routeID: routeID,
                   custID:  custID,
                   stopnumber: stopnumber
                   customer: customer,
                   latitude: lat,
                   longitute: lng,
                   timestamp: timeStamp};

There's nothing more too it. To finish off, just send the data like so:

function postData()
{
    $.ajax({ type: "POST",
             url: "AddtoDatabase.php",
             data: dataObject,//no need to call JSON.stringify etc... jQ does this for you
             cache: false,
             success: function(resopnse)
             {//check response: it's always good to check server output when developing...
                 console.log(response);
                 alert('You will redirect in 10 seconds');
                 setTimeout(function()
                 {//just added timeout to give you some time to check console
                    window.location = 'AddtoDatabase.php';
                 },10000);
             }
    });

Secondly, your postData function redirects the client before the AJAX request has been sent! After the call to $.ajax, you have a window.location = "AddtoDatabase.php"; statement in your code. If you want the client to be redirected after the ajax call, you will have to move that expression to your success callback function (the one where I log the response) in the second snippet ^^.

When you've changed all this, your $_POST variable should look about right. If not, print out the $_REQUEST object and see what the response of an ajax call is then.

Lastly, please be aware that using an api that supports prepared statements (and thus protects you against most injection attacks), that doesn't mean stringing unchecked POST/GET data into a query is any safer than it used to be...
Bottom line: When you use an API that supports critical safety features such as prepared statements use those features.

Just to be absolutely clear, and complete, here's a slightly reworked version of the PHP code, too:

$routeID = $_POST['routeID'];
$custID = $_POST['custID'];
$stopnumber = $_POST['stopnumber'];
$customer = $_POST['customer'];
$latitude = $_POST['latitude'];
$longitude = $_POST['longitude'];
$timestamp = $_POST['timestamp'];
//you're connecting OO-style, why do you switch to procedural next?
//choose one, don't mix them, that makes for fugly code:
$mysqli = mysqli_connect('fdb5.biz.nf', 'username', 'password', 'database');//procedural
//or, more in tune with the times:
$mysqli= new mysqli("fdb5.biz.nf","username","password","database");//OO

mysqli_select_db($mysqli,"database");
//or
$mysqli->select_db('database');

Check the docs to see the procedural counterpart of all methods I'll be using from here on end, if you want. I prefer the OOP-API

//making a prepared statement:
$query = 'INSERT INTO Locations 
          (routeID, custID, stopnumber, customer, latitude, longitude, timestamp) VALUES 
          (?,?,?,?,?,?,?)';
if (!($stmt = $mysqli->prepare($query)))
{
    echo $query.' failed to prepare';
    exit();
}
$stmt->bind_param('s', $routeID);
$stmt->bind_param('s',$custID);
//and so on
$stmt->bind_param('d', $latitude);//will probably be a double
$stmt->execute();//query DB

Useful links on prepared statements:

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download