Passing an array from PhP to jQuery using JSON and $.ajax - php

First off, I apologise since this is my first time working with JSON.
My website has a client script that requests person data from the server. The server first queries the database (using mysql and mysqli) and then returns the data (names, ages, etc.) to the client side.
Specifically, I want to pass an associative array from the PhP side to the client side.
After doing some research, I decided to do this with AJAX JSON calls.
The client side call is done like this:
var person_id = $('#my_text_box').val();
$.ajax({
url: 'php/upload/my_server_script.php',
method: 'POST',
data: {id: person_id},
dataType: 'json',
cache: false,
success: function(response_data)
{
alert(response_data['name']); //The server should return an associative array
console.log(response_data);
},
error: function(jqXHR, textStatus, errorThrown)
{
console.log(arguments);
console.log(jqXHR.responseText);
console.log('Error: ' + errorThrown + ' ' + textStatus + ' ' + jqXHR);
}
});
The server side calls a method that will query the database and give the details of the person with the requested ID.
$id = $_POST['id'];
function getPersonData($id)
{
$personData = array();
(1 - Connect and SELECT name FROM Persons WHERE id = {$id}
2 - Fill the $personData array with result row
3 - Name will be saved in $personData['name'])
return json_encode($personData);
The AJAX call fails with the error 500 - Internal Server Error. When I check the contents of the server response on the browser (On Chrome, Network tab), it says there is no response (This request has no response data available).
The thing is, this code works perfect locally. But when I upload it to my cloud web server, the only AJAX calls in my website that fail are the ones that use JSON as the format for the data being transferred. The other ones work fine.
A couple of things I've tried:
First, checking if the array on the PhP side is empty or built with errors. It's not, all the correct values are there;
Second, including application/json to the cloud web server mime.type file (It's Apache);
Then, including a header('Content-Type: application/json'); in my server-side script.
Also, adding "contentType: 'application/json' " to the client-side $.ajax.
None of these four worked. What could I be forgetting?
Note: The browser's log reads as follows:
Arguments[3]
0: Object
1: "error"
2: "Internal Server Error"
callee: function (jqXHR, textStatus, errorThrown)
length: 3
__proto__: Object
*(url of my script file)*
Error: Internal Server Error error [object Object] ^
Note #2: Full PhP code:
//Fetch persondata for a specific ID, and encode the data in an array in JSON format
function JSONSelectPersonDataFromID($ID)
{
$personData = array(); //Array or array with results
//If querysuccess, commit. Else, rollback
$querySuccess = True;
//This method opens connection with root user
$conn = OpenDBConn();
$conn->autocommit(False);
try
{
if($videoID > 0)
{
$sql = "SELECT name FROM Persons WHERE id={$id}";
//Debugging
//echo $sql . "<br>";
$persons = mysqli_query($conn, $sql);
if(mysqli_connect_errno($conn))
{
$querySuccess = False;
}
if(isset($persons ) && (count($persons ) > 0))
{
//Loop through every scene
$personData = $persons ->fetch_array(MYSQLI_ASSOC);
}
else
{
return null;
}
}
else
{
$querySuccess = False;
}
}
catch(Exception $e)
{
$querySuccess = False;
}
if(!$querySuccess)
{
//Rollback
$conn->rollback();
die("Transaction failed");
}
else
{
//Commit
$conn->commit();
}
//Close the connection
DBClose($conn);
return json_encode($personData );
}

"Internal server error" means the server crashed somewhere but for security reasons the client only get that 500 error. Check the server's error log file, there should be the real origin of the error (some real error, file and line number). You should start there.

Does the PHP script that uses AJAX have permissions to read the other PHP Script?

Related

ajax GET failing when JSON content over 1MB on GoDaddy host

I have a very simple ajax GET request in jquery that works just fine on my local test server. If I move the web page to a hosted server (GoDaddy) along with the php service it fails with a textStatus = "error" and errorThrown = "". Chrome displays
net::ERR_EMPTY_RESPONSE.
This all happens within 1 second so it's not a timeout issue.
If I truncate the number of records so the json returned is less than 1MB it works fine.
If I call the server code from GoDaddy webpage to my local server for all records (1.8MB) all is fine too. The good returns from either site will complete in less than a second.
What could be causing GoDaddy to basically return no data when the json echo has more than 1MB of data in it?
The php server routine:
if (isset($_REQUEST['_SESSION'])) die("Get lost Dweeb!");
error_reporting(E_ALL | E_STRICT);
header('Access-Control-Allow-Origin: *');
$date_code = $_GET['date_code'];
$region = $_GET['region'];
$chargers = array();
$chg_count = 0;
$ftime = filemtime("chargers.json");
if ($ftime != $date_code) {
$aTeslaChargers = json_decode(file_get_contents("chargers.json"),true);
foreach($aTeslaChargers as $aTeslaCharger) {
if ($aTeslaCharger['region'] == $region) {
$chargers[] = $aTeslaCharger;
$chg_count++;
//if ($chg_count > 1972) break;
}
}
}
$json = json_encode(array(array("date_code" => $ftime), $chargers));
echo $json;
The javascript routine:
var url = 'https://www.website.com/get_data.php?date_code=0&region=north_america';
var jqxhr = $.ajax({
url: url,
type: "GET",
crossDomain: true
})
.done(function(response) {
console.log(new Date());
//var data = $.parseJSON(response);
//console.log(data);
console.log(response.length);
})
.fail(function(jqXHR, textStatus, errorThrown) {
console.log(new Date());
console.log(errorThrown);
});
Well I stumbled onto a solution. It was to add a header statement just before the echo which seems to allow the echo to be larger than 1MB.
header("Content-Type: application/json");
echo json_encode(array(array("date_code" => $ftime), $chargers));
I now need to understand this more and check it across various browsers. Also interesting that the data was returned as an object now so no need to do json decode on it.
I suspect there is something in the GoDaddy service that defaulted the length but I am not sure. Again my server did not behave this way.

how to manage errors server side (php) when Ajax is involved?

So, I have an ajax call that prevents default post submission, server side I do some validation and checking, if the data is correct I do some database operations (inserting item for user etc) but if the data is not correct I don't have to make anything but throw out an error (i.e. item already present). My case in the controller was something like this:
} else {
print('Item already present');
}
but now I have the ajax call that manages the error like this:
error: function( xhr, status, errorThrown ) {
alert( "Sorry, there was a problem!" );
console.log( "Error: " + errorThrown );
console.log( "Status: " + status );
console.dir( xhr );
},
So obviously the php doesn't print anything.
How should I modify my php to act well with the ajax call?
When you make an ajax call, you should be expecting a particular type of data back. A typical (example) scenario is to get back data in JSON. If you are using jQuery, then I typically to look for errors in a two places because I think of ajax errors coming in two types:
network error or anything that results in a website error (404 - page not found, 500 - potential coding error, etc). This is caught in the ajax 'error' handler function as you have it above. I believe you could intentionally trigger an error in your PHP code to get this case.
logical error. This is an error that you might be expecting to handle - such as a bad username/password during a login call via ajax. In this case, you don't really want to throw a PHP error. Instead you want to return an error, but perhaps also include some meta data bout the error such as 'username does not exist' or whatever.
So, on your php server, you would have a view that needs to set the header to be a JSON response, and then output the JSON error, e.g.:
<?php
// output a json version of any list of objects that has the
// "toArray()" method defined.
// ...for ajax calls.
header( 'Content-type: application/json' );
$isError = 'false';
if (checkToSeeIfErrorOccurred())
{
$isError = 'true',
$errorMessage = getErrorMessages();
}
?>
<!-- define json result -->
{
error: "<?php echo $isError; ?>",
errorMessage: "<?php echo $errorMessage; ?>"
}
So, on your client side, in (for instance) your jquery ajax call, you would define a successHandler that needs to check for this error, and specify the dataType of the return value. Note that even though it is a successHandler, the 'success' part just means you had no network or programmatic/PHP error thrown. So, you still need to check for the logical error you might return in your JSON:
// your error handler
function myErrorHandler( xhr, status, errorThrown )
{
alert( "Sorry, there was a problem!" );
console.log( "Error: " + errorThrown );
console.log( "Status: " + status );
console.dir( xhr );
};
function mySuccessHandler( response )
{
// response is returned as an object
if (response.error === 'true')
{
// maybe call same error handler?
myErrorHandler( 'whoCares', 'logicalFailure', response.errorMessage );
}
else
{
// handle success
}
};
$.ajax(
url,
dataType: 'json',
error: myErrorHandler,
success: mySuccessHandler,
...
);
I don't know if this is typical for other folks and it is only an example but it has worked well for me...
One way you could think about this is use ajax to do your request and then return xml with a result from php echo statement. If the result is successful then your code does what it needs to do else as part of the php server return you have an xml error tag with why it went wrong and then process this in your ajax.
Another way you could return a result is with json.

Cannot get AJAX answer to GET

I'm trying to achieve the following:
when you click on H1, JQuery GETs info for certain key from the server and sends it back to user, where jquery is showing prompt with this info. PHP in server.php
$link = mysql_connect("mysql.hostinger.com.ua", "_my_login_", "_my_password_") or die("NOOO!");
mysql_select_db("u994953720_db");
$key;
if(isset($_GET['Key'])) {
$key = $_GET['Key'];
$selected = mysql_query("SELECT * FROM `Table` WHERE `Key`='".$key."'", $link);
$selected_row = mysql_fetch_array($selected);
if($selected_row!=null){
$response = array(
"result" => $selected_row['Value']
);
echo json_encode($response);
exit;
}else{
$response = array(
"result" => "Nope."
);
echo json_encode($response);
exit;
}
}
jQuery in the main page:
$('h1').on('click', function () {
$.ajax({
type: 'GET',
url: '/server/server.php',
data: {
'Key': 'Roman'
},
success: function(data) {
alert(data.result);
},
dataType: 'json'
});
});
But I don't have any effect. Could you guys show me how to fix my mistakes?
P.S.Working not working example
P.S.I am only starting learning PHP, so there can be some really stupid mistakes.
UPDATE: I've done everything like you guys said (I don't care about safety yet), but it still doesn't work. In the console there is the following message:
XHR finished loading: GET "http://site0.hol.es/server/server.php?Key=Roman".
When I include error method to ajax:
error: function(requestObject, error, errorThrown) {
alert("request objqect: " + requestObject + " . Error: " + error + " . Error thrown: " + errorThrown);
}
, there is an alert: parsing error, unexpected token <
UPDATE 1: I've understood, that my while page is being writed to json result, like here, but I don't have any other echo-s, how can it happen?
UPDATE: I've figured out, that PHP was sending the whole page what it was placed in, so, I simply removed that) But thank you for your comments about safety, I'll correct it
By looking at your site I can see that you are returning HTML + JSON. Try throwing an exit after your echo:
echo json_encode($response);
exit;
Also - you are not handling a no data state at all. You should be do something like:
if(isset($_GET['Key'])) {
// your valid request code
} else {
echo json_encode(array('result' => false, 'reason' => "You must send a Key"));
}
Furthermore you can debug you php code by hitting the endpoint directly and var_dumping/debugging the code that is run there. For starters, what is the output of $selected_row = mysql_fetch_array($selected); when you go to http://site0.hol.es/server/server.php?Key=Roman
Finally - just little warning, as others have mentioned. You are wide open to SQL injection attacks. Look into using PDO -
What PDO is:
http://php.net/manual/en/book.pdo.php
Why to use it:
http://code.tutsplus.com/tutorials/why-you-should-be-using-phps-pdo-for-database-access--net-12059
How to use it: http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers

Why the static message is not coming from ajax file if no data found in mysql database?

I have a very strange problem and couldn't figure it out. I am working with AJAX/PHP and fetching the data from mysql database on user interaction by ajax call. Everything is working very fine and no problem at all. But only one issue which is persisting is when the data is not found in mysql database, then a user-friendly message is not returned from the server ajax file - the one part works and other doesn't. Here is my code -
This is my first file where the form reside (full code is not there; only js code) -
<script type="text/javascript">
$(document).ready(function(){
$("#selcustomer").change(function(){
var customers_id = $(this).val();
if(customers_id > 0)
{
$.ajax({
beforeSend: startRequest,
url: "ajax/ajax.php",
cache: false,
data: "customers_id="+customers_id,
type: "POST",
dataType: "json",
success: function(data){
if(data != "No result found.")
{
$("#img_preloader").hide();
$("#error").html('');
// $("#txtfname").val(data.fname);
// $("#txtlname").val(data.lname);
for(var key in data)
{
document.getElementById("txt"+key).value = data[key];
}
}
else
{
$("#img_preloader").hide();
$("#error").html(data);
$("input").each(function(){
$(this).val('');
});
}
}
});
}
else
{
$("#error").html('');
$("input").each(function(){
$(this).val('');
});
}
});
});
function startRequest()
{
$("#img_preloader").show();
}
</script>
And this is my server-side ajax file (php file) which interacts with database -
<?php
include("../includes/db-config.php");
if(isset($_POST["customers_id"]))
{
$customers_id = $_POST["customers_id"];
$query = "SELECT * FROM `tb_customers` WHERE `customers_id` = '$customers_id'";
$rs = mysql_query($query);
if(mysql_num_rows($rs) > 0)
{
$row = mysql_fetch_array($rs);
$customers_first_name = $row['customers_first_name'];
$customers_last_name = $row['customers_last_name'];
$customers_email_id = $row['customers_email_id'];
$customers_phone_no = $row['customers_phone_no'];
$customers_address_line_1 = $row['customers_address_line_1'];
$customers_address_line_2 = $row['customers_address_line_2'];
$customers_country = $row['customers_country'];
$data = array('fname' => $customers_first_name, 'lname' => $customers_last_name, 'emailid' => $customers_email_id, 'phoneno' => $customers_phone_no, 'addressline1' => $customers_address_line_1, 'addressline2' => $customers_address_line_2, 'country' => $customers_country);
echo json_encode($data);
}
else
{
echo "No result found.";
}
}
?>
The if part is working fine but when no data is found in database the else part is not sending the data back to jQuery code. I checked in browser console and saw the else part is returning the response but the jquery code in success: part of $.ajax is not running - neither within if, nor in else and also not outside of if/else. I mean to say that a simple alert is not fired with data under success when no data is found in mysql database. But when i remove all the data in ajax/php file and say simply write 123 then alert comes with 123 but not when the actual code is there. Can you plz tell me what is the issue behind this strange problem?
Your datatype is set to JSON in your AJAX call, so the return value must be a valid JSON.
When you are encountering the else condition, you are returning something that is not JSON.
Try this -
else
{
echo json_encode("No result found.");
}
Or something more flexible-
else{
echo json_encode(Array("err"=>"No result found."));
}
EDIT-
...But when i remove all the data in ajax/php file and say simply write
123 then alert comes with 123...
That is because a 123 (number) is valid JSON. Instead of 123, try writing No result and an error would be thrown, because No result (a string) needs quotes(which is taken care when you use json_encode).

Ajax success if statement and echo mySQL query result

I have an Ajax script that makes a call to a php file on my server every twenty seconds.
The server then runs a simple mysql query to return the contents of a particular field.
If that field is blank I want the php file to echo the word "pending", which when caught by the success handler will recall the initial function. However if that field is not blank, it will contain a URL to which I want to redirect the user to. That field will update any where between 5 seconds and 5 minutes from the start of the first call and that time cannot be changed.
I think the main issue may be with my php file, in that I dont think it is echoing the data in a way that the success handler recognises. However I have detailed both parts of my code as whilst the success handler seems to be constructed correctly I am not 100% sure.
Very new to this, so apologies if I have not explained myself correctly but if anyone could assist that would be great:
UPDATE - for clarity what I am looking to achieve is as follows:
Ajax call to my php file.
PHP file queries database
If field queried contains no data echo the word "pending" to the ajax success handler (IF) which in turn recalls the original function / ajax call.
If field queried contains data (will be a URL) echo this result to the ajax success handler (ELSE)in a format that will redirect the user via window.location.assign(data).
FURTHER UPDATE
I managed to solve this question with using a combination of the advice from #mamdouhalramadan and #martijn
I also have changed setInterval to setTimeout as the poll function was causing responses to stack up should the server be running slowly and as such cause errors. I also added in cache: false and a further option in the success handler to take into account slightly different behaviour in IE:
AJAX
function poll() {
$.ajax({
url: 'processthree.php?lead_id='+lead_id,
type: "GET",
cache: false,
async: false,
success: function(data3) {
//alert("pending called " + data3)
if(data3.indexOf("pending") >-1 ){
setTimeout(poll, 20000);
}
else if ( (navigator.userAgent.indexOf('MSIE') != -1) ) {
//alert("Submit success - MSIE: " + data3);
parent.window.location.replace(data3);
}
else{
//alert("process three called " + data3)
window.top.location.assign(data3);
}
},
error: function(xhr, error){
//alert("Error");
//alert("Error: " + error + ", XHR status: " + xhr.status);
},
});
}
setTimeout(poll, 20000);
PHP
$query = ("SELECT column FROM table WHERE id = '$lead_id'") or die(mysql_error());
$result = mysql_query($query);
$return = array();
while($row = mysql_fetch_assoc($result))
{
$return = 'pending';
if($row['column'] != '')
{
$return = $row['column'];
}
}
echo $return;
I believe using json might help you out here, not to mention it is safer, like so:
function poll() {
$.ajax({
url: 'processthree.php?lead_id='+lead_id,
type: "GET",
dataType: 'json',//specify data type
success: function(data3) {
if(data3.res.indexOf("pending") >-1 ){
//rest of the code.....
then in your php:
$return = array();
while($row = mysql_fetch_assoc($result))
{
$return['res'] = 'pending';
if($row['column'] != '')
{
$return['res'] = $row['column'];
}
}
echo json_encode($return);
Note: use PDO or MYSQLI instead of mysql as it is deprecated.

Categories