PHP cURL vs file_get_contents

111

Czym te dwa fragmenty kodu różnią się podczas uzyskiwania dostępu do interfejsu API REST?

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

i

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

Sądząc po obu, dają ten sam rezultat

print_r(json_decode($result))
Salvador Dali
źródło
2
cURLjest w stanie znacznie więcej niż file_get_contents. To powinno wystarczyć.
18
FWIW nie ma dużej różnicy w szybkości. Właśnie zakończyłem pobieranie 5000 adresów URL i zapisywanie ich kodu HTML do plików (około 200 KB na plik). Zrobiłem w połowie z curl, a w połowie z file_get_contents jako eksperymentem i nie było zauważalnej różnicy.
David Gilbertson
8
Możliwe jest wysyłanie danych postu za pomocą file_get_contents, o ile używasz wersji obsługującej kontekst strumienia.
Chris Strickland

Odpowiedzi:

129

file_get_contents()to prosty śrubokręt. Doskonały do ​​prostych żądań GET, w których nagłówek, metoda żądania HTTP, limit czasu, cookiejar, przekierowania i inne ważne rzeczy nie mają znaczenia.

fopen()z kontekstem strumienia lub cURL z setopt to powerdrills z każdym bitem i opcją, o której możesz pomyśleć.

Xeoncross
źródło
17
Aby pozostać w ramach tej metafory, zauważ, że cURL to wiertarka ze skomplikowanym uchwytem wiertarskim, która wymaga dość dobrej znajomości go, aby go zmienić (czytaj: ustawianie opcji cURL jest nieco żmudne, ale pozwala robić wszystko, co chcesz).
poke
20
file_get_contentspozwala także na ustawienie kontekstu, co oznacza, że ​​możesz dowolnie ustawić pola nagłówka.
velop
4
a jako dodatek do komentarza @ velop, poprzez kontekst strumienia można również wysłać POST, PUT, uwierzytelnianie, nagłówki, zawartość, proxy i wiele więcej za pomocą jednego żądania file_get_contents
Markus Köhler
@velop: Tak. I metoda też. I przekierowania. I timeout ... php.net/manual/en/context.http.php
Sz.
25

Oprócz tego, z powodu niedawnych włamań do witryn internetowych, musieliśmy bardziej zabezpieczyć nasze witryny. Robiąc to, odkryliśmy, że file_get_contents nie działa, a curl nadal będzie działać.

Nie w 100%, ale uważam, że to ustawienie php.ini mogło blokować żądanie file_get_contents .

; Disable allow_url_fopen for security reasons
allow_url_fopen = 0

Tak czy inaczej, nasz kod działa teraz z curl .

vr_driver
źródło
9
Tak, file_get_contentswymaga allow_url_fopenprawdy.
Costa
2
Tak, wiele firm hostingowych wyłącza file_get_contents()tę funkcję z powodu wielu exploitów, o których wiadomo, że korzystają z tej funkcji. cURL to funkcja, której ludzie powinni teraz używać w kodzie.
frustratedtech
15
@frustratedtech Co to są „exploity”?
rdlowrey
3
Firmy hostingowe wyłączają się, allow_url_fopenponieważ mylą to allow_url_include. allow_url_fopeni file_get_contentssą w porządku.
fritzmg
2
@vr_driver te linki nie mają nic wspólnego zfile_get_contents()
rdlowrey
19

To stary temat, ale w moim ostatnim teście na jednym z moich API cURL jest szybszy i stabilniejszy. Czasami file_get_contents przy większym żądaniu potrzebuje ponad 5 sekund, gdy cURL potrzebuje tylko od 1,4 do 1,9 sekundy, co jest dwukrotnie szybsze.

Muszę dodać jedną notatkę na ten temat, że po prostu wysyłam GET i odbieram zawartość JSON. Jeśli poprawnie skonfigurujesz cURL, uzyskasz świetną odpowiedź. Po prostu „powiedz”, aby zakreślić, co chcesz wysłać, a co chcesz odebrać i to wszystko.

Na twoim przykładzie chciałbym zrobić taką konfigurację:

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

To żądanie zwróci dane w ciągu maksymalnie 0,01 sekundy

Ivijan Stefan Stipić
źródło
1
0,1 MICROsekundy (1/1000 milisekund) ... Trudno mi w to uwierzyć.
Mark Tomlin,
Tak. Mam kilka odpowiedzi w 0,02 ms, na przykład sprawdzenie numeru telefonu w Twilio API. Jest szybki.
Ivijan Stefan Stipić,
4
0,02 ms = 20 mikrosekund; powiedziałeś 0,1 mikrosekundy, co nie może być poprawne.
Walf
2
Jest to prawie dwa razy szybsze w porównaniu z tym, file_get_contents że właśnie wykonałem kilka wywołań API w celu potwierdzenia. 0,8 sekundy dla file_get_contentsi 0,49 sekundy dla curl(3 wywołania API)
Jsp,
1
Powinieneś użyć własnej konfiguracji. Wtedy twoje zapytania będą trwały od 1,4-1,9 do 0,01 s;)
Rauli Rajande