"

Programming on the Server Side

39 Fetching Structured Data

Decoration Connections

You have met JSON before. If you need a JSON refresher, see the Client-side Storage chapter.

In the examples in the previous chapter, PHP scripts were responding to Ajax requests with plain text. But most apps need to retrieve structured data from the server (e.g. an array of strings containing suggestions for a Google search, or an array of objects representing items in a social media feed). But HTTP can only transmit strings, so to accomplish this, we need a way of translating data structures into strings and back again. When the term AJAX was coined, everyone was using XML to encode data structures, but these days most people use JSON (see the Client-side Storage chapter for more on JSON).

Receiving JSON Data

If you know you are going to receive JSON data, you can change the text method call in the fetch statement to a json method call, like this:

fetch(url, { credentials: 'include' })
    .then(response => response.json())
    .then(success)

The response.json() method will call JSON.parse() on the text from the body of the HTTP Response, and then your success function will receive a JavaScript data structure instead of the original text string from the HTTP Response. So you’d better be sure that you’re sending a JSON-encoded string from your PHP program, otherwise you will see errors in the JavaScript console.

Sending JSON Data

To send JSON data from a PHP program, you can use PHP’s json_encode global function on an array or associative array. It will look something like this:

<?php
header('Content-Type: application/json');
// ... create a $data object
echo json_encode($data);

Although it is not strictly necessary, it’s best practice to use the PHP header function as shown above to set the Content-Type field of the HTTP Response to application/json.

image Do it Yourself

Get the ajax_json folder from the Full Stack Example Pack and load it into a browser through a local server. This app allows the user to launch a request for a list of random integers. This list is created by the server/randomlist.php program, which copies it into the HTML response as a JSON-encoded array. The client side code receives the array and computes and displays the average value.

To convince yourself that numbers are really coming from random.php, try this:

  • On Chrome, open the Developer Tools and go to the Network tab. Reload the page, fill in some numbers, then press the button. You will see the AJAX HTTP Request appear. You can find the parameters in the Payload tab and the decoded array that was transmitted in the Preview tab.
  • Examine the contents of server/randomlist.php to verify that it receives parameters, creates an array, and then encodes and echoes it.
  • Examine the contents of js/getrandom.js to note that the success function receives an array (the result of a behind-the-scenes call to JSON.parse) rather than text. It loops over the array to sum it up and compute and display the average.

Fetching from a Database

To fetch data from a database, launch a fetch request with GET parameters to a PHP program. The program should connect, execute a SELECT query, and then build an array of the rows received. Each row could be an associative array. Then the final step is to JSON encode the two-dimensional structure and echo it into the HTTP Response.

Here’s an example that gets users’ first and last names and returns them as a JSON-encoded array. First, after connecting to the database, the code launches an SQL SELECT query as usual:

$command = "SELECT fname, lname FROM grades";
$stmt = $dbh->prepare($command);
$success = $stmt->execute();

Then it creates an array to hold the rows, and used array_push to fill it with associative arrays containing user names, one for each row:

$userlist = [];
while ($row = $stmt->fetch()) {
$user = [ “first” => $row[“fname”], “last” => $row[“lname”] ];
array_push($userlist, $user);
}

Finally, it echo’s a JSON encoded version of the array…

echo json_encode($userlist);

On the client side, the success function will receive an array of objects, a bit like this:

[
    {first: "Sam", last: "Scott"}, 
    {first: "Anne", last: "St-Amand"} 
]

image Do it Yourself

To see code similar to the above in action, get the ajax_json2 folder from the Full Stack Example Pack and load it into a browser through a local server. If you don’t already have it, you will need to get and import the data/grades.sql file as well. Then you will need to modify connect.php to make it match your database name, userid, and password.

The ajax_json2 app uses AJAX to retrieve the full list of user names and IDs from the grades database table via the server/userlist.php program. Press the button to make that happen.

To convince yourself that data is really coming from userlist.php, try this:

  • On Chrome, open the Developer Tools and go to the Network tab. Reload the page, then press the button. You will see the AJAX HTTP Request appear, and you can see the. You can find the parameters in the Payload tab and the decoded array that was transmitted in the Preview tab.
  • Examine the contents of server/userlist.php to verify that it receives parameters, creates an array, and then encodes and echoes it.
  • Examine the contents of js/getjson.js to note that the success function receives an array of objects (associative arrays) rather than text. It loops over the array to display each object.

Optional: You can also return an array of objects from the PHP program. Objects and associative arrays encode to exactly the same format in JSON (because JavaScript makes no distinction between objects and associative arrays). So this change only needs to be made on the server side. The userlist2.php and user.php files in ajax_json2 implement the alternative solution. If you decide to do this in your own code, study user.php carefully, because there are some hoops you have to jump through when you create the class in order to make this solution work.

What to do While the User Waits

Because networks can be slow, AJAX requests can sometimes take a few seconds to complete. If things don’t happen instantly, it can cause the user to start pressing buttons over and over again, or behaving in other destructive ways which could end up launching more and more AJAX requests. This is a problem you have to think about whenever you use AJAX.

The solution is to think in terms of the User Interface Design Principles of feedback and contraints, as discussed in the More User Interface Design Principles chapters. First, make sure you give the user enough feedback to understand that they have to wait. You could do this by displaying an animated “loading” or “updating” icon as shown below.

image

Alternatively, many web sites will show the user a generic wireframe of what is being loaded, which gets “filled in” once the content is fetched. Below is an example of what Bluesky Social Media App looks like as the user waits for their feed to load.Bluesky's wireframes while you wait.

Even when you’ve given the user enough feedback to let them know what’s going on, it  may still be a good idea to constrain them. You can do this by disabling buttons and links through JavaScript, re-enabling them in the success function once the AJAX request is complete.

image Do it Yourself

To see code similar to the above in action, get the ajax_json folder from the Full Stack Example Pack and load it into a browser through a local server and make sure it works (we’ve seen this program in a previous DIY box).

Then somewhere in the server/randomlist.php program add the following line:

sleep(5);

This will cause the script to pause for 5 seconds before continuing, simulating a slow internet connection.

Now try pressing the button to load and note how long it takes.

Launch three requests quickly, changing the number of integers each time, and observe what happens as the AJAX requests complete.

image Coding Practice

  1. Create a fortune cookie server. The fortune cookie server is a PHP program that echoes a JSON-encoded array containing a random fortune (you can hard code a few possible fortunes) and five lucky numbers (chosen randomly). Then create a JavaScript program on a web page that sends an AJAX request to retrieve the fortune and the lucky numbers, then displays them on the page. If the user doesn’t like their fortune, they can click a button to get a new one. This button should launch another AJAX request to replace the old fortune and lucky numbers with a new one.
  2. Create a joke server. The joke server is a PHP program that contains an array of jokes, where each joke is also an array containing a question and an answer, like this:
$a = [
    ["Why did the chicken cross the road?", "To get to the other side"],
    ["Where did Napoleon keep his armies?", "In his sleevies"],
    …
];

The joke server should return a JSON encoding of a randomly selected joke from the array.

Then write a JavaScript program on a web page with a button that says “Get Question”. When they press the button, get a new joke with an AJAX request to the joke server. When the joke is received, you should show the question and change the button text to “Get Answer”. When they press the button again, show the answer. Then change the button back to “Get Question”.

  1. Redo Exercise 3 from the previous chapter so that the PHP program returns an array of results for the three guesses. Each result should be “correct”, “close” (if they’re within 5), or “wrong”. Then color the input fields green, orange, or red as appropriate to indicate the results to the user.
  2. This exercise uses the data/world.sql database tables from the Full Stack Example Pack. Make sure you import that file into your local database if you don’t already have it. Then modify the PHP program you wrote in the PDO for SELECT chapter to display all the cities in a range of populations. The new version should just output a JSON-encoded array of cities. Test it in a browser. Then write a new HTML page with a form to enter min and max. When the user submits the form, it should launch an AJAX request to fetch the array of cities, then display the list on the same page, below the form, nicely formatted.
  3. Add some delay, feedback, and constraints to the ajax_json app from the Full Stack Example Pack. First add a sleep(5); delay to the randomlist.php file (as in the last Do it Yourself box above). Then try the following, by adding code to getrandom.js:
    1. Constrain the user by disabling the “Get Them” button until the most recent AJAX request has completed. Make sure that it works and prevents any further AJAX requests until you are ready for them.
    2. Feedback: Instead of disabling the button, set a global Boolean variable when the button is pressed. If the user hits the button again before the AJAX request is completed give them an error message somewhere on the screen and do not load the request. Make sure that it works and prevents any further AJAX requests until you are ready for them.
    3. Feedback: Add to either a or b above to include a display of some kind of “loading” icon or a small wireframe indicating that results are coming. Make sure to remove it once the AJAX request is complete
  4. Go back to Exercise 1 to add feedback and constraints while the AJAX request is completing: disable the button and show a loading message while the user is waiting for the AJAX request to complete.

License

Icon for the Creative Commons Attribution-NonCommercial 4.0 International License

Full Stack Web Development for Beginners Copyright © 2025 by Sam Scott is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License, except where otherwise noted.