Home arrow AJAX & Prototype arrow Google's Closure Compiler Service API: Talking to the API via a PHP Class

Google's Closure Compiler Service API: Talking to the API via a PHP Class

In this second part of the series, I develop a concrete PHP class derived from the abstract parent defined in the previous tutorial. This new class implements some refined methods that permit you to interact “face-to-face” with Google's Closure Compiler Service API in a pretty straightforward fashion.

TABLE OF CONTENTS:
  1. Google's Closure Compiler Service API: Talking to the API via a PHP Class
  2. Interacting with the Closure Compiler API using PHP
By: Alejandro Gervasio
Rating: starstarstarstarstar / 1
September 29, 2010

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

If the ever-increasing size of your custom JavaScript files has you desperately looking for an application that lets you optimize them through a few simple options, then you should take a close look at Google's Closure Compiler Service API. This web service released recently by the search company (at least at the time of this writing) will permit you to perform the entire optimization process either manually by using a graphical user interface, or programmatically via POST HTTP requests.

If you've read the introductory tutorial of this series, you're familiar in general terms with the capabilities that the Closure Compiler API offers. In that part I gave a brief overview of the API’s main features, including the ability to specify the level of optimization that will be applied to the target files, and the format (text, XML or JSON) in which the files will be dispatched to the client.

It’s valid to recall that the main objective of this series is to demonstrate, in a step-by-step manner, how to interact with the Closure Compiler Service API using PHP. This process can be ported to other programming languages with minor efforts. In keeping with that premise, in the previous article I went through the development of an abstract PHP class, which encapsulated most of the functionality required to perform HTTP requests to a given host and a TCP port via a set of simple methods.

With that abstract parent already defined, the next step is to create a concrete subclass that is capable of talking directly to the Closure Compiler Service API. This subclass will allow us to automatically optimize multiple JavaScript files easily, without the need to explicitly use the compiler’s GUI.

With that said, it’s time to start building the aforementioned concrete PHP class. Want to see how this will be done? Just keep reading. 

Creating the backend to interact with the Closure Compiler Service API: creating an abstract HTTP request handler class in PHP

As I just explained, my goal here is simply to show how to consume Google’s Closure Compiler Service API using an object-oriented backend composed of a few sample PHP classes. To accomplish this, I first developed an abstract class, which was nothing but an enhanced wrapper of the “fsockopen()” PHP function. The full source code of the class looked like this:   

(HttpRequestHandlerAbstract.php)

<?php

abstract class HttpRequestHandlerAbstract
{
    protected $_data = array();
    protected $_url;
    protected $_port;
    protected $_method;
    protected $_headers = array();
    protected $_responseHeader;
    protected $_responseContent;
   
    // constructor
    public function __construct(array $data, array $settings = array())
    {
        $this->setData($data);
        if (array_key_exists('url', $settings)) {
            $this->setUrl($settings['url']);
        }  
        if (array_key_exists('port', $settings)) {
            $this->setPort($settings['port']);
        }
        if (array_key_exists('method', $settings)) {
            $this->setMethod($settings['method']);
        }
    }
   
    // set the data that will be passed with the request
    public function setData(array $data)
    {
        if (empty($data)) {
            throw new HttpRequestHandlerException('The request arguments are not valid.');
        }
        $this->_data = $data;
        return $this;
    }
     
    // get the specified request data
    public function getData()
    {
        return $this->_data;
    }
   
    // set the URL the request will be made to (implemented by subclasses)
    abstract public function setUrl($url);
     
    // get the given URL
    public function getUrl()
    {
        return $this->_url;
    }
   
    // set the TCP port the request will be made on (implemented by subclasses)
    abstract public function setPort($port);
     
    // get the given port
    public function getPort()
    {
        return $this->_port;
    }
   
    // set the request method (GET or POST)
    public function setMethod($method = 'GET')
    {
        $method = strtoupper($method);
        if (!in_array($method, array('GET', 'POST'), TRUE)) {
            throw new HttpRequestHandlerException('The request method is not valid.');
        }
        $this->_method = $method;
        return $this;
    }
   
    // get the request method
    public function getMethod()
    {
        return $this->_method;
    }
       
    // add a new request header
    public function addHeader($key, $header)
    {
        $key = strtolower($key);
        if (!array_key_exists($key, $this->_headers)) {
            $this->_headers[$key] = $header;
        }
        return $this;
    }
   
    // remove a specified request header
    public function removeHeader($key)
    {
        $key = strtolower($key);
        if (array_key_exists($key, $this->_headers)) {
            unset($this->_headers[$key]);
        }
        return $this;
    }
     
    // get a specified request header
    public function getHeader($key)
    {
        $key = strtolower($key);
        if (array_key_exists($key, $this->_headers)) {
            return $this->_headers[$key];
        }
    }
     
    // get the header included in the response
    public function getResponseHeader()
    {
        return $this->_responseHeader;
    }
   
    // get the content included in the response
    public function getReponseContent()
    {
        return $this->_responseContent;
    }
               
    // send an HTTP request to the specified URL and TCP port
    public function sendRequest()
    {
        // parse and urlencode the request data
        $data = '';
        foreach ($this->_data as $key => $value) {
            $data .= '&' . $key . '=' . urlencode($value);
        }
        $data = trim($data, '&');
        // parse the given URL
        $url = parse_url($this->_url);
        if (!isset($url['host']) OR !isset($url['path'])) {
            throw new HttpRequestHandlerException('No host or path was specified.');
        }
        $host = $url['host'];
        $path = $url['path'];
        // open a socket connection on the specified TCP port
        if (!$fp = fsockopen($host, $this->_port)) {
            throw new HttpRequestHandlerException('Error opening socket connection to the URL '. $this->_url . ' on port.' . $this->_port);
        }
        fputs($fp, "$this->_method $path HTTP/1.0rn");
        fputs($fp, "Host: $hostrn");
        fputs($fp, "Content-type: application/x-www-form-urlencodedrn");
        fputs($fp, "Content-length: ". strlen($data) . "rn");
        fputs($fp, "Connection: closernrn");
        fputs($fp, $data);
        // get the response of the request
        $response = '';
        while(!feof($fp)) {
            $response .= fgets($fp, 128);
        }
        // close the socket connection:
        fclose($fp);
        // process the response
        $response = explode("rnrn", $response, 2);
        $this->_responseHeader = $response[0];
        $this->_responseContent = $response[1];
        return $this->_responseContent;
    }
   
    // send the specified header
    public function sendHeader($key)
    {
        if ($header = $this->getHeader($key)) {
            header($header);
        }
    } 
}

 

(HttpRequestHandlerException.php)

<?php

class HttpRequestHandlerException extends Exception{}

If you haven't worked with sockets in PHP before, don’t worry; the previous class handles the process transparently behind the scenes through its “sendRequest()” method. Besides, the class implements some getters and mutator methods that allow you, among other things, to set the URL and TCP port on which HTTP requests will be made, which are pretty easy to grasp.

So far, so good. Having defined an abstract parent that triggers HTTP requests to a specific URL on a TCP port, we now need to start building the concrete class responsible for communicating directly with the Closure Compiler Service API. As you’ll see in a moment, the driving logic of this class will be very easy to understand, but to learn how it’ll be created you’ll have to click on the following link and keep reading. 



 
 
>>> More AJAX & Prototype Articles          >>> More By Alejandro Gervasio
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

AJAX & PROTOTYPE ARTICLES

- Best AJAX Tutorials for Forms
- The Best AJAX Tutorials
- 8 Great Ajax Tutorials
- Using Ajax and jQuery
- Using Ajax and jQuery with HTML Forms
- Ajax.org Offers Cloud9 IDE for JavaScript
- Java Technologies Provider ICEsoft Releases ...
- Using Recaptcha in AJAX Prototype Framework ...
- Google's Closure Compiler Service API: Addit...
- Installing Google Web Toolkit: Introducing t...
- Google's Closure Compiler Service API: Displ...
- Google's Closure Compiler Service API: Deliv...
- Google's Closure Compiler Service API: the A...
- Google's Closure Compiler Service API: the S...
- Google's Closure Compiler Service API: Optim...

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: