Documentation and updates can be found at http://github.com/shuber/curl
<?php
class Curl {
public $cookie_file = 'curl_cookie.txt';
public $headers = array();
public $options = array();
public $referer = '';
public $user_agent = '';
protected $error = '';
public function __construct() {
$this->user_agent = $_SERVER['HTTP_USER_AGENT'];
}
public function delete($url, $vars = array()) {
return $this->request('DELETE', $url, $vars);
}
public function error() {
return $this->error;
}
public function get($url, $vars = array()) {
if (!empty($vars)) {
$url .= (stripos($url, '?') !== false) ? '&' : '?';
$url .= http_build_query($vars);
}
return $this->request('GET', $url);
}
public function post($url, $vars = array()) {
return $this->request('POST', $url, $vars);
}
public function put($url, $vars = array()) {
return $this->request('PUT', $url, $vars);
}
protected function request($method, $url, $vars = array()) {
$handle = curl_init();
# Set some default CURL options
curl_setopt($handle, CURLOPT_COOKIEFILE, $this->cookie_file);
curl_setopt($handle, CURLOPT_COOKIEJAR, $this->cookie_file);
curl_setopt($handle, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($handle, CURLOPT_HEADER, true);
curl_setopt($handle, CURLOPT_POSTFIELDS, $vars);
curl_setopt($handle, CURLOPT_REFERER, $this->referer);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_URL, $url);
curl_setopt($handle, CURLOPT_USERAGENT, $this->user_agent);
# Format custom headers for this request and set CURL option
$headers = array();
foreach ($this->headers as $key => $value) {
$headers[] = $key.': '.$value;
}
curl_setopt($handle, CURLOPT_HTTPHEADER, $headers);
# Determine the request method and set the correct CURL option
switch ($method) {
case 'GET':
curl_setopt($handle, CURLOPT_HTTPGET, true);
break;
case 'POST':
curl_setopt($handle, CURLOPT_POST, true);
break;
default:
curl_setopt($handle, CURLOPT_CUSTOMREQUEST, $method);
}
# Set any custom CURL options
foreach ($this->options as $option => $value) {
curl_setopt($handle, constant('CURLOPT_'.str_replace('CURLOPT_', '', strtoupper($option))), $value);
}
$response = curl_exec($handle);
if ($response) {
$response = new CurlResponse($response);
} else {
$this->error = curl_errno($handle).' - '.curl_error($handle);
}
curl_close($handle);
return $response;
}
}
class CurlResponse {
public $body = '';
public $headers = array();
public function __construct($response) {
# Extract headers from response
$pattern = '#HTTP/\d\.\d.*?$.*?\r\n\r\n#ims';
preg_match_all($pattern, $response, $matches);
$headers = split("\r\n", str_replace("\r\n\r\n", '', array_pop($matches[0])));
# Extract the version and status from the first header
$version_and_status = array_shift($headers);
preg_match('#HTTP/(\d\.\d)\s(\d\d\d)\s(.*)#', $version_and_status, $matches);
$this->headers['Http-Version'] = $matches[1];
$this->headers['Status-Code'] = $matches[2];
$this->headers['Status'] = $matches[2].' '.$matches[3];
# Convert headers into an associative array
foreach ($headers as $header) {
preg_match('#(.*?)\:\s(.*)#', $header, $matches);
$this->headers[$matches[1]] = $matches[2];
}
# Remove the headers from the response body
$this->body = preg_replace($pattern, '', $response);
}
public function __toString() {
return $this->body;
}
}
?>
CURL, Client URL Library Functions
介紹
PHP supports libcurl, a library created by Daniel Stenberg, that allows you to connect and communicate to many different types of servers with many different types of protocols. libcurl currently supports the http, https, ftp, gopher, telnet, dict, file, and ldap protocols. libcurl also supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading (this can also be done with PHP's ftp extension), HTTP form based upload, proxies, cookies, and user+password authentication.
These functions have been added in PHP 4.0.2.
需求
In order to use PHP's cURL functions you need to install the » libcurl package. PHP requires that you use libcurl 7.0.2-beta or higher. In PHP 4.2.3, you will need libcurl version 7.9.0 or higher. From PHP 4.3.0, you will need a libcurl version that's 7.9.8 or higher. PHP 5.0.0 requires a libcurl version 7.10.5 or greater.
安裝
To use PHP's cURL support you must also compile PHP --with-curl[=DIR] where DIR is the location of the directory containing the lib and include directories. In the "include" directory there should be a folder named "curl" which should contain the easy.h and curl.h files. There should be a file named libcurl.a located in the "lib" directory. Beginning with PHP 4.3.0 you can configure PHP to use cURL for URL streams --with-curlwrappers.
Note: Note to Win32 Users In order to enable this module on a Windows environment, libeay32.dll and ssleay32.dll must be present in your PATH. You don't need libcurl.dll from the cURL site.
資源類型
This extension defines two resource types: a cURL handle and a cURL multi handle.
預先定義常數
See also the cURL Predefined Constants
範例
Once you've compiled PHP with cURL support, you can begin using the cURL functions. The basic idea behind the cURL functions is that you initialize a cURL session using the curl_init(), then you can set all your options for the transfer via the curl_setopt(), then you can execute the session with the curl_exec() and then you finish off your session using the curl_close(). Here is an example that uses the cURL functions to fetch the example.com homepage into a file:
Example#1 Using PHP's cURL module to fetch the example.com homepage
<?php
$ch = curl_init("http://www.example.com/");
$fp = fopen("example_homepage.txt", "w");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
?>
Table of Contents
- Constants — Curl Predefined Constants
- curl_close — Close a cURL session
- curl_copy_handle — Copy a cURL handle along with all of its preferences
- curl_errno — Return the last error number
- curl_error — Return a string containing the last error for the current session
- curl_exec — Perform a cURL session
- curl_getinfo — Get information regarding a specific transfer
- curl_init — Initialize a cURL session
- curl_multi_add_handle — Add a normal cURL handle to a cURL multi handle
- curl_multi_close — Close a set of cURL handles
- curl_multi_exec — Run the sub-connections of the current cURL handle
- curl_multi_getcontent — Return the content of a cURL handle if CURLOPT_RETURNTRANSFER is set
- curl_multi_info_read — Get information about the current transfers
- curl_multi_init — Returns a new cURL multi handle
- curl_multi_remove_handle — Remove a multi handle from a set of cURL handles
- curl_multi_select — Get all the sockets associated with the cURL extension, which can then be "selected"
- curl_setopt_array — Set multiple options for a cURL transfer
- curl_setopt — Set an option for a cURL transfer
- curl_version — Gets cURL version information
CURL
07-May-2008 03:30
02-May-2008 07:44
Although it has been noted that cURL outperforms both file_get_contents and fopen when it comes to getting a file over a HTTP link, the disadvantage of cURL is that it has no way of only reading a part of a page at a time.
For example, the following code is likely to generate a memory limit error:
<?php
$ch = curl_init("http://www.example.com/reallybigfile.tar.gz");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
$output = curl_exec($ch);
$fh = fopen("out.tar.gz", 'w');
fwrite($fh, $output);
fclose($fh);
?>
While this, on the other hand, wouldn't
<?php
$hostfile = fopen("http://www.example.com/reallybigfile.tar.gz", 'r');
$fh = fopen("out.tar.gz", 'w');
while (!feof($hostfile)) {
$output = fread($hostfile, 8192);
fwrite($fh, $output);
}
fclose($hostfile);
fclose($fh);
?>
02-May-2008 11:20
In order to prevent curl sending messages to the server error log, you need to instruct curl to use a temporary file for output on stderr.
<?php
$gacookie="/askapache/tmp/curl-1.txt";
@touch($gacookie);
@chmod($gacookie,0666);
if($fp = tmpfile()){
$ch = curl_init("http://www.askapache.com/p.php");
curl_setopt ($ch, CURLOPT_STDERR, $fp);
curl_setopt ($ch, CURLOPT_VERBOSE, 2);
curl_setopt ($ch, CURLOPT_ENCODING, 0);
curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/5.0');
curl_setopt ($ch, CURLOPT_HTTPHEADER, $FF);
curl_setopt ($ch, CURLOPT_COOKIEFILE, $gacookie);
curl_setopt ($ch, CURLOPT_COOKIEJAR, $gacookie);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_FAILONERROR, 1);
curl_setopt ($ch, CURLOPT_HEADER, 1);
curl_setopt ($ch, CURLINFO_HEADER_OUT, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 30);
$r=curl_exec($ch);$ch_info=curl_getinfo($ch);
if (curl_errno($ch)) return false;
else curl_close($ch);
header("Content-type: text/plain");
echo $r;
sleep(2);
$postdata='keywords='.$_GET['k'];
$ch1 = curl_init("http://www.askapache.com/p.php");
curl_setopt ($ch1, CURLOPT_STDERR, $fp);
curl_setopt ($ch1, CURLOPT_VERBOSE, 2);
curl_setopt ($ch1, CURLOPT_ENCODING, 0);
curl_setopt ($ch1, CURLOPT_USERAGENT, 'Mozilla/5.0');
curl_setopt ($ch1, CURLOPT_COOKIEJAR, $gacookie);
curl_setopt ($ch1, CURLOPT_COOKIEFILE, $gacookie);
curl_setopt ($ch1, CURLOPT_POSTFIELDS, $postdata);
curl_setopt ($ch1, CURLOPT_POST, 1);
curl_setopt ($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch1, CURLOPT_FAILONERROR, 1);
curl_setopt ($ch1, CURLOPT_HEADER, 1);
curl_setopt ($ch1, CURLINFO_HEADER_OUT, 1);
curl_setopt ($ch1, CURLOPT_CONNECTTIMEOUT, 30);
$r=curl_exec ($ch1);$ch1_info=curl_getinfo($ch1);
if (curl_errno($ch1)) return false;
else curl_close($ch1);
header("Content-type: text/plain");print_r($ch1_info);echo $r;sleep(2);
}fclose($fp);
@unlink($gacookie);
?>
See also: http://www.askapache.com/security/curl-google-post-feed.html
10-Mar-2008 03:55
I've developed a simple curl class for executing get, post, and put requests (based on the documentation and user notes here).
The simplest example:
<?php
// a simple GET request:
include('eac_curl.class.php');
$http = new cURL();
$result = $http->get('http://www.domain.com/somepage.php');
?>
Along with that is a streams class to perform nearly the same thing using streams.
http://www.kevinburkholder.com/sw_curl_stream.php
Hope it's useful. Any feedback is welcomed.
[note: cross-posted to streams page]
08-Mar-2008 06:20
Do not forget to use the complete path for the cookies
$ch = curl_init() ;
$myfile = "d:\\mydir\\second_dir\\cookiefile.txt" ;
curl_setopt($ch, CURLOPT_COOKIEJAR, $myfile) ;
Best regards,
Fernando Gabrieli
04-Mar-2008 01:16
if you would like to send xml request to a server (lets say, making a soap proxy),
you have to set
url_setopt($ch, CURLOPT_HTTPHEADER, Array("Content-Type: text/xml"));
makesure you watch for cache issue:
the below code will prevent cache...
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
hope it helps ;)
26-Jan-2008 03:26
As a windows xp user having php 5.2.5 running as an apache module on my personal computer, all I had to do in order to get this CURL stuff working is to uncomment the following line in my php.ini file:
extension=php_curl.dll
Thought I'd just mention it as it may save time to others since it seems somehow less compicated than the process mentioned (without sufficient explanation, mind you) in the above article (compile php??? options??? all I ever did to install php was to unzip the archive I downloaded and add a couple of line to my apache conf file).
I just tried downloading a web page and save its source into a text file using the example from the manual above. When the php_curl.dll extension is not active, it doesn't work (fatal error with init_curl, as you'd expect). When the php_curl.dll extension is active, it works. No need for any other intricate operation as far as I can say.
Otherwise, it's great that I now have my tool for doing any http request i want.
17-Jan-2008 08:46
ryan at tankprofiler dot com was exactly right. We had our path properly set for IIS 6.0 on Windows Server 2k3, but we could not get cURL to load up in our test environment.
We followed his troubleshooting steps and had his identical issue: --permissions--. Setting the permissions on both requisite .dll files to 'EVERYONE' allowed it to load for IIS. Someone should update the 'NOTE' at the top of this page to include this information.
We have not tried with just the IUSR_YOURSRVRNAME and NETWORK_SERVICE users enabled, yet. But we'll test with those 2 instead of EVERYONE on our live servers.
16-Jan-2008 07:00
re: jade dot skaggs at gmail dot com code
The code looks great! However, you should make a comment as to fopen() line reminding newbees like me to ensure that "allow_url_fopen" should be set "on" in the server. Please correct me if I am wrong.
Thanks!
07-Jan-2008 09:48
After much struggling, I managed to get a SOAP request requiring HTTP authentication to work. Here's some source that will hopefully be useful to others.
<?php
$credentials = "username:password";
// Read the XML to send to the Web Service
$request_file = "./SampleRequest.xml";
$fh = fopen($request_file, 'r');
$xml_data = fread($fh, filesize($request_file));
fclose($fh);
$url = "http://www.myservicehost.com/services/calculation";
$page = "/services/calculation";
$headers = array(
"POST ".$page." HTTP/1.0",
"Content-type: text/xml;charset=\"utf-8\"",
"Accept: text/xml",
"Cache-Control: no-cache",
"Pragma: no-cache",
"SOAPAction: \"run\"",
"Content-length: ".strlen($xml_data),
"Authorization: Basic " . base64_encode($credentials)
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_USERAGENT, $defined_vars['HTTP_USER_AGENT']);
// Apply the XML to our curl call
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_data);
$data = curl_exec($ch);
if (curl_errno($ch)) {
print "Error: " . curl_error($ch);
} else {
// Show me the result
var_dump($data);
curl_close($ch);
}
?>
05-Jan-2008 01:25
As Josh at endquote pointed out, you need to include the "urlencode"d __VIEWSTATE when posting to aspx/asp pages.
And I wanted to add, you may also have to do the same thing with __EVENTVALIDATION or any other fields that come preset with data.
29-Oct-2007 01:26
If you have trouble on server 2003, IIS 6 ( perhaps other versions ) with getting the php_curl loading please see the following.
- run (as an administrator) php.exe -i > C:\phpinfo.txt and go open C:\phpinfo.txt, look in the file to see if CURL was loading, if it's there then keep reading.
- running <?PHP phpinfo(); ?> inside a text.php script on my IIS server would not show CURL loading
- A permissions problem on libeay32.dll and ssleay32.dll was causing the cli version of php allowing me access to these two dlls while IIS was not able to get them. I gave 'everyone' read and execute on these two dll's to try to fix the issue and it just now worked. You may wish to be more restrictive, perhaps IUSR rather than EVERYONE; but check your permissions none-the-less.
Hopefully this saves someone some time!
- Ryan Nanney
25-Sep-2007 10:52
<?
/*
* Author: Ojas Ojasvi
* Released: September 25, 2007
* Description: An example of the disguise_curl() function in order to grab contents from a website while remaining fully camouflaged by using a fake user agent and fake headers.
*/
$url = 'http://www.php.net';
// disguises the curl using fake headers and a fake user agent.
function disguise_curl($url)
{
$curl = curl_init();
// Setup headers - I used the same headers from Firefox version 2.0.0.6
// below was split up because php.net said the line was too long. :/
$header[0] = "Accept: text/xml,application/xml,application/xhtml+xml,";
$header[0] .= "text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
$header[] = "Cache-Control: max-age=0";
$header[] = "Connection: keep-alive";
$header[] = "Keep-Alive: 300";
$header[] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7";
$header[] = "Accept-Language: en-us,en;q=0.5";
$header[] = "Pragma: "; // browsers keep this blank.
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_USERAGENT, 'Googlebot/2.1 (+http://www.google.com/bot.html)');
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_REFERER, 'http://www.google.com');
curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate');
curl_setopt($curl, CURLOPT_AUTOREFERER, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
$html = curl_exec($curl); // execute the curl command
curl_close($curl); // close the connection
return $html; // and finally, return $html
}
// uses the function and displays the text off the website
$text = disguise_curl($url);
echo $text;
?>
Ojas Ojasvi
20-Sep-2007 09:09
a few notes regarding the paymentech solution posted above by "ksavage". to work properly, two changes are required (at least they were for my system/account).
first, the content-type (in header) should read:
"Content-type: application/PTI40\r\n";
.. and NOT (PTI26)
second, the following needs to be added to the script (where the curl options are stated):
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0)
...otherwise, paymentech will ask for SSL certificate.
04-Sep-2007 07:35
I would like to specify a content-type for a file I am uploading with cURL and yet I find I do not have any way of doing this. I know that there is a mechanism through the command-line cURL to specify content-types of files.
I want to set userInfo.xml to have a Content type of "text/xml". Here is my code:
<?php
$postData['userInfo'] = "@userInfo.xml";
$url = "http://curl.dev";
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
$response = curl_exec($ch);
print_r($response);
if(curl_errno($ch))
{
print curl_error($ch);
}
curl_close($ch);
?>
01-Sep-2007 02:27
FYI,
Anyone trying to connect to .NET with CURL to send a simple XML post, pay attention to the following. This will save you hours! There is a previous note that I saw either on this page, or somewhere else on this site that explains the correct way to specify the header option is to create an array, then reference the array from the CURLOPT.
ie. Do something like this:
// Req. HTTP Header Values
$header[] = "Content-type: text/xml";
// Target URL
$sendTo = "http://www.blah.com";
// Post Data
$post = "<?xml version="1.0\" encoding=\"utf-8\"?>\n<root>\n....etc, etc,";
// Create CURL Connection
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, 'XtraDoh xAgent');
curl_setopt($ch, CURLOPT_URL, $sendTo);
curl_setopt($ch, CURLOPT_TIMEOUT, 900);
curl_setopt($ch, CURLOPT_CONNECTIONTIMEOUT, 30);
curl_setopt($ch, CURLOPT_FAILONERROR, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
Notice the HTTPHEADER, $header above. I have not been able to get .NET to properly read the HTTP header as specified (in this case as text/xml) when using the following:
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type'=>'text/xml'));
Although this may work when working with other PHP, IIS, or even PHP, Apache, it does not (at least in my experience) work with .NET, IIS.
09-Jul-2007 02:30
This function takes a URL and returns a plain-text version of the page. It uses cURL to retrieve the page and a combination of regular expressions to strip all unwanted whitespace. This function will even strip the text from STYLE and SCRIPT tags, which are ignored by PHP functions such as strip_tags (they strip only the tags, leaving the text in the middle intact).
Regular expressions were split in 2 stages, to avoid deleting single carriage returns (also matched by \s) but still delete all blank lines and multiple linefeeds or spaces, trimming operations took place in 2 stages.
function webpage2txt($url)
{
$user_agent = “Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)”;
$ch = curl_init(); // initialize curl handle
curl_setopt($ch, CURLOPT_URL, $url); // set url to post to
curl_setopt($ch, CURLOPT_FAILONERROR, 1); // Fail on errors
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // allow redirects
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); // return into a variable
curl_setopt($ch, CURLOPT_PORT, 80); //Set the port number
curl_setopt($ch, CURLOPT_TIMEOUT, 15); // times out after 15s
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
$document = curl_exec($ch);
$search = array(’@<script[^>]*?>.*?</script>@si’, // Strip out javascript
‘@<style[^>]*?>.*?</style>@siU’, // Strip style tags properly
‘@<[\/\!]*?[^<>]*?>@si’, // Strip out HTML tags
‘@<![\s\S]*?–[ \t\n\r]*>@’, // Strip multi-line comments including CDATA
‘/\s{2,}/’,
);
$text = preg_replace($search, “\n”, html_entity_decode($document));
$pat[0] = “/^\s+/”;
$pat[2] = “/\s+\$/”;
$rep[0] = “”;
$rep[2] = ” “;
$text = preg_replace($pat, $rep, trim($text));
return $text;
}
Potential uses of this function are extracting keywords from a webpage, counting words and things like that. If you find it useful, drop us a comment and let us know where you used it.
07-Jul-2007 06:59
Don't foget to curl_close($ch); Even if curl_errno($ch) != 0
Because if you don't - on Windows this will produce windows-error-report (Program terminated unexpectedly)
03-Jun-2007 04:51
In case you wonder how come, that cookies don't work under Windows, I've googled for some answers, and here is the result: Under WIN you need to input absolute path of the cookie file.
This piece of code solves it:
<?php
if ($cookies != '')
{
if (substr(PHP_OS, 0, 3) == 'WIN')
{$cookies = str_replace('\\','/', getcwd().'/'.$cookies);}
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookies);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookies);
}
?>
30-May-2007 04:58
Earlier I posted about using php to interface with an authorize.net gateway. I accidentally made a mistake in my code.
Instead of:
curl_setopt($connection, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($AuthNetConn, CURLOPT_CAINFO, "path:/ca-bundle.crt");
It should be
curl_setopt($connection, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($connection, CURLOPT_CAINFO, "path:/ca-bundle.crt");
Whatever you call that first connection variable, it needs to be the same in both statements. Sorry about that.
16-May-2007 12:25
I also think that a leading ampersand is a special escape for the cURL library to tell it that this post field is actually a path to a file that should be sent to the web server.
Not sure if that works yet, but I sure hope so. I don't relish the thought of rolling my own multi-part submitter by hand for something I'm working on.
13-May-2007 08:51
Many people still use the fopen wrappers, file_get_contents(), or even include() to open files across the internet. The issue with this is that they were not designed to do so and they are inefficient in doing so. Curl is a great alternative to these and isn't much harder to use. It even beats out the use of sockets in fairly default configurations.
I have created a script that tests all 4 methods on 20 different websites 10 times each. The results are clear, here is one set of the results:
Curl time: 43.02 seconds
FGC time: 86.48 seconds
Fopen time: 86.34 seconds
Socket time: 44.91 seconds
As you can see, there is little performance difference between file_get_contents and fopen/fread. Likewise, there is little difference between curl and sockets.
You may use the test to see the results in realtime if you'd like: http://trucex.com/curltest.php
09-May-2007 03:54
Post variables should be properly urlencode()'d, so, for your example,
$data = array('text' => urlencode(stripslashes("@pouetpouet")));
06-Mar-2007 11:23
For anyone trying to use cURL to submit to an ASP/ASPX page that uses an image as the submit button.
Make sure that you have 'button_name.x' and 'button_name.y' in the post fields. PHP names these fields 'button_name_x' and 'button_name_y', while ASP uses a dot.
Also, as noted above, be sure to include the '__VIEWSTATE' input field in your post request.
25-Jan-2007 02:24
Using curl to take snapshots of the current page for emailing the HTML is a clever little idea. (ie: Email this page to a friend)
//to be explained below!
session_write_close();
$pageurl = "http://www.site.com/content.php?PHPSESSID=123XYZ
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_URL, $pageurl );
$html = curl_exec ( $ch );
curl_close($ch);
//then you need to fix pathing to absolute
$search = "/(src|href|background)=\"[^:,^>,^\"]*\"/i";
preg_match_all ( $search, $html, $a_matches );
//you can figure out the rest ! but thought the reg expression is useful as well
But here is the catch, you may want to make sure curl connects to the server under the same session as the browser. So naturally you pass the session cookie through the curl system either by the cookie jar system, or through the query string in the path.
This is where you will get stuck. PHP will need write access to the same session file simultaneously!! causing serious hanging issues!
This is why you should close off your session before you make curl take a page snapshot!
20-Jan-2007 01:05
If PHP configure fails with cURL errors, try ommiting the --with-curl=path and just make this --with-curl.
Of course it will also be optimal to make sure that the cURL library directory is listed in /etc/ld.so.conf and then run 'ldconfig'.
By default this is /usr/local/lib.
27-Nov-2006 01:42
I was having problems with Authorize.net and the SSL cert matching even after adding:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
What I found after a lot of stumbling was I needed to set VERIFYHOST to FALSE. So if you are still have a problem with Authorize.NET SSL and cURL add this:
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
22-Nov-2006 10:33
I was working on using php to interface with an authorize.net gateway, and I ran into a problem with certificates using curl to talk the https:// url.
curl_error() told me "SSL certificate problem, verify that the CA cert is OK."
I googled it and found the same "solution" over and over again: bypass verification by adding this line after curl_init():
curl_setopt($connection, CURLOPT_SSL_VERIFYPEER, false);
This worked great, but I was required to verify, so here's what I did. Add the following lines:
curl_setopt($connection, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($AuthNetConn, CURLOPT_CAINFO, "path:/ca-bundle.crt");
with "path:/ca-bundle.crt" being the path to that certificate file. You can get this file by downloading the curl package (http://curl.haxx.se/download.html) and looking for it in the lib folder.
Feel free to email me.
25-Aug-2006 06:53
For anyone who is having trouble getting some of the advanced functionality to work in whatever version of PHP you have, I wrote a little wrapper for the command line version of curl. The function below is for Windows (hence, the curl.exe), but it works the same way under Linux or whatever.
The curl man page enumerates a ton of options you can use...
function curlPageGrabber($destinationURL, $refererURL, $postData, $autoForward = false, $autoGrabCookies = true, $curlDebug = false)
{
$curlString = "c:\curl\curl.exe -i -v -m 30 -L -b c:\curl\cookiejar.txt -c c:\curl\cookiejar.txt ";
$curlString .= " -A \"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322;)\" ";
$curlString .= " -H \"Accept-Language: en-us\" ";
$curlString .= " -H \"Accept-Encoding: gzip, deflate\" ";
$curlString .= " -H \"Host: affiliate-program.amazon.com\" ";
$curlString .= " -H \"Accept: */*\" ";
$curlString .= " --compressed ";
//$curlString .= " --trace-ascii ";
if ($refererURL != '')
{
$curlString .= "-e \"".$refererURL."\" ";
}
if ($postData != '')
{
$curlString.= " -d \"$postData\" ";
}
$curlString .= $destinationURL;
if ($curlDebug == true)
{
echo "<p>curlString: $curlString</p>";
}
$temp = exec($curlString, $retval);
$htmlData = '';
foreach ($retval as $arrayLine)
{
$htmlData .= $arrayLine."\r\n";
}
if ($curlDebug == true)
{
echo "<textarea cols=80 rows=20>$htmlData</textarea>";
}
return $htmlData;
} // end function
06-Jul-2006 08:27
Note that on Win32 this documentation can get a little confusing.
In order to get this to work you need to:
1) Be sure that the folder where libeay32.dll and ssleay32.dll - tipically C:\\PHP - is present on the PATH variable.
2) Uncomment - remove the semi-colon - the line that says "extension=php_curl.dll" from php.ini
3) Restart the webserver (you should already know this one, but...)
It took me some time to realize this, since this page doesn't mention the need to uncomment that php.ini's line.
30-May-2006 05:42
This may be obvious to everybody *except* me, but if you want to use curl to connect via ftp rather than http, then you just need to use "ftp://" in the url specification (I was looking for an use_ftp flag or something).
Use the CURLOPT_USERPWD to login to the ftp site.
05-May-2006 04:01
<?php
/*
Sean Huber CURL library
This library is a basic implementation of CURL capabilities.
It works in most modern versions of IE and FF.
==================================== USAGE ====================================
It exports the CURL object globally, so set a callback with setCallback($func).
(Use setCallback(array('class_name', 'func_name')) to set a callback as a func
that lies within a different class)
Then use one of the CURL request methods:
get($url);
post($url, $vars); vars is a urlencoded string in query string format.
Your callback function will then be called with 1 argument, the response text.
If a callback is not defined, your request will return the response text.
*/
class CURL {
var $callback = false;
function setCallback($func_name) {
$this->callback = $func_name;
}
function doRequest($method, $url, $vars) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
if ($method == 'POST') {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);
}
$data = curl_exec($ch);
curl_close($ch);
if ($data) {
if ($this->callback)
{
$callback = $this->callback;
$this->callback = false;
return call_user_func($callback, $data);
} else {
return $data;
}
} else {
return curl_error($ch);
}
}
function get($url) {
return $this->doRequest('GET', $url, 'NULL');
}
function post($url, $vars) {
return $this->doRequest('POST', $url, $vars);
}
}
?>
29-Mar-2006 02:48
When you try to login to a page using cURL, you could experience problems when you're not providing the right URL.
For instance, if you use the front page to login (http://awebsite.com/) where to form is located, you will receive a http 405 error, instead view the source and see what the form's action is, it might just be: http://awebsite.com/processlogin.php
Took me hours to find this out, hope it can save someone else's time.
02-Mar-2006 04:21
Beware of any extra spaces in the URL. A trailing space in the URL caused my script to fail with the message "empty reply from server".
23-Feb-2006 01:57
The examples below for HTTP file upload work great, but I wanted to be able to post multiple files through HTTP upload using HTML arrays as specified in example 38.3 at
http://us3.php.net/features.file-upload
In this case, you need to set the arrays AND keys in the $post_data, it will not work with just the array names. The following example shows how this works:
<?php
$post_data = array();
$post_data['pictures[0]'] = "@cat.jpg";
$post_data['pictures[1]'] = "@dog.jpg";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://my.domain.com/my_url.php" );
curl_setopt($ch, CURLOPT_POST, 1 );
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$postResult = curl_exec($ch);
if (curl_errno($ch)) {
print curl_error($ch);
}
curl_close($ch);
print "$postResult";
?>
21-Feb-2006 10:40
I had the following experience when harvesting urls with a get variable from a page using cUrl. HTML pages will output ampersands as & when the page is read by the curl function.
If you code a script to find all hyperlinks, it will use & instead of &, especially using a regular expression search.
It is hard to detect because when you output the url to the browser it renders the html. To fix, add a line to replace the & with &.
function processURL($url){
$url=str_replace('&','&',$url);
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
$xml = curl_exec ($ch);
curl_close ($ch);
echo $xml;
}
}
17-Feb-2006 04:19
load https:// or http://ex.com/exam.php
with POST data (name=alex&year=18) and apply COOKIEs
$sessions = curl_init();
curl_setopt($sessions,CURLOPT_URL,'http://ex.com/exam.php');
curl_setopt($sessions, CURLOPT_POST, 1);
curl_setopt($sessions,CURLOPT_POSTFIELDS,'name=alex&year=18');
curl_setopt($sessions,CURLOPT_COOKIEJAR,
dirname(__FILE__).'/cookie.txt');
curl_setopt($sessions,CURLOPT_FOLLOWLOCATION,0);
curl_setopt($sessions, CURLOPT_HEADER , 1);
curl_setopt($sessions, CURLOPT_RETURNTRANSFER,1);
$my_load_page = curl_exec($this->sessions);
06-Feb-2006 01:53
To shed some light on some of the numbers trucex at gmail has in his tests, some of the web pages (Yahoo and GoDaddy) downloaded at exceptionally faster speeds than with file_get_contents(). This is simply because CURL accepts (by default) compression protocols such as deflate and gzip.
Most likely GoDaddy.com may be using compression for specific HTTP clients including CURL. I know for a fact that Yahoo.com and Google.com use gzip compression. You can test servers for gzip compression here: http://www.whatsmyip.org/mod_gzip_test/
For the sake of performance, I would recommend the use of CURL. if performance was not an issue and I wanted to keep my code simple and portable (for PHP servers without the cURL extension) I would use file_get_contents().
02-Feb-2006 03:55
If you're getting trouble with cookie handling in curl:
- curl manages tranparently cookies in a single curl session
- the option
curl_setopt($ch, CURLOPT_COOKIEJAR, "/tmp/cookieFileName");
makes curl to store the cookies in a file at the and of the curl session
- the option
curl_setopt($ch, CURLOPT_COOKIEFILE, "/tmp/cookieFileName");
makes curl to use the given file as source for the cookies to send to the server.
so to handle correctly cookies between different curl session, the you have to do something like this:
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_COOKIEJAR, COOKIE_FILE_PATH);
curl_setopt ($ch, CURLOPT_COOKIEFILE, COOKIE_FILE_PATH);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec ($ch);
curl_close($ch);
return $result;
in particular this is NECESSARY if you are using PEAR_SOAP libraries to build a webservice client over https and the remote server need to establish a session cookie. in fact each soap message is sent using a different curl session!!
I hope this can help someone
Luca
23-Dec-2005 08:39
In replay to trucexs post,
You are right in case if we will talk about simple script, like you mention. Now just imagine situation when you will need to create some kind of web based proxy (example gesoft.org)? Can it be done by using simple functions like file_get_contents? The answer will be positive, but at the same time dont forget the time which will be spend to do the same job. Is it worth to spend more time?
Now most important thing in which I will never agree, is it possible to execute more than 1000 threads at the same? Yes and here is an example of it. proxy-list.org. 1000 proxies are rechecked every 10 min. The difference between first proxy testing and last one could be easily calculated and it will be equal something about 46 seconds. It should be mentioned that this testing script not only executed and stopped but it has 30 seconds timeout!!! That means that script can not finish its work 30 seconds earlier.
According my stats, if just simple web page will be opened by curl, there is possibility to execute up to 10k threads at the same time.
One more important parameter is which amount of possible simultaneously threads can be executed depends directly proportionally on hosting quality! Such as, busyness, CPU, RAM, at list internet channel quality and speed.
Regards and good luck in you work
Vitali Simsive
18-Dec-2005 07:10
I've seen a few people claim things like curl executing 2000 requests per minute (I didn't believe it, but see godaddy.com in the results below). I've also gotten into 5-6 argumen