class.xcurl.php

By: arvin
February 11, 2010

Programming for the Web today will usually require you to access different websites’ data and functionality to create and build a variety of applications. To do this, you must first be able to fetch their methods. On PHP, you can use cURL or Client URL Request Library. And you will see that even when writing a single class or function, you may need to use cURL several times so it will be best to make a separate classor function for this, to make coding faster.

Basic Usage

Below is an example usage of this xcurl, getting the most recent tweets on Twitter’s public timeline

  $response = xcurl::get('http://twitter.com/statuses/public_timeline.xml');
 
  /* Output:
  $response = array(
      'url' => 'http://twitter.com/statuses/public_timeline.xml',
      'http_code' => '200'
      'headers' => array(...)
      'data'  => '...'
  );
  */

The output of the xcurl request methods is always an associative array with 4 elements; url, http_code, headers, and data.

url – The URL of the API request that was made.
http_code – HTTP status code returned by the api 2XX for successful, or for some 0. Any other value normally indicates an error.
headers – An associative array of all the headers sent by the API request, along with the response.
data – The body of the response.
error – This value is only set if an error was generated when trying to execute the curl request i.e. SSL-related problems (via curl_error())

Posting data

To post data to a URL is just as easy, in the following example, we will tweet an image using img.ly:

  $data = array(
    'media' => '@/path/to/image/folder/ducklings.jpg', // cURL-specific notation
    'username' => 'twitter_username',
    'password' => 'twitter_password',
    'message' => 'saw these ducklings crossing the street'
  );
 
  $response = xcurl::post('http://img.ly/api/uploadAndPost', $data);

If all went well, in a few moments you can see the update on your twitter feed.

HTTP Authetication

For some API requests, you need to send login information via HTTP authentication. Do it by including the username:password string to the options array for the 3rd argument.

  $data = array(
    'botkey' => '12345678',
    'apimethod' => 'getuser',
    'userkey' => 'abcdefghi'
  );
$options = array(
    'userpwd' => 'username:password'
);
 
$response = xcurl::post('https://www.imified.com/api/bot/', $data, $options);

Below is the full source code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?php
 
// safe mode curl
 
class xcurl {
 
    function xcurl() {
 
    }
 
    function post($url, $data, $options=null) {
        return self::request($url, array('post'=>$data), $options);
    }
 
    function get($url, $data = null, $options=null) {
        return self::request($url, array('get'=>$data), $options);
    }
 
    function call   ($url, $data=null, $options=null) { return self::request($url, $data, $options); }
    function fetch  ($url, $data=null, $options=null) { return self::request($url, $data, $options); }
    function request($url, $data=null, $options=null) {
 
        $ch = curl_init();
 
        // Set post, get, cookie data
		if($data) {
    		if(is_array($data)) {
        		if($data['post']) {
        			curl_setopt($ch, CURLOPT_POSTFIELDS, $data['post']);			
        		}		
        		if($data['get']) {
        		    $url .= '?'. self::toQueryString($data['get']);
        		}
    		} else {
        		$url .= $data;
    		}
		}
 
		// Set options
		if($options) {
    		if($options['verbose']) {
        	    curl_setopt($ch, CURLOPT_VERBOSE, TRUE);
                if(is_string($options['verbose']))
        	        curl_setopt($ch, CURLOPT_STDERR, fopen($options['verbose']));
        	    else if(is_resource($options['verbose']))
        	        curl_setopt($ch, CURLOPT_STDERR, $options['verbose']);
    		}
    		if($options['userpwd']) {
        		curl_setopt($ch, CURLOPT_USERPWD, $options['userpwd']);
    		}
    		if(isset($options['sslverifypeer'])) {
        	    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $options['sslverifypeer']);	
    		}
    		if(isset($options['post'])) {
        	    curl_setopt($ch, CURLOPT_POST, $options['post']);	
    		}
		}
 
		curl_setopt($ch, CURLOPT_HEADER, true);
		curl_setopt($ch, CURLOPT_URL, $url);	
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		$raw = curl_exec($ch);
		$error     =  curl_error($ch);
		$response  = self::parseResponse($raw);
		$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		curl_close($ch);
 
		$data = array (
		    'url'       => $url,
		    'http_code' => $http_code,
		    'headers'   => $response['headers'],
		    'data'      => $response['data']
		);
 
		if($raw === false) $data['error'] = $error;
		// $data['raw'] = $raw;
		return $data;
    }
 
	function parseResponse($data) {
    	$blankline = strrpos($data, "\r\n\r\n");
    	$headers = self::parseHeaders(substr($data, 0, $blankline));
    	$body    = substr($data, $blankline + 4);
 
    	return array(
    	    'headers' => $headers,
    	    'data' => $body
    	);
	}
 
	function toQueryString($array) {
    	$string = '';
    	foreach($array as $key => $value)
        	$string .= $key .'='. urlencode($value) .'&';
    	return $string;
	}
 
	function fromQueryString($url) {    	
    	if(strpos($url, '?') === false) return array();
    	$queryString = substr($url, strpos($url, '?') + 1);
    	$pairs = explode('&', $queryString);
 
    	$array= array();
    	foreach($pairs as $pair) {
    	    list($key, $value) = explode('=', $pair, 2);
    	    $array[$key] = $value;
	    }
    	return $array;
	}
 
	// http://www.php.net/manual/en/function.http-parse-headers.php#77241
	function parseHeaders($data) {
        $headers = array();
        $fields = explode("\r\n", preg_replace('/\x0D\x0A[\x09\x20]+/', ' ', $data));
        foreach( $fields as $field ) {
            if( preg_match('/([^:]+): (.+)/m', $field, $match) ) {
                $match[1] = strtolower(preg_replace('/(?<=^|[\x09\x20\x2D])./e', 'strtoupper("\0")', strtolower(trim($match[1]))));
                if(isset($headers[$match[1]]) ) {
                    $headers[$match[1]] = array_merge((array) $headers[$match[1]], (array) $match[2]);
                } else {
                    $headers[$match[1]] = trim($match[2]);
                }
            }
        }
        return $headers;
	}
}
 
?>

  • Twitter
  • Facebook
  • email
  • Blogplay
  • Suggest to Techmeme via Twitter
  • Mixx
  • SphereIt
  • Sphinn
  • Tumblr
  • Google Bookmarks
  • del.icio.us
  • Reddit
  • Digg
  • StumbleUpon
About the Author

arvin is an overdue college crammer, occasional programmer, ever-newbie mashup coder, romantic long-distance lover, retired blogger, and ex-puppy-love-fiction writer. http://twitter.com/rvn

Comments RSS | Give a Comment | Trackback

No Comments

Leave a Reply