$ _SERVER ['REQUEST_METHOD']是否保证是大写的?

时间:2012-05-26 12:30:55

标签: php

我的代码中目前有strtoupper($_SERVER['REQUEST_METHOD'])

strtoupper电话是否必要? $_SERVER['REQUEST_METHOD']是否已保证为大写?

6 个答案:

答案 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 3875REQUEST_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而不是==比较。