php curl redirect follow

Following redirects with Curl in PHP.

As a good web citizen, I try to always follow redirects. Not just in my browser, where I actually don’t have all that much control over things, but also a consumer of web services.

When doing requests with CURL, redirects are not followed by default.

Assuming the given url actually redirects like this:

Curl will automatically just stop. To make it follow redirects, the FOLLOWLOCATION setting is needed, as such:

CURLOPT_FOLLOWLOCATION will follow the redirects up to 5 times (by default).

This is also the default behavior for browsers, but actually non-conforming with the HTTP standard, and also not desirable for consumers of web services.

To fix this, all you have to do is use CURLOPT_CUSTOMREQUEST instead of CURLOPT_POST :

Streams

After doing this, the secondary request will be a POST request as well. There’s one more issue though, if you were doing a POST or a PUT request you probably had a request body attached.

There’s two ways to supply a request body, as a string or as a stream. If we were uploading a file it makes much more sense to use a stream, because it unlike posting a string, a stream doesn’t have to be kept in memory.

For example, this is how we could upload a large file using POST.

This will work great, unless the target location redirects. If it does, curl will throw the following error:

This seems to be related to PHP bug #47204.

Basically this means that you cannot use CURLOPT_INFILE and CURLOPT_FOLLOWLOCATION together. There’s two alternatives:

Strings

Using CURLOPT_POSTFIELDS you can supply a request body as a string. Lets try to upload our earlier failed request using that method:

This also will not work exactly as you expect. While the second request to /someredirect will still be a POST request, it will be sent with an empty request body.

To fix this, use the undocumented CURLOPT_POSTREDIR option.

According to the PHP changelog, this was added in PHP 5.3.2, and according to PHP bug #49571 there are four possible values:

Web mentions

Comments

MeadSteve • Jul 23, 2013

I guess when you get a 301/308 it’d normally be worth logging something as well, for the maintainer of the code to take some action. Versus a 302/307 where you’d be happy for the code to do this silently.

Ed Dikotope • Nov 19, 2013

Best answer to my problem over the entire internet. Thank you very much.

Tom Binga • Mar 20, 2014

You helped solved a problem that’s been holding me back for a week or so now. Thank you!

Marcos Saturno • Jun 03, 2014

I’m still having problems when trying to write onto web HDFS (hadoop) from a PHP script. If I make a PUT request passing CREATE as a parameter, it will provide me a 307 temporary redirect, so i’d need to make a second PUT request to the new URL provided. I’m not able to follow it or at least slipt the redirect URL from the HTTP Response. Could you please help me with it?

I’m using something like:

Marcos Saturno • Jun 03, 2014

*I commented the //CURLOPT_PUT, but also tested with both on. 😉

Does your request not have a body? I wonder if that messes things up. You may want to PUT an empty string instead of nothing at all, because curl may fall back to ‘GET’ behavior (although with a PUT method).

Marcos Saturno • Jun 03, 2014

But actually I found some classes ready to use WEB HDFS:
https://github.com/simpleen.

Tx for the help, anyways!

Roger Qiu • Jun 08, 2014

I don’t feel secure knowing my request might be redirected to some place I don’t know.

Shanly • Jun 10, 2014

Awesome post! This solved my problem, thanks.

Arlanthir • Mar 06, 2015

Thank you for this.

Please can any one help me

richyrich • Apr 29, 2015

Thank you so much for this article, saved my time. All the best!

Источник

PHP: Following redirects with cURL.

This is a short guide on how to force PHP’s cURL functions to follow a HTTP redirect. By default, cURL will not follow any redirect headers that are sent by the server.

301 Moved.

If you send a cURL request that doesn’t follow redirects, you may end receiving the following response from the server:

301 Moved. The document has moved here.

Note that you might also receive a 302 header. This all depends on the server and the URL that you are sending a request to.

Take the following PHP example:

The above code will output “301 Moved” response because Google has a 301 redirect on the URL in question and our cURL client has not been configured to follow it.

PHP and the CURLOPT_FOLLOWLOCATION option.

This is where the CURLOPT_FOLLOWLOCATION option comes in useful. This option tells the cURL client that it should automatically follow any redirects specified in the “Location:” header. Hence the name “follow location”.

In PHP, you can use this option like so:

If you add the line above to our original code, you will see that our cURL client now follows Google’s 301 redirect.

Using the CURLOPT_MAXREDIRS option.

If your cURL client follows redirects, then it is a good idea to also use the CURLOPT_MAXREDIRS option. This allows us to specify the maximum number of redirects that we should follow before stopping. If we do not set this option, then a simple server misconfiguration could kill our client by sending it too many redirect headers. The CURLOPT_FOLLOWLOCATION option is recursive, which means that you could get stuck in an endless redirect loop.

An example using PHP:

The PHP code above tells cURL that it should only follow 3 redirects. If a 4th redirect is encountered, a “CURLE_TOO_MANY_REDIRECTS” error will be thrown.

Источник

PHP cURL: Get target of redirect, without following it

The curl_getinfo function returns a lot of metadata about the result of an HTTP request. However, for some reason it doesn’t include the bit of information I want at the moment, which is the target URL if the request returns an HTTP redirection code.

I’m not using CURLOPT_FOLLOWLOCATION because I want to handle specific redirect codes as special cases.

If cURL can follow redirects, why can’t it tell me what they redirect to when it isn’t following them?

Of course, I could set the CURLOPT_HEADER flag and pick out the Location header. But is there a more efficient way?

5 Answers 5

This can be done in 4 steps:

Step 1. Initialise curl

Step 3. Check if you have the correct response code

Step 4. Parse the headers to get the new URL

Once you have the new URL you can then repeat steps 2-4 as often as you like.

php curl redirect follow. Смотреть фото php curl redirect follow. Смотреть картинку php curl redirect follow. Картинка про php curl redirect follow. Фото php curl redirect follow

You can simply use it: (CURLINFO_REDIRECT_URL)

as you mentioned, disable the CURLOPT_FOLLOWLOCATION option (before executing) and place my code after executing.

php curl redirect follow. Смотреть фото php curl redirect follow. Смотреть картинку php curl redirect follow. Картинка про php curl redirect follow. Фото php curl redirect follow

curl doesn’t seem to have a function or option to get the redirect target, it can be extracted using various techniques:

From the response:

Apache can respond with a HTML page in case of a 301 redirect (Doesn’t seem to be the case with 302’s).

If the response has a format similar to:

You can extract the redirect URL using DOMXPath :

Using CURLOPT_NOBODY

Using a regex the target URL can be extracted from the header:

Источник

Php curl redirect follow

PHP поддерживает libcurl, библиотеку, созданную Daniel»ом Stenberg»ом, которая даёт возможность соединяться с серверами различных типов и по разным протоколам.
libcurl в настоящее время поддерживает протоколы http, https, ftp, gopher, telnet, dict, file и ldap.
libcurl также поддерживает сертификаты HTTPS, HTTP POST, HTTP PUT, загрузку по FTP (это можно сделать также РНР-расширением ftp), загрузку на основе форм HTTP, прокси, куки и аутентификацию user+password.

Эти функции были введены в PHP 4.0.2.

curl_init

Описание

resource curl_init([string url])

Функция curl_init() инициализирует новую сессию и возвратит CURL-дескриптор для использования в функциях curl_setopt(), curl_exec() и curl_close(). Если необязательный параметр url предоставлен, то опция CURLOPT_URL получит значение этого параметра. Вы можете вручную устанавливать его с помощью функции curl_setopt().

curl_setopt

Описание

bool curl_setopt (resource ch, string option, mixed value)

Функция curl_setopt() устанавливает опции для CURL-сессии, идентифицируемой параметром ch. Параметр option является опцией, которую вы хотите установить, а value это значение опции option.

Параметр value должен быть long для следующих опций (специфицированных параметром option):

Параметр value должен быть строкой для следующих значений параметра option:

Следующие опции ожидают дескриптора файла, который получается с помощью функции fopen():

Параметр value должен быть функцией следующего вида long write_callback (resource ch, string data) для следующих значений параметра option:

Параметр value должен быть функцией следующего вида string read_callback (resource ch, resource fd, long length)<> для следующих значений параметра option:

Источник

cURL в PHP: примеры POST, GET запросов с headers, cookie, JSON и многопоточностью

В этой статье мы рассмотрим эффективные приемы работы с cURL, отправление POST, GET и т.д. запросов, работу с cookie, заголовки, JSON а также в конце статьи будут некоторые полезные инструменты, которые могут значительно облегчить вам работу с HTTP запросами.

GET запрос при помощи cURL

Для того, чтобы отправить запрос, нужно создать объект при помощи функции curl_init(), а затем следует настроить его.

Все настройки, которые вы можете найти по этой ссылке. Там вы найдете опции, которые мы будем устанавливать функцией curl_setopt, в дальнейших примерах.

Пример простого GET запроса при помощи cURL:

Если в результате сервер вернет нам редирект, то мы по нему автоматически не перейдем. А иногда это бывает полезно. Чтобы cURL автоматически шел по редиректу нужно установить опцию CURLOPT_FOLLOWLOCATION.

С установленной опцией скрипт автоматически перейдет по вернувшемуся редиректу и вернет ответ уже с итоговой страницы.

POST запрос при помощи cURL

Теперь давайте отправим post запрос на адрес https://httpbin.org/anything

Отлично, с GET и POST запросами в cURL мы немного освоились. Теперь разберемся с заголовками, которые мы можем отсылать в запросе.

Заголовки устанавливаются при помощи опции CURLOPT_HTTPHEADER Чтобы получше узнать, для чего нужна эта опция давайте попробуем отправить POST запрос в формате JSON

cURL: POST запрос в формате JSON

Отличия конфигурации JSON запроса от обычного POST запроса заключается в том, что мы кодируем поля при помощи json_encode() И добавляем заголовок Content-Type: application/json

cURL: GET запрос в формате JSON

GET запрос в формате JSON отправляется так же как и POST запрос, просто нужно CURLOPT_CUSTOMREQUEST установить в ‘GET’

cURL и другие виды HTTP запросов: PUT, DELETE, HEAD, PATCH, OPTIONS, CONNECT и т.д.

Стоп, Дмитрий, прекрати выдумывать виды запросов!

Ничего я не выдумываю: HTTP протокол предполагает множество типов HTTP запросов просто POST и GET являются более распространенными.

Чтобы отправить PUT запрос, нужно установить опцию CURLOPT_PUT таким образом:

Это делается по тому же принципу, как и CURLOPT_POST. Но что делать с остальным зоопарком запросов? Разве у cURL есть CURLOPT_DELETE или CURLOPT_HEAD? Нет.

Для того, чтобы отправлять другие виды запросов есть другая опция: CURLOPT_CUSTOMREQUEST

Вместо строки curl_setopt($curl, CURLOPT_POST, true); мы явно задаем имя запроса опцией CURLOPT_CUSTOMREQUEST:

Замечание: Не используйте эту возможность пока не убедитесь, что сервер поддерживает данный тип запроса.

Как получить заголовки ответа

В предыдущем примере мы научились посылать заголовки. Самый правильный способ принять заголовки:

Иногда можно встретить другой вариант получения заголовков ответа. К сожалению, они не совсем правильные и могут работать некорректно в некоторых случаях.

Рассмотрим такой пример:

Мы сначала определяем размер заголовка, с помощью CURLINFO_HEADER_SIZE затем вырезаем его из ответа. К сожалению, это может не срабатывать, когда используется прокси или в некоторых случаях редиректа.

Скачивание больших файлов с помощью cURL

Для того, чтобы скачать большой файл пригодится этот способ:

Обратите внимание, если вы будете использовать file_get_contents для скачивания файлов, то файл сначала загружается в оперативную память, а потом сохраняется на диск. Поэтому если файл действительно большой, то скорее всего вашему серверу не хватит памяти. Также к памяти будет требователен следующий код:

Здесь мы скачиваем файл при помощи cURL в оперативную память, а затем сохраняем его на диск. Не смотря на то, что этот способ не годится для скачивания больших файлов, с помощью него можно вполне сохранить простую веб страницу.

Параллельные cURL запросы в PHP

Для чего могут потребоваться многопоточные запросы? Например у нас есть много URL адресов:

И если мы будем по очереди отправлять запросы, то второй запрос начнется только после того, как закончился первый и так далее, а это существенно увеличивает время работы скрипта.

Как выполнить 3 запроса одновременно? В этом нам поможет curl_multi_

Давайте решим конкретную задачу при помощи параллельных curl запросов. Нам нужно отправить одновременно 3 запроса.

Такие параллельные запросы выполняются значительно быстрее чем поочередные.

cURL запросы с сохранением и загрузкой cookie из файла

cURL позволяет нам установить cookie при передачи запросов, а также автоматически принимать и устанавливать cookie, которые нам возвращает сервер, сохраняя их между запросами.

Давайте рассмотрим такой пример:

Теперь cookie у нас хранятся в файле cookie.txt в директории со скриптом (если вы ничего не меняли). Если мы совершаем повторные запросы, то cURL автоматически берет и отправляет cookie на сервер, как и обычный браузер. Таким образом мы можем авторизироваться на сайте и сохранить сеанс между запросами.

Передача cookie без файлов

Иммитация браузера с помощью cURL

Иногда сайт, к которому мы обращаемся может фильтровать запросы, защищаясь от парсинга. Если для этого используются упрощенные способы защиты, например проверка User-Agent, то мы можем легко притвориться, что являемся реальным польователем, который взаимодействует с сайтом через браузер, мы можем послать заголовки и cookie, которые обычно посылает браузер.

В данном примере установлены заголовки, которые посылает Chrome.

В простых ситуациях этого хватает. Но если используется защита при помощи javascript или что-то более продвинутое, то здесь cURL бессилен, и следует использовать либо BAS либо Zennoposter. Либо если вы хотите попытать счастье с PHP, то Selenium.

Не используйте эти знания в противоправных целях.

cURL запросы через прокси

Простой пример для отправки запросов через proxy. Если ваш прокси предполагает авторизацию, то раскомментируйте соответствующие строчки.

Отправка файлов

Авторизация с помощью cURL

HTTP Авторизация

Чтобы с помощью cURL авторизироваться на сайте, который использует Basic HTTP-аутентификацию нужно установить опцию CURLOPT_USERPWD, в которой будет наш логин и пароль.

OAuth авторизация

Авторизация через форму

Давайте применим полученные нами знания и авторизируемся на каком-нибудь сайте. Для этого нужно посмотреть куда форма отправляет данные и отправить туда то же самое.

Допустим на сайте есть такая форма:

Тогда наш cURL запрос должен быть сформирован так:

Автоматическое построение запросов

Перевод консольной команды curl в PHP

И вот еще один сервис, который переводит консольную команду curl в PHP: https://incarnate.github.io/curl-to-php/

Так вы можете создать простые запросы на cURL в PHP не создавая их вручную.

Лайфхак

В консоли браузера, во вкладке сеть, вы можете кликнуть правой кнопкой мыши и скопировать любой запрос в виде команды cURL, а потом с помощью сервиса curl-to-php перевести запрос в PHP. Теперь вы вообще можете сконвертировать в cURL абсолютно любой запрос, который посылает ваш браузер.

Как работать с cURL гораздо проще

Вы можете спросить: почему у cURL такие кривые и страшные методы? У вас может возникнуть желание взять и создать обертку для работы с cURL, чтобы вы могли не писать каждый раз большие куски некрасивого кода, а писать все проще, например так:

К счастью, такая обертка уже написана и найти ее можно здесь: https://github.com/php-curl-class/php-curl-class

Просто установите ее при помощи: composer require php-curl-class/php-curl-class и не работайте с кривыми кусками кода, которые таковы вероятно потому, что cURL изначально консольное приложение.

POST и GET запросы без cURL

С помощью PHP мы можем отправить простой GET запрос используя функцию file_get_contents.

При помощи file_get_contents мы также можем отправить POST запрос.

Подробнее о том, какие опции можно передавать в stream_context_create, вы можете изучить здесь: http://docs.php.net/manual/ru/context.http.php

Другие инструменты для работы с запросами в PHP

Для работы с запросами есть еще более мощный инструмент: Guzzle

Несколько примеров на Guzzle

GET запросы на Guzzle

Разные типы запросов на Guzzle

Асинхронные запросы на Guzzle

Если интересно, то читайте: Guzzle Quick Start

Пишите комментарии, если что-то осталось не понятно.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *