5

There are a bunch of questions on Stack Overflow about whether AJAX should return JSON or HTML, and most seem to agree that it is ideal to return JSON for the sake of speed. However, that means that if I degrade gracefully, I will have some duplicate code because I am generating the same markup in both PHP and Javascript.

A hypothetical example: A website has a list of links to short stories. If the user has Javascript, then clicking on one of these links loads the story without a page refresh. This is done with an AJAX request that returned a JSON with the story information. Javascript generates the markup for the story. If the user does not have Javascript, then clicking on the same link reloads the page with the story now loaded. PHP generates the markup for the story.

Is there a solution to use JSON and degrade gracefully without duplicating the code?

2 Answers 2

6

Sure.

You are using json_encode right? So start with the same data structure. For simplicity here I will use an array.

$stories = array( '[id]' => [details] );

Now you have a quick break. If the request is an AJAX request, then simply echo json_encode($stories);. Otherwise standard requests will process the view with that same data structure.

I'm going to expand on this a bit. Assuming you aren't using some MVC paradigm and doing "straight" PHP work.

For generating the page you are going to want to encapsulate the logic for this table in a separate PHP file called with an include(). Let's call this file storyList.php and it's in the same web-accessible folder as everything else.

// File: storyList.php
// First connect to the database and pull the story list
// based on any parameters passed.
$story = new StoryList($_REQUEST);
$list = $story->fetch_list();

// Now do a quick conditional based on the headers.
// See http://php.net/manual/en/function.get-headers.php and
// define your own function for testing if a request is made
// with AJAX or not. Several libraries include their own.
if (is_xhr())
{
    echo json_encode($list);
}
else
{
    foreach ($list as $title => $story)
    {
        // Format as a table
    }
}
2
  • Thank you for answering, but I'm confused. Isn't this still duplicate code? If for example I change it from a table to an ordered list, won't I have to make this change in both my Javascript and my PHP?
    – juicy lucy
    Commented May 16, 2011 at 21:21
  • @juicy: Yes, this is why I typically prefer to load html instead of JSON.
    – Josh K
    Commented May 17, 2011 at 0:59
2

In a recent Google IO presentation this subject was discussed in some detail.

To solve this problem they used Mustache for templating. Using the Mustache.js implementation on the client side and the sharing same templates on the server side - in your case perhaps Mustache.php - the duplication can be removed.

2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.