在PHP中获取请求的“Content-Type”标头

58

我正在用PHP实现一个REST服务,该服务应该支持多个输入和输出格式(JSON、XML)。因此,我想要检查请求头中的"Accept""Content-Type"来确定客户端发送和请求的内容类型。

访问"Accept"头信息只需要使用$_SERVER['HTTP_ACCEPT']即可。但是访问"Content-Type"头信息似乎比较困难。我搜索了PHP文档和网页,但唯一提供的解决方案是使用PHP函数apache_request_headers(),但这仅在PHP被安装为Apache模块时才受支持,而这在我的情况下不是真实的情况。

所以我的问题是:如何访问请求中的“Content-Type”头信息?


请记住,$_SERVER["CONTENT_TYPE"]并不总是可用的。 - user1898931
3个回答

68

普通(GET)请求没有Content-Type头。对于POST请求,它将显示为$_SERVER [“CONTENT_TYPE”],其值为multipart / form-data或application / x-www-form-urlencoded。

这是CGI/1.1规范规定的:http://www.ietf.org/rfc/rfc3875


8
有一份已记录的PHP内置服务器bug报告。它应该返回 CONTENT_TYPE 但实际上返回 HTTP_CONTENT_TYPE。希望它能在不久的将来得以修复。https://bugs.php.net/bug.php?id=66606&thanks=6 - Jake A. Smith
3
虽然不常见,但GET请求可以有Content-Type头部,并且可以包含请求正文。 - tobyink

25
你需要手动告诉Apache提供Content-Type头信息(以及任何其他你想要的头信息)。

在你的.htaccess文件或虚拟主机中添加以下内容:

RewriteEngine on
RewriteRule .* - [E=HTTP_CONTENT_TYPE:%{HTTP:Content-Type},L]

完成了,你刚刚合成了自己的$_SERVER['HTTP_CONTENT_TYPE']

编辑:

我假设你是在Apache下运行PHP作为CGI,因此可以使用除GET和POST之外的动词,大多数rest服务都是如此。如果你使用另一个Web服务器或鲜为人知的PHP SAPI,则需要使用类似的技巧;无论您使用其他机制 - $_ENVapache_request_headers(),甚至是php_http扩展中的类,PHP作为CGI都无法访问请求头以外的内容都将为空。


@NeilE.Pearson 有没有办法允许在头部中使用 charset?我正在遇到问题,它无法接受它。 - Ben Sinclair
@BenSinclair,由于您的问题已被删除,我会假设您不再需要答案 ;) - Neil E. Pearson
1
这不需要 mod_rewrite SetEnvIfNoCase ^Content-Type "(.+)" CONTENT_TYPE=$1 - Vicary
@BenSinclair 这很有道理。我相信响应中的媒体类型 Content-Type: 已经添加了 ;charset=UTF-8,但请求中的表单媒体类型却没有。这与 RFC6749 一致,并且关于 "application/x-www-form-urlencoded" 的 UTF-8 规范的缺失在附录 B 中进行了讨论 [http://tools.ietf.org/html/rfc6749#appendix-B]。 - ClearCrescendo
1
这应该是被选中的答案! - Cagy79
显示剩余2条评论

6
您可以使用以下代码获取内容类型(如“text/html”):

你也可以用这个方法获取内容类型:

echo split(',', getallheaders()['Accept'])[0];

或者

echo get_headers('http://127.0.0.1', 1)["Content-Type"]

更新

像本杰明所说的那样,apache_request_headers自5.4.0起可在FastCGI中使用,并自5.5.7起在内部PHP服务器中使用。


1
谢谢提供的信息。从文档来看,"这些函数只有在将 PHP 作为 Apache 模块运行时才可用"。据我所知,PHP 经常使用 FastCGI 运行。这也正是我的情况。我个人更喜欢使用 $_SERVER["CONTENT_TYPE"],它看起来更干净整洁。 - CodeZombie
2
请注意,apache_request_headers() 函数在 PHP 5.4.0 中可在 FastCGI 下使用。 - BenMorel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接