Php 为PUT或DELETE请求覆盖$\u POST

Php 为PUT或DELETE请求覆盖$\u POST,php,rest,Php,Rest,在PHP中,我希望能够全局访问PUT和DELETEvars,就像全局访问GET和POSTvars一样。我最初考虑将数据分别添加到全局命名空间中的$\u PUT和$\u DELETE,但后来我意识到每个请求的数据都存储在消息体中,因此从POST、PUT或DELETE请求中不能有多个数据集 覆盖$\u POST变量是否有任何副作用? i、 e.str\u parse(文件获取内容php://input",元(邮政), 我是傻了,还是有更好的方法访问PUT和DELETE数据 编辑以澄清我的想法: 我

在PHP中,我希望能够全局访问
PUT
DELETE
vars,就像全局访问
GET
POST
vars一样。我最初考虑将数据分别添加到全局命名空间中的
$\u PUT
$\u DELETE
,但后来我意识到每个请求的数据都存储在消息体中,因此从
POST
PUT
DELETE
请求中不能有多个数据集

覆盖
$\u POST
变量是否有任何副作用? i、 e.
str\u parse(文件获取内容php://input",元(邮政),

我是傻了,还是有更好的方法访问
PUT
DELETE
数据


编辑以澄清我的想法:

我非常清楚
$\u POST
中的数据来源,事实上我在我的问题前面提到过它。如果向服务器发送HTTP POST请求,则数据存储在
php://input
。如果向服务器发送HTTP PUT或DELETE请求,则数据存储在完全相同的位置,这意味着
$\u POST
将为空(因为尽管数据可用,但没有发布任何数据)

另一方面,通过查询字符串传递
GET
请求。这允许同时传递
$\u POST
$\u GET
变量。不可能同时传递
POST
PUT或DELETE
变量

如果我从
php://input
PUT
和/或
DELETE
请求中,没有数据丢失

另一种选择是添加:

global $_PUT;
global $_DELETE;
在函数的开头似乎很愚蠢,因为我一次只能使用一个函数

我的第一个问题,也是我真正想要回答的问题,是关于覆盖
$\u POST
时存在哪些副作用或问题。我不可能是第一个尝试以下愚蠢行为的人:

$_POST['foo'] = 'bar';

我只是担心,如果我做了类似的事情,它可能不会被跨域保存。

< P>你不应该直接修改<代码> $POST ,因为这代表了来自客户端的值。考虑它是只读的,并且在用户定义变量中做任何修改。< /P> 作为访问PUT和DELETE数据的后续操作,目前PHP中没有内置用于直接访问此数据的superglobal。由于数据是文件数据,可能非常大,因此在典型的赋值语句中读取整个文件内容的有用性和效率都很高。
$variable=$\u PUT['file'];
是有问题的。相反,它应该分块读取。因此,使用方法与从任何其他文件输入资源读取一致

更多信息请点击此处:

你会在互联网上看到这种被称为“坏习惯”的现象,但如果你真的理解了为什么它是“坏习惯”,那么答案就变得模糊了。最具体的原因是人们经常谈论的“被公车撞到”的情况——如果项目交给了新的开发人员怎么办

把手拧到一边(毕竟你可以留下评论),这样做确实没有令人信服的理由,,但同样,也没有令人信服的理由。如果希望值是全局的,为什么不将它们放入一个
$\u会话
键中?或者创建一个全局变量?或者创建一个静态类,通过所有其他可选应用程序访问put/DELETE值roaches,我认为覆盖
$\u POST
,虽然不会让你的服务器爆炸,但最有可能让你头疼

我把这个小静态类放在一起,在依赖它之前,您需要测试它。使用:

//To check if this is a rest request:
Rest::isRest();

//To get a parameter from PUT
$put_var = Rest::put('keyname', false);

//To get a parameter from DELETE
$dele_var = Rest::delete('keyname', false);

 class Rest {
    static private $put = false;
    static private $delete = false;
    static private $is_rest = false;
    function __construct() {
        self::$is_rest = true;
        switch ($_SERVER['REQUEST_METHOD']) {
            case 'PUT':
                parse_str(self::getVars(), self::$put);
                break;
            case 'DELETE':
                parse_str(self::getVars(), self::$delete);
                break;
            default:
                self::$is_rest = false;
        }
    }
    private static function getVars() {
        if (strlen(trim($vars = file_get_contents('php://input'))) === 0)
            $vars = false;
        return $vars;
    }
    public static function delete($key=false, $default=false) {
        if (self::$is_rest !== true)
            return $default;
        if (is_array(self::$delete) && array_key_exists($key, self::$delete))
            return self::$delete[$key];
        return $default;
    }
    public static function put($key=false, $default=false) {
        if (self::$is_rest !== true)
            return $default;
        if (is_array(self::$put) && array_key_exists($key, self::$put))
            return self::$put[$key];
        return $default;
    }
    public static function isRest() {
        return self::$is_rest;
    }
}

保留Post和Get原样。不应修改它,因为它仅用于阅读目的。创建$\u PUT和$\u DELETE全局变量:

//  globals
$_DELETE = array ();
$_PUT = array ();

switch ( $_SERVER['REQUEST_METHOD'] ) {
    case !strcasecmp($_SERVER['REQUEST_METHOD'],'DELETE'):
        parse_str( file_get_contents( 'php://input' ), $_DELETE );
        break;

    case !strcasecmp($_SERVER['REQUEST_METHOD'],'PUT'):
        parse_str( file_get_contents( 'php://input' ), $_PUT );
        break;
}
没有经过测试,但你应该明白了。几周前我自己也在寻找rest框架,并决定使用python。session()听起来很有希望,但如果你创建一个“请求”对象,则无论请求是通过HTTP、命令行还是通过HTML5 web套接字发出,您都将有一种统一的方式来访问请求数据。然后,您可以使请求对象在全局范围内可访问,或者将其作为参数传递给所需的函数或方法

理想情况下,您应该将独立于请求的数据存储在静态或全局变量中,例如“静态”设置不管请求是什么,也不管特定于请求的数据是本地变量还是对象,都可以由您的业务逻辑使用。例如,如果您有一个web套接字服务器,那么在一个PHP进程中处理多个请求对象会更容易。下面的示例可能会有所帮助:

 $headers = getallheaders();
 $query = parse_str($_SERVER['QUERY_STRING']);
 $data = file_get_contents('php://input');

 if(strpos($headers['Content-Type'],'application/x-www-form-urlencoded') !== false)
 {
      $data = parse_str($data);
 }
 elseif(strpos($headers['Content-Type'],'application/json') !== false)
 {
      $data = json_decode($data);
 }
 elseif(strpos($headers['Content-Type'],'application/soap+xml') !== false)
 {
      $data = // parse soap
 }
 elseif(strpos($headers['Content-Type'],'application/xml') !== false)
 {
      $data = // parse xml
 }
 // else ...


 $request = new Request($_SERVER['REQUEST_METHOD'],$data,$query);

 // example business logic

    $method = $request->get_request_method();

    $obj = new BlogPost();
    if($method == 'GET')
    {
        $obj->id($request->get_query('id'));
        $obj->load();
    }
    elseif($method == 'PUT')
    {
        $obj->id($request->get_query('id'));
        $obj->title($request->get_data('title'));
        $obj->body($request->get_data('body'));
        $obj->save();
    }
    elseif($method == 'POST')
    {
        $obj->title($request->get_data('title'));
        $obj->body($request->get_data('body'));
        $obj->save();
    }
    elseif($method == 'DELETE')
    {
        $obj->id($request->get_query('id'));
        $obj->wipe();
    }

无论是PUT、POST、PATCH还是DELETE,HTTP请求中只有一个数据体,因此您的应用程序不需要复杂的$request对象。request对象可以创建控制器(如果您使用的是MVC)非常简单。

你没有回复他关于
的问题,有没有更好的方法来访问PUT和DELETE数据?
part@yes123我喜欢它,因为我想知道我有没有车。在窗户上贴一些塑料并不能把它变成一艘船。用其他HTTP方法的数据覆盖superglobals只会带来长期的痛苦,特别是如果您计划将此代码模块化和/或与其他人共享$_POST代表POST数据,$\u GET代表GET数据。不要把它们混在一起。@Marc B,好的,但是如果我用一个对象覆盖
$\u POST
,该对象充当
$\u POST
数据的包装器,实现数组接口(ArrayAccess、Countable等),该怎么办?可以提供附加功能,而无需修改开发人员与w的交互方式