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 - это мощные сверла с каждым битом и опцией, о которых вы можете подумать.

Xeoncross
источник
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 .

vr_driver
источник
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 с;)
Раули Раджанде