PHP cURL vs file_get_contents


111

Чим ці дві частини коду відрізняються під час доступу до API REST?

$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 - це powerdrills з кожним бітом і можливим варіантом.


17
Щоб залишитись у цій метафорі, зауважте, що CURL - це силовий дриль із складним патроном, який вимагає, щоб ви знали це досить добре, щоб насправді змінити його (читайте: налаштування параметрів CURL трохи стомлююче, але дозволяє робити все, що завгодно).
ткнути

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

Так чи інакше, наш код зараз працює з завитком .


9
Так, file_get_contentsвимагає allow_url_fopenбути правдою.
Коста

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

15
@frustratedtech Що це за "подвиги"?
rdlowrey

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/100 мілілісекунд) ... Мені важко повірити.
Марк Томлін

Так. У мене є відповіді за 0,02 мс, наприклад перевірка номеру телефону Twilio API. Швидкий.
Івіджан Стефан Стипіч

4
0,02 мс = 20 мікросекунд; ви сказали 0,1 мікросекунди, що не може бути правильним.
Уолф

2
Це майже вдвічі швидше порівняно з тим, що file_get_contents я щойно робив кілька дзвінків API для підтвердження. 0,8 секунди за file_get_contents0,49 секунди curl(3 виклики API)
Jsp

1
Ви повинні використовувати власну установку. Тоді ваші запити перейдуть від 1,4-1,9s до 0,01s;)
Rauli Rajande
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.