php - 为 PUT 或 DELETE 请求覆盖 ​​$_POST

标签 php rest

在 PHP 中,我希望能够全局访问 PUTDELETE 变量,类似于 GETPOST vars 是全局访问的。我原本考虑将数据分别添加到全局命名空间中的$_PUT$_DELETE,但后来我意识到每个请求的数据都存储在消息体中所以有POSTPUTDELETE 请求不可能有多个数据集。

覆盖$_POST 变量是否有任何副作用?

str_parse( file_get_contents( 'php://input' ), $_POST );

我是不是太傻了,还是有更好的方法来访问 PUTDELETE 数据?


编辑以澄清我的想法:

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

另一方面,GET 请求是通过查询字符串传递的。这允许同时传递 $_POST$_GET 变量。 不可能同时传递POSTPUT 或DELETE 变量。

如果我在 PUT 和/或 DELETE 请求上从 php://input 覆盖 $_POST,那么没有数据丢失。

添加的替代方法:

global $_PUT;
global $_DELETE;

函数的开头看起来很愚蠢,因为我一次只能使用一个无论如何

我的第一个问题,也是我真正想要回答的问题,是关于覆盖 $_POST 时存在哪些副作用或问题。我不可能是第一个尝试像这样愚蠢的事情的人:

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

我只是担心,如果我做任何类似的事情,它可能不会跨范围保留。

最佳答案

您会在整个 Internet 上看到这种称为“不良做法”的做法,但如果您真正了解为什么这是“不良做法”,那么答案就会变得模糊。最具体的原因是经常流传的“被公共(public)汽车撞了”的场景——如果项目被移交给新的开发人员怎么办?

撇开手腕(毕竟你可以发表评论),确实没有一个令人信服的理由这样做,但是同样,也没有一个令人信服的理由也可以去做。如果您希望它们是全局的,为什么不将值放在 $_SESSION 键中?或者做一个全局变量?或者创建一个静态类来访问 PUT/DELETE 值?对于所有其他可选方法,我认为覆盖 $_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;
    }
}

关于php - 为 PUT 或 DELETE 请求覆盖 ​​$_POST,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6270033/

相关文章:

php - 无法让 PHP 从 mySQL 中提取行条目作为数组

php - 如何将数据库中存储的ip转换为ip2long

php - 如何从在 PHP 中使用自动加载加载的类中捕获异常?

java - 蓝色混合 : Java Rest API starter app

java - 阿拉伯文本在 itext 的 PDF 中显示 شناية الÙ

web-services - 为什么 Windows Phone 应用程序的 REST 服务中会出现 NotFound 错误?

php - 为什么它不会循环? (PHP 和 MySQL)

javascript - 如何将下拉列表转换为在 HTML 和 PHP 中显示搜索匹配结果的输入标记?

rest - 如何为 Azure 存储构建授权 header 获取容器属性 REST API

ruby - RFC2616 : Do I really need to set WWW_Authenticate when returning 401?