【问题标题】:Detecting request type in PHP (GET, POST, PUT or DELETE)检测 PHP 中的请求类型(GET、POST、PUT 或 DELETE)
【发布时间】:2010-09-26 10:05:48
【问题描述】:

如何检测 PHP 中使用了哪种请求类型(GET、POST、PUT 或 DELETE)?

【问题讨论】:

  • 不要忘记 HEAD =)(还有 OPTIONS、TRACE 和 CONNECT,但我认为 PHP 永远不会得到这些)。
  • PATCH 怎么样?
  • PATCH 也可以正常工作。 $_SERVER['REQUEST_METHOD'] === 'PATCH'

标签: php http request


【解决方案1】:

通过使用

$_SERVER['REQUEST_METHOD']

示例

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
     // The request is using the POST method
}

更多详情请查看documentation for the $_SERVER variable

【讨论】:

  • 如果您 POST 到 mypage.php?var=something 会发生什么?
  • 方法将是 POST,但如果你必须使用 $_GET 来获取这些变量我不确定。
  • 在 nickf 提到的情况下,您也可以(也许)使用 $_REQUEST 变量。 $_REQUEST 包含 post、get 和 cookie 值。阅读php.net/manual/en/reserved.variables.request.php的文档
  • @NathanLong 根据我的经验,这是不正确的。如果您 POST 到 mypage.php?var=something 那么“某事”将在 $_GET['var']
  • $_POST$_GET 有点不幸命名。 $_GET 包含来自 URL 查询组件的变量,与 HTTP 方法无关。如果请求以application/x-www-form-urlencoded 发送,$_POST 将包含表单字段。
【解决方案2】:

PHP 中的 REST 可以非常简单地完成。创建http://example.com/test.php(如下所述)。将此用于 REST 调用,例如http://example.com/test.php/testing/123/hello。这适用于开箱即用的 Apache 和 Lighttpd,不需要重写规则。

<?php
$method = $_SERVER['REQUEST_METHOD'];
$request = explode("/", substr(@$_SERVER['PATH_INFO'], 1));

switch ($method) {
  case 'PUT':
    do_something_with_put($request);  
    break;
  case 'POST':
    do_something_with_post($request);  
    break;
  case 'GET':
    do_something_with_get($request);  
    break;
  default:
    handle_error($request);  
    break;
}

【讨论】:

  • 如果你想让你的 API 可用,而不引用你正在使用的解释引擎,在 RewriteRule 上添加一个包含 RewriteEngine 的 .htaccess 文件 ^api/(.*)$ api.php/$1 这个假设您的 API 文件名为 api.php。此外,由于编写了上述代码块,PHP 开发人员已经贬低了拆分功能。如果你用explode替换split,它工作正常。
  • $_SERVER['PATH_INFO']前面的@是怎么回事?
  • @Svish,你注意到了多么棒的细节啊!如果 PATH_INFO 不在$_SERVER 中,它会删除PHP Notice: Undefined index: PATH_INFO。我马上把这个添加到我的技巧包中!这是一种说“我知道在这个数组中可能没有以这种方式命名的条目,我已经准备好了,所以闭嘴,按照我告诉你的去做”。 :) 谢谢大家,无论是发布这个答案还是让我注意到其中的特定角色。
  • 我通常使用 !empty 而不是 @。更好的做法?
  • 作为使用变量方法更简洁的方式:&lt;?php $request = explode("/", substr(@$_SERVER['PATH_INFO'], 1)); $rest = 'rest_'.strtolower($_SERVER['REQUEST_METHOD']); if (function_exists($rest)) call_user_func($rest, $request); ?&gt;
【解决方案3】:

检测 HTTP 方法或所谓的REQUEST METHOD 可以使用以下代码 sn-p 完成。

$method = $_SERVER['REQUEST_METHOD'];
if ($method == 'POST'){
    // Method is POST
} elseif ($method == 'GET'){
    // Method is GET
} elseif ($method == 'PUT'){
    // Method is PUT
} elseif ($method == 'DELETE'){
    // Method is DELETE
} else {
    // Method unknown
}

如果您更喜欢 switch 而不是 if-else 语句,也可以使用它。

如果 HTML 表单中需要 GETPOST 以外的方法,通常可以使用表单中的隐藏字段来解决。

<!-- DELETE method -->
<form action='' method='POST'>
    <input type="hidden" name'_METHOD' value="DELETE">
</form>

<!-- PUT method -->
<form action='' method='POST'>
    <input type="hidden" name'_METHOD' value="PUT">
</form>

有关 HTTP 方法的更多信息,我想参考以下 StackOverflow 问题:

HTTP protocol's PUT and DELETE and their usage in PHP

【讨论】:

    【解决方案4】:

    您可以使用getenv 函数,而不必使用$_SERVER 变量:

    getenv('REQUEST_METHOD');
    

    更多信息:

    http://php.net/manual/en/function.getenv.php

    【讨论】:

      【解决方案5】:

      我们还可以使用input_filter 来检测请求方法,同时还通过输入卫生提供安全性。

      $request = filter_input(INPUT_SERVER, 'REQUEST_METHOD', FILTER_SANITIZE_ENCODED);
      

      【讨论】:

        【解决方案6】:

        由于这是关于 REST 的,仅从服务器获取请求方法是不够的。您还需要接收 RESTful 路由参数。分离 RESTful 参数和 GET/POST/PUT 参数的原因是资源需要有自己唯一的 URL 用于标识。

        这是使用 Slim 在 PHP 中实现 RESTful 路由的一种方法:

        https://github.com/codeguy/Slim

        $app = new \Slim\Slim();
        $app->get('/hello/:name', function ($name) {
          echo "Hello, $name";
        });
        $app->run();
        

        并相应地配置服务器。

        这是另一个使用 AltoRouter 的示例:

        https://github.com/dannyvankooten/AltoRouter

        $router = new AltoRouter();
        $router->setBasePath('/AltoRouter'); // (optional) the subdir AltoRouter lives in
        
        // mapping routes
        $router->map('GET|POST','/', 'home#index', 'home');
        $router->map('GET','/users', array('c' => 'UserController', 'a' => 'ListAction'));
        $router->map('GET','/users/[i:id]', 'users#show', 'users_show');
        $router->map('POST','/users/[i:id]/[delete|update:action]', 'usersController#doAction', 'users_do');
        

        【讨论】:

        • 不是 OP 要求的。而且,OP 没有在任何地方提到 REST。
        • @BrunoFerreira 你想让我删除答案,因为 OP 没有专门使用 REST 这个词吗?
        【解决方案7】:
        $request = new \Zend\Http\PhpEnvironment\Request();
        $httpMethod = $request->getMethod();
        

        这样你也可以在zend framework 2中实现。 谢谢。

        【讨论】:

        • 你可以在控制器中制作 $request = $this->getRequest()。然后,$request->isPost()。另请查看 $request->getMethod()。
        【解决方案8】:

        非常简单,只需使用 $_SERVER['REQUEST_METHOD'];

        示例:

        <?php
        $method = $_SERVER['REQUEST_METHOD'];
        switch ($method) {
          case 'GET':
            //Here Handle GET Request 
            break;
          case 'POST':
            //Here Handle POST Request 
            break;
          case 'DELETE':
            //Here Handle DELETE Request 
            break;
          case 'PUT':
            //Here Handle PUT Request 
            break;
        }
        ?>
        

        【讨论】:

        • 永远不会命中“DELETE”案例,因为这不是可能的 REQUEST_METHOD。有效的 REQUEST_METHOD 是“GET”、“HEAD”、“POST”、“PUT”。在发布答案之前,请阅读文档(在此页面上的许多答案中都有指出)。
        • @Patrick,实际上,当请求方法为 DELETE 时,“DELETE”案例会受到打击;尽管如此,PHP 中的文档并未提及它。事实上,任何方法都会反映在$_SERVER['REQUEST_METHOD'] 中,甚至是定制的方法。请记住,该方法只是请求标头中的一个字符串,我们的任务是检查其正确性。
        • @Patrick DELETE 在 RFC7231 中定义,所有主流浏览器都支持。 tools.ietf.org/html/rfc7231#section-4.3.5 和 $_SERVER["REQUEST_METHOD"] 只是一个字符串。
        • @IvanDePazCenteno 没错。永远不要相信用户输入。永远不要相信用户输入。
        【解决方案9】:

        在核心 php 中你可以这样做:

        <?php
        
        $method = $_SERVER['REQUEST_METHOD'];
        
        switch ($method) {
          case 'GET':
            //Here Handle GET Request
            echo 'You are using '.$method.' Method';
            break;
          case 'POST':
            //Here Handle POST Request
            echo 'You are using '.$method.' Method';
            break;
          case 'PUT':
            //Here Handle PUT Request
            echo 'You are using '.$method.' Method';
            break;
          case 'PATCH':
            //Here Handle PATCH Request
            echo 'You are using '.$method.' Method';
            break;
          case 'DELETE':
            //Here Handle DELETE Request
            echo 'You are using '.$method.' Method';
            break;
          case 'COPY':
              //Here Handle COPY Request
              echo 'You are using '.$method.' Method';
              break;
        
          case 'OPTIONS':
              //Here Handle OPTIONS Request
              echo 'You are using '.$method.' Method';
              break;
          case 'LINK':
              //Here Handle LINK Request
              echo 'You are using '.$method.' Method';
              break;
          case 'UNLINK':
              //Here Handle UNLINK Request
              echo 'You are using '.$method.' Method';
              break;
          case 'PURGE':
              //Here Handle PURGE Request
              echo 'You are using '.$method.' Method';
              break;
          case 'LOCK':
              //Here Handle LOCK Request
              echo 'You are using '.$method.' Method';
              break;
          case 'UNLOCK':
              //Here Handle UNLOCK Request
              echo 'You are using '.$method.' Method';
              break;
          case 'PROPFIND':
              //Here Handle PROPFIND Request
              echo 'You are using '.$method.' Method';
              break;
          case 'VIEW':
              //Here Handle VIEW Request
              echo 'You are using '.$method.' Method';
              break;
          Default:
            echo 'You are using '.$method.' Method';
          break;
        }
        
        
        ?>
        

        【讨论】:

          【解决方案10】:

          另外值得注意的是,即使您发送其他类型的正确请求,PHP 也会填充所有$_GET 参数。

          以上回复中的方法完全正确,但是如果您想在处理POSTDELETEPUT等请求时额外检查GET参数,则需要检查@987654326的大小@数组。

          【讨论】:

            【解决方案11】:

            当一个方法被请求时,它会有一个array。所以只需检查count()

            $m=['GET'=>$_GET,'POST'=>$_POST];
            foreach($m as$k=>$v){
                echo count($v)?
                $k.' was requested.':null;
            }
            

            3v4l.org/U51TE

            【讨论】:

              【解决方案12】:

              我使用了这个代码。它应该可以工作。

              function get_request_method() {
                  $request_method = strtolower($_SERVER['REQUEST_METHOD']);
              
                  if($request_method != 'get' && $request_method != 'post') {
                      return $request_method;
                  }
              
                  if($request_method == 'post' && isset($_POST['_method'])) {
                      return strtolower($_POST['_method']);
                  }
              
                  return $request_method;
              }
              

              上面的代码适用于REST calls,也适用于html form

              <form method="post">
                  <input name="_method" type="hidden" value="delete" />
                  <input type="submit" value="Submit">
              </form>
              

              【讨论】:

                【解决方案13】:

                您可以获得任何查询字符串数据,即www.example.com?id=2&amp;name=r

                您必须使用$_GET['id']$_REQUEST['id'] 获取数据。

                发布数据意味着像&lt;form action='' method='POST'&gt;这样的表格,你必须使用$_POST$_REQUEST

                【讨论】:

                  猜你喜欢
                  • 2020-04-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-09-14
                  • 2014-06-04
                  相关资源
                  最近更新 更多