PHP cURL vs file_get_contents

111

Como essas duas partes do código diferem ao acessar uma API REST?

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

e

$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 produzem o mesmo resultado, a julgar por

print_r(json_decode($result))
Salvador Dalí
fonte
2
cURLé capaz de muito mais do que file_get_contents. Isso deve ser o suficiente.
18
FWIW, há pouca diferença com relação à velocidade. Acabei de buscar 5.000 URLs e salvar seu HTML em arquivos (cerca de 200k por arquivo). Fiz metade com curl e metade com file_get_contents como um experimento e não houve diferença perceptível.
David Gilbertson
8
É possível enviar dados de postagem com file_get_contents, desde que você esteja usando uma versão que suporte contexto de fluxo.
Chris Strickland

Respostas:

129

file_get_contents()é uma chave de fenda simples. Excelente para solicitações GET simples em que o cabeçalho, o método de solicitação HTTP, o tempo limite, o cookiejar, os redirecionamentos e outras coisas importantes não importam.

fopen()com um contexto de fluxo ou cURL com setopt são powerdrills com cada bit e opção que você pode pensar.

Xeoncross
fonte
17
Para ficar dentro dessa metáfora, observe que cURL é uma furadeira com um mandril de perfuração complicado que requer que você o conheça muito bem para realmente mudá-lo (leia: definir opções de cURL é um pouco tedioso, mas permite fazer tudo o que você quiser).
cutucar
20
file_get_contentspermite também definir o contexto, o que significa que você pode definir os campos do cabeçalho como desejar.
velop
4
e além do comentário de @velop, através do contexto do stream também é possível enviar POST, PUT, autenticação, cabeçalhos, conteúdo, proxy e muito mais com uma solicitação file_get_contents
Markus Köhler
@velop: Sim. E método também. E redireciona. E tempo limite ... php.net/manual/en/context.http.php
Sz.
25

Além disso, devido a alguns hacks recentes de sites, tivemos que proteger mais nossos sites. Ao fazer isso, descobrimos que file_get_contents não funcionou, onde curl ainda funcionaria.

Não 100%, mas acredito que essa configuração do php.ini pode estar bloqueando a solicitação file_get_contents .

; Disable allow_url_fopen for security reasons
allow_url_fopen = 0

De qualquer forma, nosso código agora funciona com curl .

vr_driver
fonte
9
Sim, file_get_contentsrequer allow_url_fopenser verdadeiro.
Costa
2
Sim, muitas empresas de hospedagem estão desativando file_get_contents()devido a muitos exploits que usam a função. cURL é a função que as pessoas devem usar no código agora.
frustratedtech de
15
@frustratedtech Que "exploits" são esses?
rdlowrey
3
As empresas de hospedagem desabilitam allow_url_fopenporque meio que confundem com allow_url_include. allow_url_fopene file_get_contentsestão bem para usar.
fritzmg
2
@vr_driver esses links não têm nada a ver comfile_get_contents()
rdlowrey
19

Este é um tópico antigo, mas no meu último teste em uma API, cURL é mais rápido e estável. Às vezes, file_get_contents em solicitações maiores precisam de mais de 5 segundos, quando cURL precisa de apenas 1,4 a 1,9 segundos, o que é o dobro mais rápido.

Eu preciso adicionar uma observação sobre isso que acabei de enviar GET e receber conteúdo JSON. Se você configurar o cURL corretamente, terá uma ótima resposta. Apenas "diga" ao cURL o que você precisa enviar e o que você precisa receber e pronto.

No seu exemplo, gostaria de fazer esta configuração:

$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 solicitação retornará dados em no máximo 0,01 segundo

Ivijan Stefan Stipić
fonte
1
0,1 MICROsegundos (1 / 1.000 de um MILIsegundos) ... Acho isso difícil de acreditar.
Mark Tomlin,
Sim. Tenho algumas respostas em 0,02 ms, por exemplo, verificação do número de telefone da API Twilio. É rápido.
Ivijan Stefan Stipić,
4
0,02 ms = 20 microssegundos; você disse 0,1 microssegundos, o que não pode estar certo.
Walf
2
Isso é quase duas vezes mais rápido se comparado ao file_get_contents que acabei de fazer algumas chamadas de API para confirmar. 0,8 segundos para file_get_contents& 0,49 segundos para curl(3 chamadas de API)
Jsp
1
Você deve usar sua própria configuração. Então suas consultas iriam de 1,4-1,9s para 0,01s;)
Rauli Rajande