PHP cURL frente a file_get_contents

111

¿En qué se diferencian estos dos fragmentos de código al acceder a una API REST?

$result = file_get_contents('http://api.bitly.com/v3/shorten?login=user&apiKey=key&longUrl=url');

y

$ch = curl_init('http://api.bitly.com/v3/shorten?login=user&apiKey=key&longUrl=url');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);

Ambos producen el mismo resultado, a juzgar por

print_r(json_decode($result))
Salvador Dalí
fuente
2
cURLes capaz de mucho más que file_get_contents. Eso debería bastar.
18
FWIW hay poca diferencia con respecto a la velocidad. Acabo de terminar de obtener 5,000 URL y guardar su HTML en archivos (alrededor de 200k por archivo). Hice la mitad con curl y la otra mitad con file_get_contents como experimento y no hubo diferencia perceptible.
David Gilbertson
8
Es posible enviar datos de publicaciones con file_get_contents, siempre que esté utilizando una versión que admita el contexto de transmisión.
Chris Strickland

Respuestas:

129

file_get_contents()es un destornillador simple. Excelente para solicitudes GET simples donde el encabezado, el método de solicitud HTTP, el tiempo de espera, el contenedor de cookies, las redirecciones y otras cosas importantes no importan.

fopen()con un contexto de flujo o cURL con setopt son ejercicios prácticos con cada bit y opción que se te ocurra.

Xeoncross
fuente
17
Para permanecer dentro de esa metáfora, tenga en cuenta que cURL es un taladro eléctrico con un portabrocas complicado que requiere que lo conozca bastante bien para cambiarlo (lea: configurar las opciones de cURL es un poco tedioso, pero permite hacer lo que quiera).
empuje el
20
file_get_contentstambién permite configurar el contexto, lo que significa que puede configurar los campos de encabezado como desee.
velop el
4
y como complemento del comentario de @ velop, a través del contexto de la transmisión también es posible enviar POST, PUT, autenticación, encabezados, contenido, proxy y mucho más con una solicitud file_get_contents
Markus Köhler
@velop: Sí. Y método también. Y redirecciona. Y el tiempo de espera ... php.net/manual/en/context.http.php
Sz.
25

Además de esto, debido a algunos ataques recientes a sitios web, tuvimos que proteger más nuestros sitios. Al hacerlo, descubrimos que file_get_contents no funcionaba, mientras que curl seguiría funcionando.

No al 100%, pero creo que esta configuración de php.ini puede haber estado bloqueando la solicitud file_get_contents .

; Disable allow_url_fopen for security reasons
allow_url_fopen = 0

De cualquier manera, nuestro código ahora funciona con curl .

vr_driver
fuente
9
Sí, file_get_contentsrequiere allow_url_fopenser sincero.
Costa
2
Sí, muchas empresas de alojamiento están desactivando file_get_contents()debido a muchas vulnerabilidades que se sabe que utilizan la función. cURL es la función que la gente debería usar en el código ahora.
frustratedtech
15
@frustratedtech ¿Qué "exploits" son estos?
rdlowrey
3
Las empresas de alojamiento lo desactivan allow_url_fopenporque lo confunden con allow_url_include. allow_url_fopeny file_get_contentsestán bien para usar.
Fritzmg
2
@vr_driver esos enlaces no tienen nada que verfile_get_contents()
rdlowrey
19

Este es un tema antiguo, pero en mi última prueba en una de mis API, cURL es más rápido y más estable. A veces file_get_contents en una solicitud más grande necesita más de 5 segundos cuando cURL solo necesita de 1.4 a 1.9 segundos, lo que es el doble de rápido.

Necesito agregar una nota sobre esto que solo envío GET y recibo contenido JSON. Si configura cURL correctamente, obtendrá una gran respuesta. Simplemente "diga" a cURL lo que necesita enviar y lo que necesita recibir y listo.

En su examen, me gustaría hacer esta configuración:

$ch =  curl_init('http://api.bitly.com/v3/shorten?login=user&apiKey=key&longUrl=url');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
    curl_setopt($ch, CURLOPT_TIMEOUT, 3);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json'));
$result = curl_exec($ch);

Esta solicitud devolverá datos en 0.01 segundos como máximo

Ivijan Stefan Stipić
fuente
1
0.1 MICROsegundos (1 / 1,000 de MILIsegundos) ... Encuentro eso difícil de creer.
Mark Tomlin
Si. Tengo algunas respuestas en 0.02ms, por ejemplo, verificación del número de teléfono de la API de Twilio. Es rápido.
Ivijan Stefan Stipić
4
0,02 ms = 20 microsegundos; dijiste 0,1 microsegundos que no puede ser correcto.
Walf
2
Esto es casi el doble de rápido en comparación con lo file_get_contents que hice para confirmar algunas llamadas a la API. 0,8 segundos para file_get_contentsy 0,49 segundos para curl(3 llamadas API)
Jsp
1
Debería utilizar su propia configuración. Entonces sus consultas irían de 1.4-1.9sa 0.01s;)
Rauli Rajande