Skip to content

Generating_pages_and_ajax_responses_in_pma4

Michal Čihař edited this page May 16, 2016 · 6 revisions

phpMyAdmin 4.0 comes with a new framework for generating both pages and ajax responses.

The basics

Every server response in pma 4.0 is fully buffered, e.g.: no data is sent to the client until the very end when everything is ready. Every response is processed automatically after the calling script has shutdown.

Hello world

The new way (recommended):

<?php include 'libraries/common.inc.php'; $response = PMA_Response::getInstance(); $response->addHTML("Hello world"); ?>

The old way. This is deprecated and should not be used with any new code:

<?php include 'libraries/common.inc.php'; echo "Hello world"; ?>

After calling either of the above scripts (and having been successfully authenticated), you can expect to receive a full page in your browser, including a header and a footer and the words "Hello world" as the content.

hello_world.png

If the request parameters contain an "ajax_request" with a value that evaluates to true, you will receive a JSON encoded response. For the above example it would be:

{"message":"Hello world","success":true}

N.B.: Since the addHTML() method is preferred to echo() for generating content, it has higher precedence. Therefore when both are used together, the latter will be ignored.

$response->addHTML("Hello"); // Will be printed echo "Goodbye"; // Will be discarded

Scripts

Scripts can be added both to the header and the footer of the page. In order to add a script to the page, it is necessary to first retreive the PMA_Header or the PMA_Footer object from the response. Then the PMA_Scripts object must be retrieved from one these objects. After that, you can add files, inline code and events directly to the PMA_Scripts object.

<?php include 'libraries/common.inc.php'; $response = PMA_Response::getInstance(); $header = $response->getHeader(); $header_scripts = $header->getScripts(); $header_scripts->addFile('hello.js'); // includes '/js/hello.js' into the header $footer = $response->getFooter(); $footer_scripts = $footer->getScripts(); $footer_scripts->addCode('console.log("Hello world")'); // adds inline code to the footer $response->addHTML("Hello world"); ?>

Generating AJAX responses

As shown above, the PMA_Response class will automatically generate a JSON encoded response for ajax requests. However, for most purposes this is not sufficient. Now we will look into generating more complex ajax responses.

Detecting AJAX request

At the time of writing of this page, there are two valid ways of checking for whether an ajax request is being serviced.

Using the PMA_Response class:

$response = PMA_Response::getInstance(); if ($response->isAjax()) { // do something }

The old way (Deprecated, not to be used with any new code):

if ($GLOBALS['is_ajax_request']) { // do something }

Setting the status of the response

By default, ajax responses are always successful and this case, at least the following two keys are present in it:

{"message":"Hello world","success":true}

However, it is possible to change the status of a response from success to failure by calling the isSuccess() method of PMA_Response:

$response = PMA_Response::getInstance(); $response->isSuccess(false);

Please note that for such a response, not only the value of the success key is false, but also the other key is no longer "message", but instead it's "error".

{"error":"Goodbye cruel world","success":false}

Adding data to the response

It is possible to add a single key value pair to the response or an entire array.

$response = PMA_Response::getInstance(); $response->addJSON("message", "Hello world"); $response->addJSON("data", 1);

Here you can expect something like this as a response:

{"message":"Hello world","data":1,"success":true}

Adding an array:

$response = PMA_Response::getInstance(); $response->addJSON( array( "message" => "Hello world", "foo" => 1, "bar" => 2 ) );

Expected response:

{"message":"Hello world","foo":1,"bar":2,"success":true}

Pitfalls

Overwriting response keys

As you may have noticed by now, there are several ways to add data to the "message" key in the response:

$response->addJSON("message", "baz"); // Will be used $response->addHTML("bar"); // Will be discarded echo "foo"; // Will be discarded

In the above case, the response will contain "baz", as the addJSON() function has the highest priority, followed by addHTML() and, if neither of these has been called, the contents of the buffer (which may even be an empty string) will be used.

Setting the "error" key

The "error" key should never be set, because in the case of a failure it will be overwritten by the value of the "message" key. For example:

$response->addJSON("message", "Success"); $response->isSuccess(false); $response->addJSON("error", "Failure");

Intuitively, "Failure" is expected as the value for the error, however "Success" will be send.

{"error":"Success","success":false}

Bypassing the framework

In some cases it may not be desirable for the PMA_Response class to handle the requests on a page. There are a few ways to accomplish this.

First, it's possible to explicitly disable any extras that would normally be attached to the response. This may be useful for generating standalone pages where the content of the header and footer need to be completely different from that provided by the PMA_Header and PMA_Footer classes. Calling the disable() method on an instance of the PMA_Response class will deactivate the header and the footer of the page. In the below example, calling the page will result in the display only of the words "Hello world".

<?php include 'libraries/common.inc.php'; $response = PMA_Response::getInstance(); $response->disable(); $response->addHTML("Hello world"); ?>

N.B.: In this example, the postprocessing of the response is not disabled, but only the header and the footer of the page. So, calling that page with the ajax_request parameter set to true will still return a JSON response, same as in the very first example above.

Another way to disable the framework is to set a 'PMA_MINIMUM_COMMON' constant before including the 'common.inc.php' script. In such a case, the PMA_response class will not be loaded at all. This is useful when generating non-HTML content. For example this mode is currently used for generating the CSS stylesheets.

<?php define('PMA_MINIMUM_COMMON', true); include 'libraries/common.inc.php'; echo "Hello world"; ?>

N.B.: In this example, the PMA_Response class in not available, so the page will always print "Hello world" in plain text regardless of whther it's an ajax request or not.

Header API

The header object has a few extra functionalities that can be used to customise the page. In order to have access to its API, first it is necessary to retrieve the header object from the response:

$header = PMA_Response::getInstance()->getHeader();

// Sets the title of the page to "New title" // If no call is ever made to setTitle(), the title will be // automatically set to something sensible depending on the // context in which the page was called $header->setTitle("New title");

// Sets the value for the ID attribute of the body tag // Only applicable when not servicing an ajax request $header->setBodyId("loginform");

// Disables the breadcrumbs and the top menu in the page $header->disableMenu();

// Puts the page in "Print view" mode. E.g: // disables menu, sets an appropriate title, // includes the print.css stylesheet $header->enablePrintView();

// See above section on scripts $header->getScripts();

Footer API

Like for the header, first we fetch the footer object:

$footer = PMA_Response::getInstance()->getFooter();

// Disables the scripts, links and error messages in the footer // Basically, when the footer is in minimal mode it will only contain // the closing tags for body and html ("

Clone this wiki locally