Xử lý các đối số PUT / DELETE trong PHP


84

Tôi đang làm việc trên thư viện máy khách REST của mình cho CodeIgniter và tôi đang đấu tranh để tìm cách gửi các đối số PUT và DELETE trong PHP.

Ở một vài nơi, tôi đã thấy mọi người sử dụng các tùy chọn:

$this->option(CURLOPT_PUT, TRUE);
$this->option(CURLOPT_POSTFIELDS, $params);

Thật khó chịu, điều này dường như không làm gì cả. Đây có phải là cách chính xác để đặt thông số PUT không?

Nếu vậy, làm cách nào để đặt tham số DELETE?

$ this-> option () là một phần của thư viện của tôi, nó chỉ đơn giản là xây dựng một mảng các hằng số CURLOPT_XX và gửi chúng đến curl_setopt_array () khi yêu cầu cURL đã xây dựng được thực thi.

Tôi đang cố đọc các tham số PUT và DELETE bằng mã sau:

        case 'put':
            // Set up out PUT variables
            parse_str(file_get_contents('php://input'), $this->_put_args);
        break;

        case 'delete':
            // Set up out PUT variables
            parse_str(file_get_contents('php://input'), $this->_delete_args);
        break;

Có hai tùy chọn ở đây, tôi đang tiếp cận điều này sai cách hoặc có lỗi ở đâu đó trong thư viện của tôi. Nếu bạn có thể cho tôi biết liệu điều này về mặt lý thuyết có hoạt động hay không, tôi có thể bắt đầu gỡ lỗi cho đến khi tôi giải quyết được nó.

Tôi không muốn lãng phí thêm thời gian vào một cách tiếp cận sai lầm về cơ bản.


PUT đang hoạt động tốt, chỉ cần XÓA các thông số để lo thiết lập ngay bây giờ.
Phil Sturgeon

1
Câu hỏi này thật khó hiểu. Đó là về việc gửi POST / DELETEtham số, hoặc nhận POST / DELETEtham số?
jameshfisher

Câu trả lời:


68

Thay vì sử CURLOPT_PUT = TRUEdụng use CURLOPT_CUSTOMREQUEST = 'PUT'CURLOPT_CUSTOMREQUEST = 'DELETE'sau đó chỉ đặt giá trị với CURLOPT_POSTFIELDS.


Làm cách nào để nhận POSTFIELDS ở phía api / máy chủ?
Daniel

48

Đây là một số mã có thể hữu ích cho những người khác muốn xử lý các tham số PUT và DELETE. Bạn có thể thiết lập $_PUT$_DELETEthông qua $GLOBALS[], nhưng chúng sẽ không thể truy cập trực tiếp trong các chức năng trừ khi được khai báo globalhoặc truy cập qua $GLOBALS[]. Để giải quyết vấn đề này, tôi đã tạo một lớp đơn giản để đọc các đối số yêu cầu GET / POST / PUT / DELETE. Điều này cũng được điền $_REQUESTvới các tham số PUT / DELETE.

Lớp này sẽ phân tích cú pháp các tham số PUT / DELETE và hỗ trợ cả GET / POST.

class Params {
  private $params = Array();

  public function __construct() {
    $this->_parseParams();
  }

  /**
    * @brief Lookup request params
    * @param string $name Name of the argument to lookup
    * @param mixed $default Default value to return if argument is missing
    * @returns The value from the GET/POST/PUT/DELETE value, or $default if not set
    */
  public function get($name, $default = null) {
    if (isset($this->params[$name])) {
      return $this->params[$name];
    } else {
      return $default;
    }
  }

  private function _parseParams() {
    $method = $_SERVER['REQUEST_METHOD'];
    if ($method == "PUT" || $method == "DELETE") {
        parse_str(file_get_contents('php://input'), $this->params);
        $GLOBALS["_{$method}"] = $this->params;
        // Add these request vars into _REQUEST, mimicing default behavior, PUT/DELETE will override existing COOKIE/GET vars
        $_REQUEST = $this->params + $_REQUEST;
    } else if ($method == "GET") {
        $this->params = $_GET;
    } else if ($method == "POST") {
        $this->params = $_POST;
    }
  }
}

16

Chỉ cần nhớ rằng, hầu hết các máy chủ web không xử lý các yêu cầu PUT & DELETE. Vì bạn đang làm một thư viện, tôi khuyên bạn nên nghĩ đến việc tính toán cho việc này. Thông thường, có hai quy ước bạn có thể sử dụng để bắt chước PUT & DELETE qua POST.

  1. sử dụng biến POST tùy chỉnh (ví dụ: _METHOD = PUT) ghi đè POST
  2. đặt tiêu đề HTTP tùy chỉnh (ví dụ: X-HTTP-Method-Override: PUT)

Nói chung, hầu hết các dịch vụ RESTful không cho phép PUT & DELETE trực tiếp sẽ hỗ trợ ít nhất một trong những chiến lược đó. Bạn có thể sử dụng cURL để đặt tiêu đề tùy chỉnh nếu bạn cần thông qua CURLOPT_HTTPHEADERtùy chọn.

// ex...
curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-HTTP-Method-Override: PUT') );

3

Tôi nghĩ bạn đang trộn các động từ của mình - PUT là để đặt một tệp, POST là để đăng các biến (mặc dù bạn có thể ĐĂNG một tệp).

Để đặt các biến bài đăng, hãy sử dụng CURLOPT_POSTFIELDSvới một chuỗi param1=val1&param2=val2hoặc một mảng kết hợp.

Để thực hiện XÓA, bạn sẽ muốn sử dụng tùy chọn cuộn CURLOPT_CUSTOMREQUEST


1
PUT và DELETE đều hỗ trợ việc gửi các đối số bổ sung. Bạn có thể thực hiện việc này thông qua dòng lệnh khi làm việc với curl nhưng tôi không thể tìm ra cách gửi bằng PHP-cURL. Ví dụ, vì điều này là cho REST, tôi cần một cách để đánh dấu những gì tôi đang xóa. Nếu tôi đang xóa id người dùng, tôi muốn có thể chuyển id mà không làm lộn xộn URL. Các API như Twitter chỉ hỗ trợ GET / POST để bạn có thể đưa nó vào URL, nhưng các API REST khác có thể không hỗ trợ loại thứ này, vì vậy tôi cần gửi một tham số xóa cho nó.
Phil Sturgeon

1
Được rồi, tôi có tham số PUT đang hoạt động, tôi đã đổi CURLOPT_PUT = TRUE cho CURLOPT_CUSTOMREQUEST = 'PUT' và điều đó hoạt động tốt. Bây giờ, làm cách quái nào để tôi đặt DELETE?
Phil Sturgeon

CURLOPT_CUSTOMREQUEST = 'DELETE', sau đó sử dụng chuỗi truy vấn cho các thông số có thể
Adam Hopkinson

1
Đóng lại, tôi đã cố gắng tránh sử dụng chúng trong chuỗi truy vấn như tôi đã đề cập. Hóa ra bạn có thể sử dụng CURLOPT_POSTFIELDS với PUT và DELETE khi sử dụng CURLOPT_CUSTOMREQUEST = 'DELETE. Cảm ơn phản hồi của bạn, nhưng tôi giải quyết nó bản thân mình cuối cùng :-)
Phil Sturgeon

2
Bạn đã? Tôi không giúp gì cả khi đó?
Adam Hopkinson

2

Đây là phiên bản DELETE cho CI của tôi. Nó chấp nhận các đối số kiểu GET cho các đối số DELETE, thậm chí cùng tên, tức là: GET / some / url? Id = 1 & id = 2 & id = 3

protected function _parse_delete()
{
    $query = $_SERVER['QUERY_STRING'];
    if ( !empty( $query ) )
    {
        foreach( explode('&', $query ) as $param )
        {
            list($k, $v) = explode('=', $param);
            $k = urldecode($k);
            $v = urldecode($v);
            if ( isset( $this->_delete_args[$k] ) )
            {
                if ( is_scalar( $this->_delete_args[$k] ) )
                {
                    $this->_delete_args[$k] = array( $this->_delete_args[$k] );
                }
                $this->_delete_args[$k][] = $v ;
            }
            else
            {
                $this->_delete_args[$k] = $v;
            }
        }
    }
}

1

Đây là cách tôi giải quyết vấn đề XÓA của mình:

== >> trong REST_Controller.php, tôi thay thế hàm delault _parse_delete () bằng:

protected function _parse_delete()
{
    $this->_delete_args = $_DELETE;
    $this->request->format and $this->request->body = file_get_contents('php://input');
    // Set up out DELETE variables (which shouldn't really exist, but sssh!)
    parse_str(file_get_contents('php://input'), $this->_delete_args);
}

;) nó hoạt động cho tôi!


1
$ _DELETE ;? Tôi chỉ gặp lỗi biến không xác định: _DELETE
Valor_
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.