2010-01-17 53 views
77

Estoy trabajando en mi REST client library for CodeIgniter y estoy luchando para encontrar la manera de enviar argumentos PUT y DELETE en PHP.Manejo de argumentos PUT/DELETE en PHP

personas en unos pocos lugares que he visto utilizando las opciones:

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

Irritantemente, esto parece no hacer nada. ¿Es esta la forma correcta de configurar los parámetros de PUT?

En caso afirmativo, ¿cómo configuro los parámetros DELETE?

$ this-> opción() es parte de mi biblioteca, sino que simplemente se acumula una serie de constantes CURLOPT_XX y los envía a curl_setopt_array() cuando se ejecuta la solicitud cURL acumulado.

Estoy intentando leer PUT y DELETE parámetros usando el siguiente código:

 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; 

Hay dos opciones aquí, yo estoy acercando a esto en el camino equivocado o hay un error en alguna parte de mis bibliotecas. Si pudieras decirme si esto debería funcionar teóricamente, puedo resolver la depuración hasta que lo resuelva.

No quiero perder más tiempo en un enfoque que es fundamentalmente erróneo.

+0

PUT está trabajando muy bien, basta con borrar los parámetros que preocuparse sobre la configuración ahora. –

+1

Esta pregunta es confusa. ¿Se trata de * enviar * 'POST' /' DELETE' parámetros, o * recibir * 'POST' /' DELETE' parámetros? – jameshfisher

Respuesta

66

En lugar de utilizar CURLOPT_PUT = TRUE uso CURLOPT_CUSTOMREQUEST = 'PUT' y CURLOPT_CUSTOMREQUEST = 'DELETE' valores establecidos a continuación, sólo con CURLOPT_POSTFIELDS.

3

Creo que estás mezclando tus verbos - PUT es para poner un archivo, POST es para publicar variables (aunque puedes ENVIAR un archivo).

Para establecer las variables de publicación, utilice CURLOPT_POSTFIELDS con una cadena de param1=val1&param2=val2 o una matriz asociativa.

para hacer un DELETE, tendrá que utilizar la opción de rizo CURLOPT_CUSTOMREQUEST

+1

PUT y DELETE admiten el envío de argumentos adicionales. Puedes hacer esto a través de la línea de comando cuando trabajas con curl, pero no puedo resolver cómo enviarlo con PHP-cURL. Por ejemplo, como esto es para REST, necesito una forma de marcar lo que elimino. Si elimino la identificación de usuario, quiero poder pasar la identificación sin saturar la URL. Las API como Twitter solo son compatibles con GET/POST, así que puedes poner eso en la URL, pero otras API REST pueden no ser compatibles con este tipo de cosas, así que tengo que enviar un parámetro de eliminación para ello. –

+1

Ok, tengo los parámetros PUT en funcionamiento, cambié CURLOPT_PUT = TRUE por CURLOPT_CUSTOMREQUEST = 'PUT' y eso funciona bien. Ahora, ¿cómo demonios configuro ELIMINAR? –

+0

CURLOPT_CUSTOMREQUEST = 'DELETE', luego use la cadena de consulta para los parámetros tal vez –

16

Solo recuerde, la mayoría de los servidores web no manejan las solicitudes PUT & DELETE. Como estás haciendo una biblioteca, te sugiero que pienses en explicar esto. Normalmente, hay dos convenciones que puede usar para imitar PUT & DELETE mediante POST.

  1. utilizar una variable de envío personalizado que anula la POST
  2. establecer una cabecera HTTP personalizado (ex X-HTTP-Method-Override.: PUT) (ex _method = PUT.)

En términos generales , la mayoría de los servicios RESTful que no permiten PUT & DELETE directamente serán compatibles con al menos una de esas estrategias. Puede usar cURL para establecer un encabezado personalizado si lo necesita a través de la opción CURLOPT_HTTPHEADER.

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

Gran addidtion, gracias Owen. –

+1

Has salvado a mi hombre de días. ¡Gracias! –

47

Aquí hay algunos códigos que pueden ser útiles para otros que quieran manejar los parámetros PUT y DELETE. Puede configurar $_PUT y $_DELETE a través de $GLOBALS[], pero no serán accesibles directamente en las funciones a menos que se declare global o se acceda a través de $GLOBALS[]. Para evitar esto, hice una clase simple para leer los argumentos de solicitud GET/POST/PUT/DELETE.Esto también rellena $_REQUEST con parámetros PUT/DELETE.

Esta clase analizará los parámetros PUT/DELETE y admitirá GET/POST también.

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; 
    } 
    } 
} 
+0

Esto está funcionando bien para mí. Gracias Bryan. – evanmcd

+0

Super Cool ... thnx :) –

1

Éste es cómo mi único problema BORRAR:

== >> en REST_Controller.php puedo reemplazar el delault _parse_delete() función de:

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

;) ¡esto funciona para mi!

+1

$ _DELETE ;? Acabo de recibir la variable de error indefinido: _DELETE –

0

Esta es mi versión del DELETE para CI. Se acepta GET-estilo argumentos de los, incluso mismos argumentos de nombre de borrar, es decir: 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; 
      } 
     } 
    } 
}