Je travaille sur ma bibliothèque cliente REST pour CodeIgniter et j'ai du mal à trouver comment envoyer les arguments PUT et DELETE en PHP.
Dans quelques endroits, j'ai vu des gens utiliser les options:
$this->option(CURLOPT_PUT, TRUE);
$this->option(CURLOPT_POSTFIELDS, $params);
Chose ennuyeuse, cela semble ne rien faire. Est-ce la bonne façon de définir les paramètres PUT?
Si oui, comment définir les paramètres DELETE?
$ this-> option () fait partie de ma bibliothèque, il construit simplement un tableau de constantes CURLOPT_XX et les envoie à curl_setopt_array () lorsque la requête cURL construite est exécutée.
J'essaie de lire les paramètres PUT et DELETE en utilisant le code suivant:
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;
Il y a deux options ici, j'aborde cette question de la mauvaise façon ou il y a un bug quelque part dans mes bibliothèques. Si vous pouviez me faire savoir si cela devrait théoriquement fonctionner, je peux simplement marteler le débogage jusqu'à ce que je le résolve.
Je ne veux pas perdre plus de temps sur une approche qui est fondamentalement erronée.
À la place d'utiliser CURLOPT_PUT = TRUE
utilisation CURLOPT_CUSTOMREQUEST = 'PUT'
et CURLOPT_CUSTOMREQUEST = 'DELETE'
puis définissez simplement les valeurs avec CURLOPT_POSTFIELDS
.
Voici du code qui peut être utile pour ceux qui souhaitent gérer les paramètres PUT et DELETE. Vous pouvez définir $_PUT
et $_DELETE
via $GLOBALS[]
, mais ils ne seront pas directement accessibles dans les fonctions sauf s'ils sont déclarés global
ou accessibles via $GLOBALS[]
. Pour contourner ce problème, j'ai créé une classe simple pour lire les arguments de requête GET/POST/PUT/DELETE. Cela remplit également $_REQUEST
avec les paramètres PUT/DELETE.
Cette classe analysera les paramètres PUT/DELETE et prendra également en charge 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;
}
}
}
N'oubliez pas que la plupart des serveurs Web ne traitent pas les demandes PUT & DELETE. Puisque vous créez une bibliothèque, je vous suggère de penser à en tenir compte. En règle générale, il existe deux conventions que vous pouvez utiliser pour imiter PUT & DELETE via POST.
De manière générale, la plupart des services RESTful qui n'autorisent pas directement PUT & DELETE prendront en charge au moins une de ces stratégies. Vous pouvez utiliser cURL pour définir un en-tête personnalisé si vous en avez besoin via le CURLOPT_HTTPHEADER
option.
// ex...
curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-HTTP-Method-Override: PUT') );
Je pense que vous mélangez vos verbes - PUT est pour mettre un fichier, POST est pour poster des variables (bien que vous puissiez POST un fichier).
Pour définir les variables de publication, utilisez CURLOPT_POSTFIELDS
avec soit une chaîne de param1=val1¶m2=val2
ou un tableau associatif.
Pour effectuer une suppression, vous devez utiliser l'option curl CURLOPT_CUSTOMREQUEST
Voici comment je résous mon problème DELETE:
== >> dans REST_Controller.php je remplace la fonction par défaut _ parse delete () par:
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);
}
;) ça marche pour moi!
Ceci est ma version de DELETE for CI. Il accepte les arguments de style GET pour la suppression, même les arguments du même nom, c'est-à-dire: 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;
}
}
}
}