我使用curl模拟Http Post请求,并在请求中加入了自定义的header,但我在服务端死活获取不到这个header(sign和Authorization),使用的Apache服务器,各位大神看看问题出在哪里,代码如下:
client.php
<?php
header('Content-type: text/json;charset=utf-8');
$url="http://127.0.0.1/server1.php";
$post=true;$body=array(
    "mobile" => "13600000000",
    "exp" => time()
);
$body_json = json_encode($body);$header=array(
    "sign" => "signature",
    "Authorization" => "OH key:signature"
);$ch = curl_init();
//参数设置
$res= curl_setopt ($ch, CURLOPT_URL,$url);curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_NOBODY, TRUE);
curl_setopt($ch, CURLOPT_POST, TRUE);if($post)
    curl_setopt($ch, CURLOPT_POSTFIELDS, $body_json);curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch,CURLOPT_HTTPHEADER,$header);$result = curl_exec ($ch);
echo $result;
curl_close($ch);
?>server.php
<?php
header('Content-type: text/json;charset=utf-8');$body=file_get_contents("php://input");
echo "<br>body:".$body;var_dump($_SERVER);
if( !function_exists('apache_request_headers') ) {
///
    function apache_request_headers() {
        $arh = array();
        $rx_http = '/\AHTTP_/';
        foreach($_SERVER as $key => $val) {
            if( preg_match($rx_http, $key) ) {
                $arh_key = preg_replace($rx_http, '', $key);
                $rx_matches = array();
                // do some nasty string manipulations to restore the original letter case
                // this should work in most cases
                $rx_matches = explode('_', $arh_key);
                if( count($rx_matches) > 0 and strlen($arh_key) > 2 ) {
                    foreach($rx_matches as $ak_key => $ak_val) $rx_matches[$ak_key] = ucfirst($ak_val);
                    $arh_key = implode('-', $rx_matches);
                }
                $arh[$arh_key] = $val;
            }
        }
        return( $arh );
    }
///
}
var_dump(apache_request_headers(void)) ;?>

解决方案 »

  1.   

    是谁教你那么写 header 的?
    $header=array(
        "sign" => "sign:signature",
        "Authorization" => "OH key:signature"
    );$_SERVER 中才会有
        [HTTP_SIGN] => signature
        [HTTP_OH_KEY] => signature

    可见关联键是没有作用的
      

  2.   

    @xuzuning 版主爱死你了,确实是这个问题改过之后就可以取到了,但是我写成
    $header=array(
        "sign" => "sign:signature",
        "Authorization" => "Authorization:keysignature"
    );
    却娶不到Authorization的值,怎么破?
      

  3.   

    $header=array(
        "sign" => "sign:signature",
        "Authorization" => "Authorizatio:signature"
    );
    就有
        [HTTP_SIGN] => signature
        [HTTP_AUTHORIZATIO] => signature应该是键超长了吧
      

  4.   

    其实你那样写也是很不错的,结构清晰!
    $header=array(
        "sign" => "signature",
        "Authorizatio" => "signature"
    );
    但不能忘了这句(格式化一下)
    foreach($header as $k=>&$v) $v = "$k:$v";
      

  5.   

    之前写了类似的,可以参考一下:http://blog.csdn.net/fdipzone/article/details/49518535发送header:<?php
    $url = 'http://www.example.com';
    $header = array('token:JxRaZezavm3HXM3d9pWnYiqqQC1SJbsU','language:zh','region:GZ');
    $content = array(
            'name' => 'fdipzone'
    );$response = tocurl($url, $header, $content);
    $data = json_decode($response, true);echo 'POST data:';
    echo '<pre>';
    print_r($data['post']);
    echo '</pre>';
    echo 'Header data:';
    echo '<pre>';
    print_r($data['header']);
    echo '</pre>';/**
     * 发送数据
     * @param String $url     请求的地址
     * @param Array  $header  自定义的header数据
     * @param Array  $content POST的数据
     * @return String
     */
    function tocurl($url, $header, $content){
        $ch = curl_init();
        if(substr($url,0,5)=='https'){
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, true);  // 从证书中检查SSL加密算法是否存在
        }
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($content));
        $response = curl_exec($ch);
        if($error=curl_error($ch)){
            die($error);
        }
        curl_close($ch);
        return $response;
    }
    ?>
    接收header<?php
    $post_data = $_POST;
    $header = get_all_headers();$ret = array();
    $ret['post'] = $post_data;
    $ret['header'] = $header;header('content-type:application/json;charset=utf8');
    echo json_encode($ret, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);/**
     * 获取自定义的header数据
     */
    function get_all_headers(){    // 忽略获取的header数据
        $ignore = array('host','accept','content-length','content-type');    $headers = array();    foreach($_SERVER as $key=>$value){
            if(substr($key, 0, 5)==='HTTP_'){
                $key = substr($key, 5);
                $key = str_replace('_', ' ', $key);
                $key = str_replace(' ', '-', $key);
                $key = strtolower($key);            if(!in_array($key, $ignore)){
                    $headers[$key] = $value;
                }
            }
        }    return $headers;}
    ?> 
    输出:POST data:
    Array
    (
        [name] => fdipzone
    )
    Header data:
    Array
    (
        [token] => JxRaZezavm3HXM3d9pWnYiqqQC1SJbsU
        [language] => zh
        [region] => GZ
    )
      

  6.   

    上面的方法传递其它header值都没问题,但是传递 "Authorization" => "Authorization:keysignature"却无法获取到Authorization的值,是不是Authorization的header有特殊限制?看到一个方法可以取(http://blog.csdn.net/phphot/article/details/3491295),但还是取不到,高人们看下是什么原因。
      

  7.   

    文章中写得很明白了,Authorization这个确实比较特殊,具体的,其实你只要把$_SERVER变量整个打印出来看看,看Authorization这个键最终变成什么样的,就清楚是不是文章中写的那样了。