У меня есть код, который делает запрос на выборку данных из API Jive. Я выполняю этот код на MAMP, что позволяет мне запускать либо PHP 5.6.10, либо PHP 7.0.0. С PHP5 я получаю успешный ответ. С PHP 7 я получаю 401 Unauthorized.
Соответствующая функция здесь:
protected function sendRequest($method, $url, $auth = null) {
global $CFG;
$options = func_num_args() === 4 ? func_get_arg(3) : array();
$http = array(
'max_redirects' => 0,
'request_fulluri' => 1,
'ignore_errors' => true,
'method' => $method,
'header' => array()
);
if (!is_null($auth)) {
array_push($http['header'], 'Authorization: ' . $auth);
}
if (($method === 'PUT' || $method === 'POST') && isset($options['content'])) {
$http['content'] = $options['content'];
array_push($http['header'], 'Content-length: ' . strlen($options['content']));
array_push($http['header'], 'Content-Type: application/json');
}
var_dump($http);echo('<hr/>');
$context = stream_context_create(array( 'http' => $http ));
var_dump(stream_context_get_options($context));echo('<hr/>');
$fp = fopen($url, 'rb', false, $context);
if (! $fp) {
throw new \Exception('Request failed: $php_errormsg');
}
$metadata = stream_get_meta_data($fp);
$content = stream_get_contents($fp);
$responseCode = (int)explode(' ', $metadata['wrapper_data'][0])[1];
fclose($fp);
return array (
'metadata' => $metadata,
'content' => $content,
'status' => $responseCode
);
}
Вызовы var_dump дают одинаковые результаты с обеими версиями PHP. Я получаю ответ:
{
"metadata": {
"wrapper_data": [
"HTTP/1.0 401 Unauthorized",
"Server: Apache",
"X-Jive-Request-Id: 6c433c20-688a-11e6-b332-005056a4250c",
"X-Jive-Flow-Id: 6c433c21-688a-11e6-b332-005056a4250c",
"X-Frame-Options: SAMEORIGIN",
"Expires: Mon, 22 Aug 2016 17:04:01 GMT",
"Cache-Control: no-store, no-cache, must-revalidate, private, max-age=0",
"X-JSL: D=1754 t=1471885441249342",
"Content-Type: text/plain",
"Date: Mon, 22 Aug 2016 17:04:01 GMT",
"Connection: close",
"Set-Cookie: jive.login.ts=1471885441250; Path=/; Secure; HttpOnly;HttpOnly",
"Set-Cookie: X-JCAPI-Token=pTVEn2P4; Path=/; Secure; HttpOnly",
"Set-Cookie: BIGipServerpool_sandbox.jiveon.com=25472522.20480.0000; path=/"],
"wrapper_type": "http",
"stream_type": "tcp_socket/ssl",
"mode": "rb",
"unread_bytes": 0,
"seekable": false,
"uri": "https://sandbox.jiveon.com/api/core/v3/activities?after=2016-08-22T17:01:14%2b0000&count=500",
"crypto": {
"protocol": "TLSv1",
"cipher_name": "ECDHE-RSA-AES256-SHA",
"cipher_bits": 256,
"cipher_version": "TLSv1/SSLv3"},
"timed_out": false,
"blocked": true,
"eof": false
},
"content": "",
"status": 401,
"success": false
}
Используя https://requestb.in Я вижу, что версия PHP7 не включает в себя заголовок авторизации
Что изменилось между PHP 5.6.10 и PHP 7, чтобы вызвать это? Как мне это исправить?
РЕДАКТИРОВАТЬ: Удалить текст красной сельди и добавить результат запроса корзины.
Следующие работы:
protected function sendRequest($method, $url, $auth = null) {
global $CFG;
$options = func_num_args() === 4 ? func_get_arg(3) : array();
$http = array(
'max_redirects' => 0,
'request_fulluri' => 1,
'ignore_errors' => true,
'method' => $method
);
$headers = array();
if (!is_null($auth)) {
array_push($headers, 'Authorization: ' . $auth);
}
if (($method === 'PUT' || $method === 'POST') && isset($options['content'])) {
$http['content'] = $options['content'];
array_push($headers, 'Content-length: ' . strlen($options['content']));
array_push($headers, 'Content-Type: application/json');
}
$http['header'] = $headers;
$context = stream_context_create(array( 'http' => $http ));
var_dump(stream_context_get_options($context));echo('<hr/>');
$fp = fopen($url, 'rb', false, $context);
if (! $fp) {
throw new \Exception('Request failed: $php_errormsg');
}
$metadata = stream_get_meta_data($fp);
$content = stream_get_contents($fp);
$responseCode = (int)explode(' ', $metadata['wrapper_data'][0])[1];
fclose($fp);
return array (
'metadata' => $metadata,
'content' => $content,
'status' => $responseCode
);
}
Теперь я храню все заголовки в переменной массива и устанавливаю для этого свойство заголовка.
Я не уверен на 100%, почему, но я думаю, что это как-то связано со ссылками на переменные. В одной итерации кода свойство авторизации $ http помечалось амперсандом с помощью var_dump, а fopen игнорировало его. Еще одна итерация, которая убрала этот амперсанд, сработала.
Других решений пока нет …