PHP에서 PUT / DELETE 인수 처리


84

CodeIgniter 용 REST 클라이언트 라이브러리에서 작업 중이며 PHP에서 PUT 및 DELETE 인수를 보내는 방법을 해결하는 데 어려움을 겪고 있습니다.

몇 곳에서 사람들이 옵션을 사용하는 것을 보았습니다.

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

짜증나게도 이것은 아무 일도하지 않는 것 같습니다. 이것이 PUT 매개 변수를 설정하는 올바른 방법입니까?

그렇다면 DELETE 매개 변수를 어떻게 설정합니까?

$ this-> option ()은 내 라이브러리의 일부이며, 단순히 CURLOPT_XX 상수의 배열을 구축하고 구축 된 cURL 요청이 실행될 때 curl_setopt_array ()로 보냅니다.

다음 코드를 사용하여 PUT 및 DELETE 매개 변수를 읽으려고합니다.

        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;

여기에는 두 가지 옵션이 있습니다. 잘못된 방식으로 접근하고 있거나 라이브러리 어딘가에 버그가 있습니다. 이것이 이론적으로 작동하는지 알려 주실 수 있다면 해결할 때까지 디버그를 망치면됩니다.

근본적으로 잘못된 접근 방식에 더 이상 시간을 낭비하고 싶지 않습니다.


PUT이 잘 작동합니다. 지금 설정에 대해 걱정할 매개 변수를 삭제하기 만하면됩니다.
Phil Sturgeon

1
이 질문은 혼란 스럽습니다. 그것은 약인가 전송 POST / DELETE매개 변수, 또는 수신 POST / DELETE매개 변수를?
jameshfisher 2014 년

답변:


68

대신 사용의 CURLOPT_PUT = TRUE사용 CURLOPT_CUSTOMREQUEST = 'PUT'CURLOPT_CUSTOMREQUEST = 'DELETE'함께 다음 바로 설정 값을 CURLOPT_POSTFIELDS.


API / 서버 측에서 POSTFIELDS를 수신하려면 어떻게해야합니까?
Daniel

48

다음은 PUT 및 DELETE 매개 변수를 처리하려는 다른 사용자에게 도움이 될 수있는 코드입니다. 당신은 설정할 수 있습니다 $_PUT$_DELETE경유 $GLOBALS[]하지만, 선언하지 않는 한 그들은 기능에 직접 액세스 할 수 없습니다 global또는 통해 액세스 $GLOBALS[]. 이 문제를 해결하기 위해 GET / POST / PUT / DELETE 요청 인수를 읽는 간단한 클래스를 만들었습니다. 이것은 또한 $_REQUESTPUT / DELETE 매개 변수로 채워집니다 .

이 클래스는 PUT / DELETE 매개 변수를 구문 분석하고 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

대부분의 웹 서버는 PUT & DELETE 요청을 처리하지 않습니다. 당신이 도서관을 만들고 있기 때문에 나는 이것을 설명하는 것에 대해 생각하는 것이 좋습니다. 일반적으로 POST를 통해 PUT 및 DELETE를 모방하는 데 사용할 수있는 두 가지 규칙이 있습니다.

  1. POST를 재정의하는 사용자 지정 POST 변수 (예 : _METHOD = PUT) 사용
  2. 사용자 지정 HTTP 헤더 설정 (예 : X-HTTP-Method-Override : PUT)

일반적으로 PUT & DELETE를 직접 허용하지 않는 대부분의 RESTful 서비스는 이러한 전략 중 하나 이상을 지원합니다. CURLOPT_HTTPHEADER옵션을 통해 필요한 경우 cURL을 사용하여 사용자 정의 헤더를 설정할 수 있습니다 .

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

3

나는 당신이 동사를 혼합하고 있다고 생각합니다-PUT은 파일을 넣는 것이고 POST는 변수를 게시하는 것입니다 (파일을 POST 할 수는 있지만).

포스트 변수를 설정하려면 CURLOPT_POSTFIELDS문자열 param1=val1&param2=val2또는 연관 배열 과 함께 사용하십시오 .

DELETE를 수행하려면 curl 옵션을 사용하고 싶을 것입니다. CURLOPT_CUSTOMREQUEST


1
PUT 및 DELETE는 모두 추가 인수 전송을 지원합니다. curl로 작업 할 때 명령 줄을 통해이 작업을 수행 할 수 있지만 PHP-cURL로 보내는 방법을 알아낼 수 없습니다. 예를 들어 REST 용이므로 삭제할 항목을 표시하는 방법이 필요합니다. 사용자 ID를 삭제하는 경우 URL을 복잡하게하지 않고 ID를 전달할 수 있기를 바랍니다. Twitter와 같은 API는 GET / POST 만 지원하므로 URL에 넣을 수 있지만 다른 REST API는 이러한 종류를 지원하지 않을 수 있으므로 삭제 매개 변수를 보내야합니다.
Phil Sturgeon

1
좋아, 나는 PUT 매개 변수가 작동하고 CURLOPT_CUSTOMREQUEST = 'PUT'에 대해 CURLOPT_PUT = TRUE를 바꿨고 잘 작동합니다. 이제 대체 어떻게 DELETE를 설정합니까?
Phil Sturgeon

CURLOPT_CUSTOMREQUEST = 어쩌면 매개 변수에 대한 쿼리 문자열을 사용, '삭제'
아담 홉 킨슨

1
닫기, 이미 언급했듯이 쿼리 문자열에서 사용하지 않으려 고했습니다. CURLOPT_CUSTOMREQUEST = 'DELETE를 사용할 때 PUT 및 DELETE와 함께 CURLOPT_POSTFIELDS를 사용할 수 있습니다. 의견을 보내 주셔서 감사합니다.하지만 결국 제가 해결했습니다. :-)
Phil Sturgeon

2
당신은? 내가 전혀 도와주지 않았나요?
Adam Hopkinson

2

이것은 CI 용 DELETE 버전입니다. DELETE에 대한 GET 스타일 인수, 동일한 이름 인수도 허용합니다. 예 : 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

이것이 내 DELETE 문제를 해결하는 방법입니다.

== >> REST_Controller.php 에서 delault _parse_delete () 함수를 다음으로 대체합니다 .

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);
}

;) 그것은 나를 위해 작동합니다!


1
$ _DELETE ;? 정의되지 않은 변수 오류가 발생합니다. _DELETE
Valor_
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.