PHP скрипт больше не получает данные из потока контекста - PullRequest
3 голосов
/ 29 мая 2020

У нас есть "устаревший" скрипт, который некоторое время назад перестал работать. Совершенно уверен, что это потому, что конечная точка, к которой он подключается, изменилась с http на https, а старый адрес http теперь возвращает 301.

Я никогда не делал ничего, кроме крошечных изменений в сценариях PHP, поэтому я немного из моей глубины здесь.

Обратите внимание, что наша версия PHP старая - 5.3.0. Это вполне может быть частью проблемы.

Скрипт как есть (в любом случае соответствующий бит):

$uri = "http://www.imf.org/external/np/fin/data/rms_mth.aspx"
     ."?SelectDate=$date&reportType=CVSDR&tsvflag=Y";
$opts = array('http' => array(
                 'proxy' => 'tcp://internal.proxy.address:port',
                 'method' => 'GET',
                 'request_fulluri' => true)
              );
$ctx = stream_context_create($opts);
$lines = file($uri, false, $ctx);
foreach ($lines as $line)
...

Это больше ничего не возвращает. Эта ссылка, кстати, является ссылкой МВФ для обменных курсов, так что она открыта для всех - если вы откроете ее, вы получите загрузку с таблицей курсов. Остальная часть скрипта в основном анализирует это на предмет необходимых нам данных.

Теперь мы почти уверены, что наш прокси в порядке. Выполнение некоторых тестов с помощью curl дает следующие результаты:

curl --proxy tcp://internal.proxy.address:port -v https://www.imf.org/external/np/fin/data/rms_mth.aspx?SelectDate=05/28/2020&reportType=CVSDR&tsvflag=Y

(укажите https) работает нормально.

curl --proxy tcp://internal.proxy.address:port -v http://www.imf.org/external/np/fin/data/rms_mth.aspx?SelectDate=05/28/2020&reportType=CVSDR&tsvflag=Y

(укажите http) не работает и показывает ошибку 301

curl --proxy tcp://internal.proxy.address:port -v -L http://www.imf.org/external/np/fin/data/rms_mth.aspx?SelectDate=05/28/2020&reportType=CVSDR&tsvflag=Y

(укажите http со следующими перенаправлениями), затем работает нормально.

Я попробовал кое-что после того, как погуглил. Кажется, мне нужно выбрать ssl при использовании https. Итак, я внес следующие изменения:

$uri = "https://www.imf.org/external/np/fin/data/rms_mth.aspx"
     ."?SelectDate=$date&reportType=CVSDR&tsvflag=Y";
$opts = array('http' => array(
                 'proxy' => 'tcp://internal.proxy.address:port',
                 'method' => 'GET',
                 'request_fulluri' => true),
              'ssl' => array(
                 'verify_peer' => false,
                 'verify_peer_name' => false,
                 'SNI_enabled' => false)
              );

К сожалению, флаг SNI_enabled был введен после версии 5.3.0, поэтому я не думаю, что это помогает. Также есть опция контекста follow_location для http, но она была введена в 5.3.4, поэтому тоже бесполезна.

(Кстати, я практически не контролирую версию PHP, которая у нас есть, поэтому, хотя я ценю, что более высокие версии могут предлагать лучшие решения, я боюсь, что это не очень полезно для меня).

В принципе, я сейчас застрял. Никакая комбинация этих параметров или настроек не возвращает никаких данных. Я вижу, что он работает через curl и прокси, так что это не общая проблема с подключением.

Все предложения с благодарностью получены!

Обновление: после добавления строк для включения отчетов об ошибках код ошибки для потока, соединяющегося:

Warning: file(https://www.imf.org/external/np/fin/data/rms_mth.aspx?SelectDate=05/28/2020&reportType=CVSDR&tsvflag=Y): failed to open stream: Cannot connect to HTTPS server through proxy in /usr/bass/apps/htdocs/BASS/mods/module.XSM.php on line 79

(строка 79 - это строка $lines = ...)

Таким образом, он не подключается в сценарии php, но запуск того же подключения через прокси-сервер в curl работает нормально. Какая разница в php, которая вызывает это?

1 Ответ

1 голос
/ 30 мая 2020

Вы можете использовать php функции curl, чтобы получить ответ с вашего заданного URL. А затем вы можете использовать функцию explode(), чтобы разбить ответ построчно.

$uri = "https://www.imf.org/external/np/fin/data/rms_mth.aspx"
     ."?SelectDate=$date&reportType=CVSDR&tsvflag=Y";

$opts = array(
    CURLOPT_URL            => $uri,
    CURLOPT_PROXY          => 'tcp://internal.proxy.address:port',
    CURLOPT_HEADER         => false,
    CURLOPT_RETURNTRANSFER => true
);

$ch = curl_init();
curl_setopt_array($ch, $opts);
$lines = curl_exec($ch);
curl_close($ch);

$lines = explode("\n", $lines);    // breaking the whole response string line by line

foreach ($lines as $line)
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...