Home arrow AJAX & Prototype arrow Page 2 - Google's Closure Compiler Service API: Fundamentals

Adding a method to perform HTTP requests - AJAX

Looking for a fast way to optimize your JavaScript files, but don't want to give up total control? Google offers Closure Compiler, which makes use of an intuitive REST API and several other features to get you exactly the optimization you need for your JavaScript.

TABLE OF CONTENTS:
  1. Google's Closure Compiler Service API: Fundamentals
  2. Adding a method to perform HTTP requests
By: Alejandro Gervasio
Rating: starstarstarstarstar / 1
September 28, 2010

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

As I mentioned in the preceding section, it’s mandatory to provide the earlier “HttpRequestHandlerAbstract” class with the ability to send HTTP requests to the specified URL and port. To do this, below I defined an additional method, not surprisingly called “sendRequest(),” which performs this task in a fairly simple manner. Here’s how the method has been implemented: 

// 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;
}

Well, if you’re not familiar with the internals of the HTTP protocol, fear not; the above method simply sends an HTTP request to the given host and port via the “fsockopen()” PHP native function. Once the response is received from the queried host, the header and contents are stored separately in the $_responseHeader and $_responseContent class properties for further processing.

So far, so good. Assuming that you understand how the previous “sendRequest()” method does its business, the next logical step is to add it to the definition of the “HttpRequestHandlerAbstract” class, so you can see how the pertinent class looks after giving it the final touches.

This will be done in the following section, therefore jump forward and read the lines to come.

The finished version of the earlier “HttpRequestHandlerAbstract” class

Below I've listed the full source code corresponding to the previous “HttpRequestHandlerAbstract” class, after adding to it the “sendRequest()” method discussed previously. Here it is: 

(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);
        }
    } 
}

Mission accomplished, at least for the moment. At this point, I've created an abstract class that allows us to easily make HTTP requests to a specified host. This is pretty useful, since Google's Closure Compiler Service API can only be queried programmatically via POST requests.

Even though this first task may seem unnecessary, don’t feel disappointed; the abstract class just defined will make interacting with the Closure Compiler API a breeze, believe me. Keep in mind that this is a work in progress.

Final thoughts

In this first part of the series, I provided you with a quick overview of Google's Closure Compiler Service API, including an introduction to the features that it offers and how you can access it via its GUI. Nevertheless, the main objective of the series is to demonstrate how to consume the API with PHP, and in consonance with this concept I developed an abstract class capable of making HTTP requests to a given host.

At this time, you may be wondering what this buys us, right? Well, with that abstract parent already up and running, it’s ridiculously simple to derive a subclass from it that talks directly to the API, thus making it easy to optimize JavaScript files programmatically.

That’s exactly what I plan to cover in the coming installment of the series. Now that you know what to expect from that tutorial, you don’t have any excuses to miss it!



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

blog comments powered by Disqus
   

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

 



© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap

Dev Shed Tutorial Topics: