首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >fopen no Authorization header with PHP 7

fopen no Authorization header with PHP 7
EN

Stack Overflow用户
提问于 2016-08-23 01:17:29
回答 1查看 1K关注 0票数 0

我有一些代码可以请求从Jive的API中获取数据。我在MAMP上运行这段代码,它允许我运行PHP 5.6.10或PHP 7.0.0。使用PHP5,我得到了一个成功的响应。使用PHP7,我得到了401未授权。

相关函数如下:

代码语言:javascript
复制
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调用在两个版本中产生相同的结果。我得到的回答是:

代码语言:javascript
复制
{
    "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版本不包含Authorization头

在PHP5.6.10和PHP7之间发生了什么变化导致了这种情况?我该如何修复它?

编辑:删除一些转移注意力的文本,并添加Request Bin result。

EN

回答 1

Stack Overflow用户

发布于 2016-08-23 02:39:31

以下是工作原理:

代码语言:javascript
复制
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
    );
  }

我现在将所有头文件存储在一个数组变量中,并将header属性设置为该数组变量。

我不是100%确定原因,但我认为这与变量引用有关。在代码的一次迭代中,var_dump用&符号标记了$http授权属性,而fopen忽略了这一点。另一次迭代移除了这个&符号,它起作用了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39085235

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档