PHP cURL против file_get_contents


111

Чем отличаются эти два фрагмента кода при доступе к REST API?

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

и

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

Оба дают одинаковый результат, судя по

print_r(json_decode($result))

2
cURLспособен на большее, чем file_get_contents. Этого должно быть достаточно.

18
FWIW есть небольшая разница в скорости. Я только что закончил получение 5000 URL-адресов и сохранение их HTML в файлы (около 200 КБ на файл). Я сделал половину с помощью curl и половину с file_get_contents в качестве эксперимента, и заметной разницы не было.
Дэвид Гилбертсон

8
Можно отправлять данные публикации с file_get_contents, если вы используете версию, поддерживающую контекст потока.
Крис Стрикленд

Ответы:


129

file_get_contents()простая отвертка. Отлично подходит для простых запросов GET, где заголовок, метод HTTP-запроса, тайм-аут, cookiejar, перенаправления и другие важные вещи не имеют значения.

fopen()с контекстом потока или cURL с setopt - это мощные сверла с каждым битом и опцией, о которых вы можете подумать.


17
Чтобы оставаться в рамках этой метафоры, обратите внимание, что cURL - это мощная дрель со сложным сверлильным патроном, который требует от вас достаточно хороших знаний, чтобы фактически изменить его (читайте: установка параметров cURL немного утомительна, но позволяет делать все, что вы хотите).
poke

20
file_get_contentsпозволяет также установить контекст, что означает, что вы можете установить поля заголовка по своему усмотрению.
velop

4
и в дополнение к комментарию @ velop, через контекст потока также можно отправлять POST, PUT, аутентификацию, заголовки, контент, прокси и многое другое с помощью одного запроса file_get_contents
Маркус Кёлер

@velop: Да. И метод тоже. И перенаправляет. И тайм-аут ... php.net/manual/en/context.http.php
Sz.

25

Вдобавок к этому из-за недавних взломов веб-сайтов нам пришлось больше защищать наши сайты. При этом мы обнаружили, что file_get_contents не работает, тогда как curl все еще будет работать.

Не на 100%, но я считаю, что этот параметр php.ini мог блокировать запрос file_get_contents .

; Disable allow_url_fopen for security reasons
allow_url_fopen = 0

В любом случае наш код теперь работает с curl .


9
Да, file_get_contentsтребует allow_url_fopenправды.
Costa

2
Да, многие хостинговые компании отключают их file_get_contents()из-за множества эксплойтов, которые, как известно, используют эту функцию. cURL - это функция, которую люди теперь должны использовать в коде.
frustratedtech

15
@frustratedtech Что это за «эксплойты»?
rdlowrey 02

3
Хостинговые компании отключают его, allow_url_fopenпотому что ошибочно принимают его за allow_url_include. allow_url_fopenи file_get_contentsих можно использовать.
fritzmg

2
@vr_driver, эти ссылки не имеют ничего общегоfile_get_contents()
rdlowrey

19

Это старая тема, но в моем последнем тесте на одном моем API cURL был быстрее и стабильнее. Иногда file_get_contents для большего запроса требуется более 5 секунд, тогда как cURL требуется всего от 1,4 до 1,9 секунды, что вдвое быстрее.

Мне нужно добавить одно примечание по этому поводу, что я просто отправляю GET и получаю содержимое JSON. Если вы правильно настроите cURL, у вас будет отличный ответ. Просто «скажите» cURL, что вам нужно отправить и что вам нужно получить, и все.

На вашем экзамене я хотел бы сделать такую ​​настройку:

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

Этот запрос вернет данные за 0,01 секунды максимум.


1
0,1 МИКРОсекунды (1/1000 милисекунд) ... Мне трудно в это поверить.
Марк Томлин

Да. У меня есть ответы через 0,02 мс, например, проверка номера телефона Twilio API. Быстро.
Ивьян Стефан Стипич

4
0,02 мс = 20 микросекунд; Вы сказали 0,1 микросекунды, что не может быть правдой.
Walf

2
Это почти в два раза быстрее, чем file_get_contents я сделал несколько вызовов API для подтверждения. 0,8 секунды для file_get_contents& 0,49 секунды для curl(3 вызова API)
Jsp

1
Вы должны использовать свою собственную настройку. Тогда ваши запросы изменятся с 1,4–1,9 до 0,01 с;)
Раули Раджанде
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.