PHP Classes
Icontem

File: gCurl/gcurl.class.php


  Search   All class groups All class groups   Latest entries Latest entries   Top 10 charts Top 10 charts   Newsletter Newsletter   Blog Blog   Forums Forums   Help FAQ Help FAQ  
  Login   Register  
Recommend this page to a friend! ReTweet ReTweet Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Grigori Kochanov  >  gCurl  >  gCurl/gcurl.class.php  
File: gCurl/gcurl.class.php
Role: Class source
Content type: text/plain
Description: core class
Class: gCurl
Perform HTTP requests using Curl
 

Contents

Class file image Download
<?php
/**
 * This file contains class gCurl, abstract class gCurlHandlers and exception class gCurlException.
 * It requires gCurlRequest and gCurlResponse classes as well
 * 
 * @package gCurl
 * @author Grigori Kochanov http://www.grik.net/
 */

//Load package classes
if (!class_exists('gCurlRequest')){
    require_once('gCurlRequest.class.php');
}
if (!class_exists('gCurlResponse')){
    require_once('gCurlResponse.class.php');
}
if (!class_exists('gURI')){
    require_once('URI.class.php');
}

//load the exception base class
if (!class_exists('gksException')){
    require_once('gksException.class.php');
}

/**
 * The class extending this interface will contain methods that will be used as handlers
 * for processing HTTP response
 * 
 * @package GCurl
 * @author Grigori Kochanov
 * @version 2
 * @abstract 
 */
abstract class gCurlHandlers{
    /**
     * Name of the method to handle the response body.
     * You can redefine it while processing response headers or cookies.
     * Use NULL to avoid setting a handler for the body.
     *
     * @var string
     */
    public $bodyHandlerName = 'bodyHandler';
    
    /**
     * Instance of the gCurl class utilizing this handler
     *
     * @var gCurl
     */
    protected $gCurl;
    
    /**
     * The handler method triggered after the response headers are received and processed
     * but before receiving the body
     * 
     * @param array $headers
     */
    function headersHandler(array $headers){}
    
    /**
     * The method is triggered after the response headers are received,
     * it receives an array of cookies set by the server as parameter
     *
     * @param array $cookies
     */
    function cookiesHandler(array $cookies){}
    
    /**
     * Default body handler
     *
     * @param string $chunk
     */
    function bodyHandler($ch, $chunk){}
        
    /**
     * Set the reference to the gCurl object that uses this class methods as handlers
     *
     * @param gCurl $gCurl
     */
    final function setGCurlReference(gCurl $gCurl){
        $this->gCurl = $gCurl;
    }
    
    /**
     * Destructor - to avoid a circular reference
     *
     */
    final function cleanGCurlReference(){
        $this->gCurl = null;
    }
}

/**
 * A class to simplify complex tasks for performing and processing HTTP requests with CURL
 *
 * @package GCurl
 * @author Grigori Kochanov
 * @version 2
 */
class gCurl {
    
    /**
     * Error number returned by cURL
     *
     * @var int
     */
    public $curl_errno=0;
    
    /**
     * Error text returned by cURL
     *
     * @var string
     */
    public $curl_error='';
    
    /**
     * instance of the URI class
     *
     * @var gURI
     */
    public $URI;
    
    /**
     * CURL resource handler
     *
     * @var resource
     */
    public $ch;
    
    /**
     * Full URL requested
     *
     * @var string
     */
    protected $location_href= '';
    
    /**
     * Instance of the gCurlRequest object
     *
     * @var gCurlRequest
     * @see gCurlRequest.class.php
     */
    public $Request;
    /**
     * Response object reference
     *
     * @var gCurlResponse
     * @see gCurlResponse.class.php
     */
    public $Response;
    
    /**
     * Flag that defines if cURL should automatically follow the "Location" header or not
     *
     * @var bool
     */
    private $followlocation=0;
    
    /**
     * Flag that defines if cURL should return the body of the response
     *
     * @var bool
     */
    private $return_transfer=1;
    
    /**
     * System network interface (IP)
     * 
     * @var string
     */
    private $interface=null;
    
    
    /**
     * Constants - flags
     */
    const 
    HTTP_BODY = 1,
    HTTP_HEADERS=2,
    HTTP_FULL=3;
    /**
     * sets the status of the data to show the end
     */
    const FLAG_EOF=1;
    /**
     * the HTTP response is received
     */
    const FLAG_HTTP_OK=2;
    /**
     * headers are received and processed
     */
    const FLAG_HEADERS_RECEIVED=4;
    
    /**
     * Constructor of the class
     *
     * @return void
     */
    function __construct($url,$method='GET'){
        if (!defined('CURLE_OK')){
            throw new gCurlException(10);
        }
        //init service objects
        $this->URI = new gURI();
    
        $this->ch = curl_init();
        if ($this->catchCurlError() || !$this->ch){
            throw new gCurlException(15);
        }
    
    
        //define basic parameters
        curl_setopt ($this->ch, CURLOPT_HEADER, 0);
        curl_setopt ($this->ch, CURLOPT_SSL_VERIFYHOST, 2);
        curl_setopt ($this->ch, CURLOPT_FOLLOWLOCATION, false);
        curl_setopt ($this->ch, CURLOPT_ENCODING, '');
        curl_setopt ($this->ch, CURLOPT_RETURNTRANSFER, 1);
        
        //create request and response objects
        $this->Request= new gCurlRequest();
        $this->Response = new gCurlResponse($this->ch,$this->URI);
        
        //set the headers handler
        curl_setopt($this->ch, CURLOPT_HEADERFUNCTION, array($this->Response,'headersHandler'));

        //prepare the URL to browse to
        $this->URI->process($url);
        $this->location_href = $this->URI->full;
    
        $this->Request->setRequestMethod($method);
        if (strcasecmp($method, 'POST')==0){
            curl_setopt ($this->ch, CURLOPT_POST, 1);
        }
    }

    /**
     * signal a redirect URL
     *
     * @param string $new_uri
     */
    function redirect($new_uri){
        $this->URI->parse_http_redirect($new_uri);
        $this->location_href = $this->URI->full;
        
        //create request and response objects
        $this->Request = new gCurlRequest();
        $this->Response->cleanup();
    }

    /**
     * Define whether to return the transfer or not
     *
     * @param bool $value
     */
    function returnTransfer($value){
        $this->return_transfer=(bool)$value;
    }
    
    /**
     * sets the time limit of time the CURL can execute
     *
     * @param int $seconds
     */
    function setTimeout($seconds){
        curl_setopt($this->ch,CURLOPT_TIMEOUT,$seconds);
        if ($this->catchCurlError()){
            throw new gCurlException(22);
        }
    }
    
    /**
     * Set the network interface for the outgoing connection
     *
     * @param string $interface
     */
    function setInterface($interface){
        $this->interface = $interface;
        curl_setopt($this->ch,CURLOPT_INTERFACE,$this->interface);
    }
    
    /**
     * Set extra options for the connection
     *
     * @param array $options
     */
    function setOptions(array $options){
        curl_setopt_array($this->ch,$options);
    }
    
    /**
     * Run the CURL engine
     *
     * @return gCurlResponse
     */
    function exec(){
        //add cookies to headers
        if ($this->Request->cookie_string){
            $this->Request->registerCustomHeader('Cookie: '.$this->Request->cookie_string);
        }
        //process user-defined request headers
        if ($this->Request->custom_headers){
            curl_setopt ($this->ch, CURLOPT_HTTPHEADER, $this->Request->custom_headers);
        }
        //prepare the POST data
        if ($this->Request->method=='POST' && $this->Request->post_data){
            curl_setopt ($this->ch,CURLOPT_POSTFIELDS, $this->Request->post_data);
        }
        //use proxy if defined
        if ($this->Request->proxy && $this->Request->proxy_port){
            curl_setopt ($this->ch, CURLOPT_PROXY, $this->Request->proxy);
            curl_setopt ($this->ch, CURLOPT_PROXYPORT, $this->Request->proxy_port);
            if($this->Request->proxyuser){
                curl_setopt ($this->ch, CURLOPT_PROXYUSERPWD, $this->Request->proxyuser.':'.$this->Request->proxypwd);
            }
        }
        
        //set the URI to connect to
        curl_setopt ($this->ch, CURLOPT_URL, $this->location_href);
        curl_setopt($this->ch,CURLOPT_NOBODY,!$this->return_transfer);

        //run the request
        if ($this->return_transfer){
            $result = curl_exec($this->ch);
        }else{
            curl_exec($this->ch);
            $result='';
        }
        //clear the reference in the handler to avoid circular references
        if ($this->Response->gCurlHandlers){
            $this->Response->gCurlHandlers->cleanGCurlReference();
        }
        
        if ($this->return_transfer && !$result && !$this->Response->headers['len']){
            throw new gCurlException(115);
        }
        //return the response data if required
        if ($this->return_transfer && is_string($result)){
            $this->Response->body = $result;
        }
        return $this->Response;
    }

    /**
     * Close the connection on object destruction
     *
     */
    function __destruct(){
        $this->disconnect();
    }
    
    /**
     * close connection to the remote host
     *
     */
    function disconnect(){
        if (is_resource($this->ch)){
            curl_close($this->ch);
        }
        $this->ch = NULL;
    }
    
    /**
     * check the memory consumption
     *
     */
    function checkMemoryConsumption(){
        if (memory_get_usage()>MEMORY_USAGE_LIMIT*1024){
            throw new gCurlException(60);
        }
    }
    
    /**
     * Check for an error
     *
     * @return bool
     */
    function catchCurlError(){
        if(!is_resource($this->ch) || !($curl_errno=curl_errno($this->ch))){
            return false;
        }
        $this->curl_errno = $curl_errno;
        $this->curl_error = curl_error($this->ch);
        throw new gCurlException(80,$curl_errno,$this->curl_error);
        return true;
    }
    
    /**
     * Pass the object implementing the handlers
     * 
     * @param gCurlHandlers $Handlers
     */
    function setHandlers(gCurlHandlers $Handlers){
        $Handlers->setGCurlReference($this);
        $this->Response->setHandlers($Handlers);
    }
//end of the class
}



/**
 * Exceptions for gCurl
 *
 */
class gCurlException extends Exception implements gksException {

    /**
     * The list of exception codes
     *
     * @var array
     */
    private $exception_codes= array(
        1=>'Connection error',
        10=>'Curl extension not loaded',
        15=>'Could not initialize CURL',
        20=>'Invalid handler method name',
        21=>'Error assigning the output stream for headers',
        22=>'Error setting CURL timeout',
        23=>'Error setting URL to connect to',
        50=>'Invalid request method',
        51=>'Invalid request parameters',
        60=>'Out of memory',
        70=>'Headers already sent to the user agent',
        80=>'CURL reported error',
        90=>'Invalid delay value',
        110=>'Non-HTTP response headers',
        115=>'Curl returned empty result after execution',
        120=>'Invalid host of the requested URI',
        125=>'Invalid URI',
        130=>'Redirects limit reached',
    );

    /**
     * Error number for CURL operation
     *
     * @var int
     */
    public $curl_errno;
    
    /**
     * Error message returned by CURL
     *
     * @var string
     */
    public $curl_error='';
    
    /**
     * Initialize the exception
     *
     * @param int $code
     * @param int $curl_errno
     * @param string $curl_error
     */
    function __construct($code, $curl_errno=0, $curl_error=''){
        //get the error description
        key_exists($code, $this->exception_codes) || $code=1;
        $message= $this->exception_codes[$code]; 
        if ($curl_errno){
            $message.="\nCurl Error #: ".$curl_errno;
        }
        if ($curl_error){
            $message.="\nError message: ".$curl_error;
        }
        //set the error string through the Exception class constructor
        parent::__construct($message, $code);
        
    }
    
    /**
     * Get the message prepared to write to the log file
     *
     * @return string
     */
    function getLogMessage(){
        $log_string='Exception '.$this->getCode().':'.$this->message."\n";
        if ($this->getCode() != 80){
            $log_string .= 'line '.$this->getLine().' file '.$this->getFile()."\n".$this->getTraceAsString()."\n";
        }
        return $log_string;
    }
    
    /**
     * Get the error message to output to the browser
     *
     * @return string
     */
    function getHtmlMessage(){
        $message='<b>Exception '.$this->getCode().'</b>: '.$this->message."<br>\n";
        if ($this->getCode() != 80){
            $message .= 'file '.$this->getFile()."\n<br> line ".$this->getLine().
            "<br>\nTrace: <br />\n".nl2br($this->getTraceAsString())."<br>\n";
        }
        return $message;
    }

//class end
}

 
  Advertise on this site Advertise on this site   Site map Site map   Statistics Statistics   Site tips Site tips   Privacy policy Privacy policy   Contact Contact  

For more information send a message to :
info at phpclasses dot org.
Copyright (c) Icontem 1999-2009 PHP Classes - PHP Class Scripts
  PHP Book Reviews - Reviews of books and other products