PHP cURL vs file_get_contents

111

Wie unterscheiden sich diese beiden Codeteile beim Zugriff auf eine REST-API?

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

und

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

Beide führen nach dem gleichen Ergebnis

print_r(json_decode($result))
Salvador Dali
quelle
2
cURList zu viel mehr fähig als file_get_contents. Das sollte genug sein.
18
FWIW gibt es wenig Unterschied in Bezug auf die Geschwindigkeit. Ich habe gerade 5.000 URLs abgerufen und deren HTML in Dateien gespeichert (ca. 200.000 pro Datei). Ich habe halb mit Curl und halb mit file_get_contents als Experiment gearbeitet und es gab keinen erkennbaren Unterschied.
David Gilbertson
8
Es ist möglich, Post-Daten mit file_get_contents zu senden, solange Sie eine Version verwenden, die den Stream-Kontext unterstützt.
Chris Strickland

Antworten:

129

file_get_contents()ist ein einfacher Schraubendreher. Hervorragend geeignet für einfache GET-Anforderungen, bei denen der Header, die HTTP-Anforderungsmethode, das Timeout, das Cookiejar, Weiterleitungen und andere wichtige Dinge keine Rolle spielen.

fopen()mit einem Stream-Kontext oder cURL mit setopt sind Powerdrills mit jedem Bit und jeder Option, die Sie sich vorstellen können.

Xeoncross
quelle
17
Um innerhalb dieser Metapher zu bleiben, beachten Sie, dass cURL ein Bohrer mit einem komplizierten Bohrfutter ist, bei dem Sie es ziemlich gut kennen müssen, um es tatsächlich zu ändern (lesen Sie: Das Festlegen von cURL-Optionen ist etwas mühsam, ermöglicht jedoch alles, was Sie möchten).
Poke
20
file_get_contentsErmöglicht auch das Festlegen des Kontexts, dh Sie können die Kopfzeilenfelder nach Ihren Wünschen festlegen.
Velop
4
Zusätzlich zu @ velops Kommentar ist es über den Stream-Kontext auch möglich, POST, PUT, Authentifizierung, Header, Inhalt, Proxy und vieles mehr mit einer Anfrage von file_get_contents zu senden
Markus Köhler,
@velop: Ja. Und Methode auch. Und leitet weiter. Und Timeout ... php.net/manual/en/context.http.php
.
25

Darüber hinaus mussten wir aufgrund einiger kürzlich durchgeführter Website-Hacks unsere Websites mehr sichern. Dabei stellten wir fest, dass file_get_contents nicht funktionierte, wo Curl noch funktionieren würde.

Nicht 100%, aber ich glaube, dass diese php.ini-Einstellung die Anfrage file_get_contents blockiert hat .

; Disable allow_url_fopen for security reasons
allow_url_fopen = 0

In jedem Fall funktioniert unser Code jetzt mit Curl .

vr_driver
quelle
9
Ja, file_get_contentsmuss allow_url_fopenehrlich sein.
Costa
2
Ja, viele Hosting-Unternehmen deaktivieren file_get_contents()aufgrund vieler Exploits, von denen bekannt ist, dass sie die Funktion verwenden. cURL ist die Funktion, die Benutzer jetzt im Code verwenden sollten.
frustrierte
15
@frustratedtech Was für "Exploits" sind das?
Rdlowrey
3
Hosting-Unternehmen deaktivieren, allow_url_fopenweil sie es irgendwie verwechseln allow_url_include. allow_url_fopenund file_get_contentssind gut zu bedienen.
fritzmg
2
@vr_driver diese Links haben nichts mitfile_get_contents()
rdlowrey
19

Dies ist ein altes Thema, aber bei meinem letzten Test auf einer meiner APIs ist cURL schneller und stabiler. Manchmal benötigen file_get_contents bei größeren Anforderungen mehr als 5 Sekunden, wenn cURL nur 1,4 bis 1,9 Sekunden benötigt, was doppelt so schnell ist.

Ich muss einen Hinweis hinzufügen, dass ich nur GET sende und JSON-Inhalte empfange. Wenn Sie cURL richtig einrichten, erhalten Sie eine gute Antwort. Sagen Sie einfach, was Sie senden müssen und was Sie empfangen müssen, und das war's.

Auf Ihrer Exampe möchte ich dieses Setup machen:

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

Diese Anfrage gibt Daten in max. 0,01 Sekunden zurück

Ivijan Stefan Stipić
quelle
1
0,1 MICROseconds (1/1000 MILIseconds) ... Ich finde das schwer zu glauben.
Mark Tomlin
Ja. Ich habe einige Antworten in 0,02 ms, zum Beispiel die Überprüfung der Twilio API-Telefonnummer. Ist schnell.
Ivijan Stefan Stipić
4
0,02 ms = 20 Mikrosekunden; Sie sagten 0,1 Mikrosekunden, was nicht richtig sein kann.
Walf
2
Dies ist fast doppelt so schnell file_get_contents wie bei einigen API-Aufrufen zur Bestätigung. 0,8 Sekunden für file_get_contents& 0,49 Sekunden für curl(3 API-Aufrufe)
Jsp
1
Sie sollten Ihr eigenes Setup verwenden. Dann würden Ihre Anfragen von 1.4-1.9s auf 0.01s gehen;)
Rauli Rajande