PHP原生HTTP GET请求参数失效问题排查
问题:PHP原生GET请求用stream_context_create的content字段传参失败,URL拼接参数成功
时隔许久重新学习PHP,想用原生方式而非curl类库发送GET请求到Microsoft Identity Platform。尝试用stream_context_create把参数放到content字段里时请求失败,但直接拼接参数到URL里就正常,想知道原因。
失败代码示例
<?php $data = array ( 'client_id' => '6731de76-14a6-49ae-97bc-6eba6914391e', 'state' => '12345', 'redirect_uri' => urlencode('http://localhost/myapp/permissions') ); $streamOptions = array('http' => array( 'method' => 'GET', 'content' => $data )); $streamContext = stream_context_create($streamOptions); $streamURL = 'https://login.microsoftonline.com/common/adminconsent'; $streamResult = file_get_contents($streamURL, false, $streamContext); echo $streamResult; ?>
成功代码示例
<?php $streamURL = 'https://login.microsoftonline.com/common/adminconsent?client_id=6731de76-14a6-49ae-97bc-6eba6914391e&state=12345&redirect_uri=http://localhost/myapp/permissions'; $streamResult = file_get_contents($streamURL); echo $streamResult; ?>
原因分析
- HTTP GET请求的参数传递规范:GET请求的参数本来就应该通过URL的查询字符串(
?key=value形式)传递,而非请求体。虽然少数服务器会兼容解析GET请求的请求体,但Microsoft Identity Platform的这个接口不支持这种非常规方式,只会读取URL里的查询参数。 - stream_context_create的content字段用途:这个字段是用来设置HTTP请求的请求体内容的,专门给POST、PUT这类需要携带请求体的请求使用。在GET请求里设置content,相当于给GET请求附加了请求体,但目标接口根本不会去解析这部分内容,自然拿不到参数,导致请求失败。
- 参数格式错误:就算忽略规范,直接把数组传给content也是错误的——content字段要求的是字符串格式的请求体内容,需要用
http_build_query()把数组转成URL编码的字符串,但这依然不符合GET请求的标准用法,且目标接口不支持。
修正后的原生GET请求写法
如果想用stream_context_create配置请求(比如添加请求头等额外设置),正确的做法还是把参数拼到URL里:
<?php $data = array( 'client_id' => '6731de76-14a6-49ae-97bc-6eba6914391e', 'state' => '12345', 'redirect_uri' => 'http://localhost/myapp/permissions' ); // 用http_build_query自动处理参数编码和拼接 $queryString = http_build_query($data); $streamURL = 'https://login.microsoftonline.com/common/adminconsent?' . $queryString; // 如需配置其他请求选项(比如请求头),再创建上下文 $streamOptions = array('http' => array( 'method' => 'GET', // 示例:添加自定义请求头 // 'header' => 'User-Agent: PHP Native Request' )); $streamContext = stream_context_create($streamOptions); $streamResult = file_get_contents($streamURL, false, $streamContext); echo $streamResult; ?>
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

