
Бывает так что сервер перенаправляет на другой URL. Например Google, если перейти на https://google.com c IP из РФ он делает 302-й редирект на https://www.google.ru.
Чтобы CURL сам переходил на новый URL, нужно добавить параметр:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
PHP
Но если он не помогает, то можно применить функцию:
function curl_redir_exec($ch)
{
static $curl_loops = 0;
static $curl_max_loops = 20;
if ($curl_loops >= $curl_max_loops) {
$curl_loops = 0;
return false;
}
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
$dd = explode("rnrn", $data); // или $dd = explode("rn", $data);
$header = $dd[0];
$data = @$dd[1];
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code == 301 || $http_code == 302) {
$matches = array();
preg_match('/Location:(.*?)n/', $header, $matches);
$url = @parse_url(trim(array_pop($matches)));
if (!$url) {
$curl_loops = 0;
return $data;
}
$last_url = parse_url(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
if (empty($url['scheme'])) {
$url['scheme'] = $last_url['scheme'];
}
if (empty($url['host'])) {
$url['host'] = $last_url['host'];
}
if (empty($url['path'])) {
$url['path'] = $last_url['path'];
}
$new_url = $url['scheme'] . '://' . $url['host'] . $url['path'] . ($url['query'] ? '?' . $url['query'] : '');
curl_setopt($ch, CURLOPT_URL, $new_url);
return curl_redir_exec($ch);
} else {
$curl_loops = 0;
return $data;
}
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://google.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
$html = curl_redir_exec($ch);
curl_close($ch);
echo $html;
PHP
Я получил сообщение об ошибке 302 при запросе URL через PHP curl_exec, но получил код 200, когда это делается вручную. Какая может быть разница, которая отличает результат?
Предположим, у меня есть следующий код на сервере:
$url = "http://localhost/circle/my_request/susan?confirm_key=c429d674e36ffe1a4f87fd5a17a0200dcfff0884e8bb3801d2a7d559dcc8d8cd1416295160";
$ch = @curl_init($url);
@curl_setopt($ch, CURLOPT_HEADER, true);
@curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
@curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; Circle)");
@curl_setopt($ch, CURLOPT_TIMEOUT,60);
$s = @curl_exec($ch);
$curl_info = @curl_getinfo($ch);
$http_code = $curl_info['http_code'];
В этом случае $ http_code == 302 или запрошенный URL-адрес перенаправляется. Но когда я поместил URL-адрес в браузер вручную, он не сделал перенаправление и взял меня в нужное место.
Я что-то пропустил? Почему эти 2 запроса получаются по-разному?
заранее спасибо
————Дополнительная информация—-
Привет, я перезапустил скрипт с параметром CURLOPT_FOLLOWLOCATION, установленным в true, и я получил следующий вывод:
HTTP/1.1 302 Found Date: Tue, 18 Nov 2014 14:36:37
GMT Server: Apache/2.4.4 (Win64)
PHP/5.4.12 X-Powered-By: PHP/5.4.12
Set-Cookie: PHPSESSID=92t2db5qalq4ajie0ols03hik6;
path=/; HttpOnly Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate,
post-check=0, pre-check=0 Pragma: no-cache X-Account-Management-Status: none
Location: http://somehost.com/circle Content-Length: 0
Content-Type: text/html HTTP/1.1
301 Moved Permanently Date: Tue, 18 Nov 2014 14:36:37
GMT Server: Apache/2.4.4 (Win64)
PHP/5.4.12 Location: http://somehost.com/circle/
Content-Length: 232 Content-Type: text/html;
charset=iso-8859-1 HTTP/1.1 200 OK Date: Tue,
18 Nov 2014 14:36:37 GMT Server: Apache/2.4.4 (Win64)
PHP/5.4.12 X-Powered-By: PHP/5.4.12
Set-Cookie: PHPSESSID=hk02sg1327eq78khbka0sf6pk6;
path=/; HttpOnly Expires: Thu, 19 Nov 1981 08:52:00
GMT Cache-Control: no-store, no-cache, must-revalidate,
post-check=0, pre-check=0 Pragma: no-cache X-Account-Management-Status: none
Transfer-Encoding: chunked Content-Type: text/html; charset=utf-8
Я не уверен, что это говорит, но я предполагаю, что это было перенаправлено на http://somehost.com/circle затем к http://somehost.com/circle. Это правильно?
0
Решение
Может быть использование сценария перенаправления для проверки куки или других функций.
-
Вы можете увидеть URL перенаправления в
$sвыход. Просто вставьтеecho $s;до конца вашего сценария. -
Также вы можете установить CURLOPT_FOLLOWLOCATION, и тогда curl будет переворачиваться при перенаправлении в автоматическом режиме.
5
Другие решения
Других решений пока нет …
- Главная
- Новости
- Web
- PHP
- JavaScript
- HTML и CSS
- MySQL
- Apache
- Домены
- Заработок
- SEO
- Разное
- ОС
- FreeBSD
- RouterOS
- Windows
- Linux
- Утилиты
- Git
- Редакторы
- Hardware
- Микроконтроллеры Arduino
- Справочники
- Стандарты и справочники
- Счета оплаты ЕСВ
- Здоровье
- Строительство и ремонт
- Авто
- Налогообложение
- Разное
- Веселые картинки
- Whois доменов
- Обратная связь
Главная / Web / PHP / PHP, cURL и переадресация
В идеале, для того, чтобы cURL в PHP автоматичесски «отлавливал» переадресацию по HTTP-заголовку 301 или 302, следует использовать константу CURLOPT_FOLLOWLOCATION, но на практике, как часто это бывает, все не так просто. В случае использования safe_mode или open_basedir php огорчает такой ошибкой: Warning: curl_setopt() : CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set in … Поскольку safe_mode, а особенно, open_basedir используются весьма часто, и возможности их отключить зачастую нет, необходимо использовать обходные пути.
Для начала следует принять заголовки, отдаваемые сервером. Реализуется это так — PHP-скрипт ниже:
Чтение заголовков ответа сервера cURL
$ch = curl_init(‘http://yandex.ru’);
curl_setopt($ch, CURLOPT_HEADER, 1); // Отображать в ответе заголовки
curl_setopt($ch, CURLOPT_NOBODY, 1); // Неотображать текст самой страницы
$header = curl_exec($ch);
curl_close($ch);
echo $header;
Изучив заголовки, полученные в ответе при помощи cURL, находим Location — это и будет адрес перенаправления.
Заголовки, полученные от сервера
HTTP/1.1 301 Moved Permanently
Date: Sun, 10 Jul 2011 01:05:45 GMT
Server: Apache/2.2.9 (Unix) mod_perl/2.0.4 Perl/v5.12.1
Location: http://www.yandex.ru/
Vary: Accept-Encoding
Connection: close
Content-Type: text/html; charset=iso-8859-1
Первоначально, Яндекс пересылает всех посетителей, с адреса без www на адрес с www.
Чтобы автоматически переходить по всем редиректам (с защитой от зацикливания), можно использовать код на PHP c cURL и функцию, опубликованную ниже.
Обнаружение URL переадресации и переход по ним с помощью cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, ‘http://yandex.ru’);
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // Сколько сек. ждать ответ сервреа
$page = curl_redir_exec($ch);
$page = curl_exec($ch);
curl_close($ch);
echo $page;
function curl_redir_exec($ch)
{
static $curl_loops = 0;
static $curl_max_loops = 20;
if ($curl_loops >= $curl_max_loops)
{
$curl_loops = 0;
return false;
}
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
list($header, $data) = explode(«nn«, $data, 2);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code == 301 || $http_code == 302)
{
$matches = array();
preg_match(‘/Location:(.*?)n/’, $header, $matches);
$url = @parse_url(trim(array_pop($matches)));
if (!$url)
{
$curl_loops = 0;
return $data;
}
$last_url = parse_url(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
if (!$url[‘scheme’])
$url[‘scheme’] = $last_url[‘scheme’];
if (!$url[‘host’])
$url[‘host’] = $last_url[‘host’];
if (!$url[‘path’])
$url[‘path’] = $last_url[‘path’];
$new_url = $url[‘scheme’] . ‘://’ . $url[‘host’] . $url[‘path’] . ($url[‘query’]?‘?’.$url[‘query’]:»);
echo $new_url.‘ — ‘.$http_code.‘<br>’;
curl_setopt($ch, CURLOPT_URL, $new_url);
return curl_redir_exec($ch);
}
else
{
$curl_loops = 0;
return $data;
}
}
Этот скрипт php является готовым решением для перехода по редиректам с помощью cURL.
Опубликовано: 2011/07/10
HTML-код ссылки на эту страницу:
<a href=»https://petrenco.com/php.php?txt=72″ target=»_blank»>PHP, cURL и переадресация</a>
30740