3
\$\begingroup\$

Let's say I have three files: a page that is used for searching data called search, a file that handles requests called controller, and a file that has functions which the controller calls based on what POST parameter is passed. From the search page, I post some data and specify my action (search) via AJAX to the controller. The controller then takes that and calls a function that returns the data (which is inserted into the appropriate place in the DOM) which looks something like this:

<?php
function fetchStudentData($search, $roster) {

    //If a user is not logged in or the query is empty, don't do anything
    if(!isLoggedIn() || empty($search)) {
        return;
    }
    global $db;

    //Placement roster search
    if($roster == "placement") {
        $query = $db->prepare("SELECT t1.id,
                t2.placement_date,
                t2.placement_room,
                t1.student_id,
                t1.student_type,
                t1.last_name,
                t1.first_name,
                t1.satr,
                t1.ptma,
                t1.ptwr,
                t1.ptre,
                t1.ptlg,
                t1.waiver,
                t2.tests_needed,
                t2.blackboard_id
                FROM student_data AS t1
                JOIN additional_data AS t2
                ON t1.id = t2.student_data_id
                WHERE t2.placement_date = :search
                ORDER BY t1.last_name ASC");
        $query->bindParam(":search", $search);
        $query->execute();

        if($query->rowCount() == 0) {
            return;
        }

        echo "<div id='searchHeader'>
            <div class='searchSubHead'><em>Placement Roster For $search</em></div>
            <br />
            <span>Placement Room</span>
            <span>Student ID</span>
            <span>Student Type</span>
            <span>Last Name</span>
            <span>First Name</span>
            <span>SATR</span>
            <span>PTMA</span>
            <span>PTWR</span>
            <span>PTRE</span>
            <span>PTLG</span>
            <span>Waiver</span>
            <span>Tests Needed</span>
            <span>Blackboard ID</span>
        </div>";
        while($row = $query->fetch()) {
            echo "<div id='{$row['id']}' class='placementRosterRecord'>
                <span>{$row['placement_room']}</span>
                <span>{$row['student_id']}</span>
                <span>{$row['student_type']}</span>
                <span>{$row['last_name']}</span>
                <span>{$row['first_name']}</span>
                <span>{$row['satr']}</span>
                <span>{$row['ptma']}</span>
                <span>{$row['ptwr']}</span>
                <span>{$row['ptre']}</span>
                <span>{$row['ptlg']}</span>
                <span>{$row['waiver']}</span>
                <span>{$row['tests_needed']}</span>
                <span>{$row['blackboard_id']}</span>
            </div>";
        }
    }
}
?>

This is obviously working very well for me but I wanted to know if there's a better way I should be doing this? Should I be returning the raw data from the database and encoded as JSON and then have my JavaScript take care of creating elements/structure? I see that a lot with various API's but this is something internal to my company and not something that other developers will be using. Is there anything wrong with my approach?

\$\endgroup\$

2 Answers 2

5
\$\begingroup\$

First of all, you should read about MVC.

There are a lot of tutorials out there, as well as frameworks (like CodeIgniter) that implement it. Basically your code should be divided into 3 main categories:

  • Controllers - where all logic should be placed like validations, checks. This is also where Views and Models are used, hence "controller"

  • Models - basically the source of data. Usually this is the abstraction of the data storage (databases, sessions, external requests) in the form of functions.

  • Views - the presentation, or in this case, the HTML.

Reasons to use MVC or MV* patterns is

  • Portability.

    The files, especially the views and models, can be plucked out of the architecture, and be used elsewhere in the system without modification.

    Models are simply function declarations one can just plug in the controller and call their functions. Views are simply layouts that, when plugged with the right values, display your data. They can be used and reused with little or no modification unlike with mixed code.

  • Purpose-written code and Readability

    You would not want your HTML mixed with the logic, nor the data gathering mechanism. This goes for all other parts of your code. For example, when you edit your layout, all you want to see on your screen is your layout code, and nothing more.

Never, and I mean NEVER return marked-up data using AJAX (use JSON).

The main reason AJAX is used is because it's asynchronous. This means no page-loading, no more request-wait-respond, and you could do stuff in parallel. It's pseudo-multitasking for the human.

On the same train of thought, the reason why JSON was created was because XML was too heavy for data transfer and we needed a lightweight, data transport format. XML is NOT a data-transport format but a document and mark-up language (Though by "X" for extensibility, it has served a lot of purposes beyond document).

Use client-side templating

JavaScript engines have become fast these days that even developers create parsers/compilers on JavaScript. And with that comes client-side templating, like Mustache.

Coupled with raw data from JSON, which is very light, you can integrate that data into a template to form your view and have JavaScript display it, like you already do.

Have a rendered version and a data version

Taking into account the previous answer, if you are making a website rather than a web app, where JS is optional rather than required, one should create a website that works without JS.

However, for the same data but different format, the URL should not change (much). You should then take into account in the request what data type is requested by the client. And so you must accept a parameter which indicates the data type.

An example url would look like this:

//for a website page format (default: HTML):
http://example.com/my/shop/available/items.php

//for the JSON version
http://example.com/my/shop/available/items.php?format=JSON

//for the XML version
http://example.com/my/shop/available/items.php?format=XML

This means, that for the same page (available items), you have 3 formats you can use. This can be seen in the Joomla Framework (the framework that powers the Joomla CMS)

With these 3 tips, your code will be cleanly separated and purposely written (MVC), fast on transport and rendering (JSON + client-side templating) and extensible (multi-format support).

\$\endgroup\$
1
  • \$\begingroup\$ "Never, and I mean NEVER return marked-up data using AJAX" I disagree. While a lot of data calls you're going to want to use JSON, many common libraries use AJAX for retrieving templates as well, which are simple HTML files. It depends on your use-case. I would argue that saying "never do this" is harmful.. even if the harm was done nearly 3 years ago :) \$\endgroup\$
    – Dan
    Commented Sep 29, 2015 at 7:55
3
\$\begingroup\$

Your approach, which is to load a partial view (html) via ajax, is just fine. Yes, you could load something else such as json, xml, etc. The problem you'd face is that you would require additional client side (js) code to deal with the data. Some feel that the lighter payload of json offers faster loading over html. I argue that your users would likely never really notice an improvement.

I would offer these suggestions:

  1. Design the initial app with 0% javascript in the beginning! Things can change a lot while developing an app. You'll appreciate not having to change both your php and js early on.
  2. Separate your data access and presentation layers.
  3. Use a templates system which allows you to render a full html layout (everything inside <html></html> including the page specific content) or partial html (the content in <div></div>).
  4. Once you decide to spruce things up with some js and ajax, have your controllers load the partial view if it's an ajax request, or full layout if it's a regular request.
\$\endgroup\$

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.