PHP cURL vs file_get_contents

111

En quoi ces deux morceaux de code diffèrent-ils lors de l'accès à une API REST?

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

et

$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);

Ils produisent tous deux le même résultat, à en juger par

print_r(json_decode($result))
Salvador Dali
la source
2
cURLest capable de bien plus que file_get_contents. Cela devrait suffire.
18
FWIW il y a peu de différence en ce qui concerne la vitesse. Je viens de finir de récupérer 5 000 URL et d'enregistrer leur code HTML dans des fichiers (environ 200 Ko par fichier). J'ai fait la moitié avec curl et l'autre moitié avec file_get_contents comme expérience et il n'y avait aucune différence perceptible.
David Gilbertson
8
Il est possible d'envoyer des données de publication avec file_get_contents, tant que vous utilisez une version qui prend en charge le contexte de flux.
Chris Strickland

Réponses:

129

file_get_contents()est un simple tournevis. Idéal pour les requêtes GET simples où l'en-tête, la méthode de requête HTTP, le délai d'expiration, le cookiejar, les redirections et d'autres choses importantes n'ont pas d'importance.

fopen()avec un contexte de flux ou cURL avec setopt sont des powerdrills avec tous les bits et toutes les options auxquels vous pouvez penser.

Xeoncross
la source
17
Pour rester dans cette métaphore, notez que cURL est une perceuse électrique avec un mandrin de forage compliqué qui vous oblige à le connaître assez bien pour le changer (lire: définir les options cURL est un peu fastidieux, mais permet de faire tout ce que vous voulez).
poke le
20
file_get_contentspermet également de définir le contexte, ce qui signifie que vous pouvez définir les champs d'en-tête comme vous le souhaitez.
velop
4
et en plus du commentaire de @ velop, via le contexte de flux, il est également possible d'envoyer POST, PUT, l'authentification, les en-têtes, le contenu, le proxy et bien plus encore avec une requête file_get_contents
Markus Köhler
@velop: Oui. Et la méthode aussi. Et redirige. Et timeout ... php.net/manual/en/context.http.php
Sz.
25

De plus, en raison de certains hacks récents de sites Web, nous avons dû sécuriser davantage nos sites. Ce faisant, nous avons découvert que file_get_contents ne fonctionnait pas, là où curl fonctionnerait toujours.

Pas à 100%, mais je pense que ce paramètre php.ini a peut-être bloqué la requête file_get_contents .

; Disable allow_url_fopen for security reasons
allow_url_fopen = 0

Dans tous les cas, notre code fonctionne désormais avec curl .

vr_driver
la source
9
Oui, il file_get_contentsfaut allow_url_fopenêtre honnête.
Costa
2
Oui, de nombreuses sociétés d'hébergement désactivent en file_get_contents()raison de nombreux exploits connus pour utiliser la fonction. cURL est la fonction que les gens devraient utiliser dans le code maintenant.
frustratedtech
15
@frustratedtech De quels "exploits" s'agit-il?
rdlowrey
3
Les sociétés d'hébergement désactivent allow_url_fopenparce qu'elles se trompent en quelque sorte allow_url_include. allow_url_fopenet file_get_contentssont bons à utiliser.
fritzmg
2
@vr_driver ces liens n'ont rien à voir avecfile_get_contents()
rdlowrey
19

C'est un vieux sujet mais lors de mon dernier test sur une de mes API, cURL est plus rapide et plus stable. Parfois, file_get_contents sur une demande plus importante a besoin de plus de 5 secondes alors que cURL n'a besoin que de 1,4 à 1,9 secondes, ce qui est le double plus rapide.

Je dois ajouter une note à ce sujet que je viens d'envoyer GET et de recevoir du contenu JSON. Si vous configurez correctement cURL, vous aurez une excellente réponse. Il suffit de "dire" à cURL ce que vous devez envoyer et ce que vous devez recevoir et c'est tout.

Sur votre exemple, je voudrais faire cette configuration:

$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);

Cette demande renverra les données en 0,01 seconde maximum

Ivijan Stefan Stipić
la source
1
0,1 MICROsecondes (1/1 000 de MILIsecondes) ... Je trouve cela difficile à croire.
Mark Tomlin
Oui. J'ai des réponses en 0,02 ms, par exemple la vérification du numéro de téléphone de l'API Twilio. Est rapide.
Ivijan Stefan Stipić
4
0,02 ms = 20 microsecondes; vous avez dit 0,1 microsecondes, ce qui ne peut pas être exact.
Walf
2
C'est presque deux fois plus rapide que file_get_contents je viens de faire quelques appels API pour confirmer. 0,8 seconde pour file_get_contents& 0,49 seconde pour curl(3 appels API)
Jsp
1
Vous devez utiliser votre propre configuration. Ensuite, vos requêtes passeraient de 1,4-1,9s à 0,01s;)
Rauli Rajande