我的代码中目前有strtoupper($_SERVER['REQUEST_METHOD'])
。
但strtoupper
电话是否必要? $_SERVER['REQUEST_METHOD']
是否已保证为大写?
答案 0 :(得分:13)
简短回答:不,这不能保证,但通常接收非大写的HTTP方法意味着客户端违反了规范。
如果您正在处理W3规范定义的方法,例如GET和POST,那么您可以保证符合规范的客户端会以大写形式发送它们。这是因为HTTP方法是defined as case-sensitive ...
Method标记指示要对Request-URI标识的资源执行的方法。该方法区分大小写。
和W3定义的方法如OPTIONS, GET, POST etc.以大写形式定义。
但是,如果您正在处理不符合规范的客户端,那么您的网络服务器和PHP都不会将$_SERVER['REQUEST_METHOD']
的值大胆地强制为大写。这可以通过像这样的简单脚本轻松演示......
<?php
echo "The method used by your request was $_SERVER[REQUEST_METHOD]";
?>
如果我们使用方法不是大写的HTTP请求命中该脚本,它将以非大写形式回显该方法。许多常用工具将让我们这样做。例如,让我们从UNIX shell中点击它:
$ curl http://localhost/echo_method.php -X GET -w "\n"
The method used by your request was GET
$ curl http://localhost/echo_method.php -X gEt -w "\n"
The method used by your request was gEt
$ curl http://localhost/echo_method.php -X fWoRbLeWoRbLe -w "\n"
The method used by your request was fWoRbLeWoRbLe
......或使用Python:
>>> import httplib
>>> connection = httplib.HTTPConnection('localhost')
>>> connection.request('pOsT', '/echo_method.php')
>>> connection.getresponse().read()
'The method used by your request was pOsT'
“好的”,您可能会说,“因此,如果我的API被编写得不好的脚本或本机应用程序使用,则存在潜在的问题。但我的API仅用于由在网络浏览器中运行的JavaScript触发的AJAX调用。这个问题对我有影响吗?“
不幸的是,是的。在发送AJAX时,现代浏览器似乎将大多数标准HTTP方法强制转换为大写,但目前对于自定义HTTP方法,或者特别是PATCH method,
点击之前的相同PHP脚本,这次是在Chrome JavaScript控制台...
var request;
request = new XMLHttpRequest();
request.open("GeT", "http://localhost/echo_method.php", true);
request.send();
request.onreadystatechange = function() {
if (request.readyState == 4) {
console.log(request.responseText);
}
}
产生结果
The method used by your request was GET
但是将HTTP方法更改为pATcH
会给我们
var request;
request = new XMLHttpRequest();
request.open("pATcH", "http://localhost/echo_method.php", true);
request.send();
request.onreadystatechange = function() {
if (request.readyState == 4) {
console.log(request.responseText);
}
}
给我们
The method used by your request was pATcH
更糟糕的是,Web浏览器并不是will coerce all methods except the PATCH method大写的唯一客户端。
总之:虽然HTTP规范要求请求包含大写的HTTP方法(除非它是在不同情况下专门定义的自定义方法),但常见的Web工具使前端开发人员很容易弄错,并且PHP的$_SERVER['REQUEST_METHOD']
变量将不如果他们这样做,就会神奇地将该方法强制转换为大写。
当然,这取决于您是否要依赖客户遵守规范,验证方法是否为大写并使用适当的状态代码(可能是400或405)进行响应,如果不是,则返回错误消息,或者接受错误套装的HTTP方法,方法是通过strtoupper($_SERVER['REQUEST_METHOD'])
强制将方法强制为大写字母,就像问题提供者原来的那样。
答案 1 :(得分:4)
RFC 3875将REQUEST_METHOD
变量定义为大写,因此可以依赖它。
REQUEST_METHOD元变量必须设置为方法 应该由脚本用来处理请求......
REQUEST_METHOD = method method = "GET" | "POST" | "HEAD" | extension-method extension-method = "PUT" | "DELETE" | token
该方法区分大小写。
答案 2 :(得分:0)
它完全是SAPI特有的,据我所知,PHP“规范”中没有任何内容可以强制使用大写方法名称。这是AOL Server SAPI的代码片段:
Ns_RegisterRequest(ctx->ns_server, "POST", value, php_ns_request_handler, NULL, ctx, 0);
如果有人将POST
更改为post
,那么它将为小写。
对strtoupper()
的单次调用无需花费任何费用,因此请不要冒险并只使用它。
答案 3 :(得分:0)
是的,这就是PHP内部在php 5.4下寻找的内容
http://lxr.php.net/opengrok/xref/PHP_5_4/main/SAPI.c#456
454 if (SG(server_context)) {
455 if (PG(enable_post_data_reading) && SG(request_info).request_method) {
456 if (SG(request_info).content_type && !strcmp(SG(request_info).request_method, "POST")) {
http://lxr.php.net/opengrok/xref/PHP_5_4/main/SAPI.c#797
796 } else if (SG(request_info).proto_num > 1000 &&
797 SG(request_info).request_method &&
798 strcmp(SG(request_info).request_method, "HEAD") &&
799 strcmp(SG(request_info).request_method, "GET")) {
它从服务器提供这些值,但如果它不符合the spec传递数据,则它是一个性能很差的服务器......但HTTP RFC仅表示大写。所以,它永远不会成为一个问题。
由于这些原因,保证大写。
答案 4 :(得分:-1)
通常是,但我不会指望它100%。这样的事情可能会在新的软件版本或不同的配置中发生变化。你真的不想要像服务器升级那样破坏代码的东西。如果你想比较它,那么总是要确保两个字符串都是小写或大写。
答案 5 :(得分:-2)
php documentation似乎表明此变量有四个可能的值:GET,HEAD,POST或PUT,所有这些都是大写的。你可以随时做一个strcasecmp而不是==比较。