Pracuję nad moją biblioteką klienta REST dla CodeIgniter i staram się ustalić, jak wysyłać argumenty PUT i DELETE w PHP.
W kilku miejscach widziałem ludzi korzystających z opcji:
$this->option(CURLOPT_PUT, TRUE);
$this->option(CURLOPT_POSTFIELDS, $params);
Irytujące wydaje się, że to nic nie daje. Czy to właściwy sposób ustawiania parametrów PUT?
Jeśli tak, jak ustawić parametry DELETE?
$ this-> option () jest częścią mojej biblioteki, po prostu buduje tablicę stałych CURLOPT_XX i wysyła je do curl_setopt_array (), gdy zbudowane żądanie cURL jest wykonywane.
Próbuję odczytać parametry PUT i DELETE przy użyciu następującego kodu:
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;
Są tu dwie opcje, podchodzę do tego w niewłaściwy sposób lub gdzieś w moich bibliotekach jest błąd. Gdybyś mógł dać mi znać, czy to powinno teoretycznie zadziałać, mogę po prostu wkurzyć debugowanie, dopóki go nie rozwiążę.
Nie chcę tracić więcej czasu na podejście, które jest zasadniczo błędne.
źródło
POST
/DELETE
parametry, czy odbiórPOST
/DELETE
parametry?Odpowiedzi:
Zamiast używać
CURLOPT_PUT = TRUE
use,CURLOPT_CUSTOMREQUEST = 'PUT'
aCURLOPT_CUSTOMREQUEST = 'DELETE'
następnie po prostu ustaw wartości za pomocąCURLOPT_POSTFIELDS
.źródło
Oto kod, który może być pomocny dla innych, którzy chcą obsługiwać parametry PUT i DELETE. Możesz ustawić
$_PUT
i$_DELETE
za pośrednictwem$GLOBALS[]
, ale nie będą one bezpośrednio dostępne w funkcjach, chyba że zostaną zadeklarowaneglobal
lub dostępne za pośrednictwem$GLOBALS[]
. Aby obejść ten problem, stworzyłem prostą klasę do odczytywania argumentów żądań GET / POST / PUT / DELETE. To również zapełnia$_REQUEST
się parametrami PUT / DELETE.Ta klasa przeanalizuje parametry PUT / DELETE i będzie również obsługiwać 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; } } }
źródło
Pamiętaj tylko, że większość serwerów WWW nie obsługuje żądań PUT & DELETE. Ponieważ tworzysz bibliotekę, radzę pomyśleć o uwzględnieniu tego. Zwykle istnieją dwie konwencje, których można użyć do naśladowania operacji PUT & DELETE za pomocą POST.
Ogólnie rzecz biorąc, większość usług RESTful, które nie pozwalają bezpośrednio na PUT & DELETE, będzie obsługiwać co najmniej jedną z tych strategii. Możesz użyć cURL, aby ustawić niestandardowy nagłówek, jeśli potrzebujesz, za pomocą
CURLOPT_HTTPHEADER
opcji.// ex... curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-HTTP-Method-Override: PUT') );
źródło
Myślę, że mieszasz czasowniki - PUT służy do umieszczania pliku, POST służy do wysyłania zmiennych (chociaż możesz POST plik).
Aby ustawić zmienne post, użyj
CURLOPT_POSTFIELDS
z ciągiemparam1=val1¶m2=val2
lub tablicą asocjacyjną.Aby wykonać DELETE, będziesz chciał użyć opcji curl
CURLOPT_CUSTOMREQUEST
źródło
To jest moja wersja DELETE for CI. Przyjmuje argumenty w stylu GET dla DELETE, nawet te same argumenty nazw, np .: 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; } } } }
źródło
Oto jak rozwiązać problem z DELETE:
== >> w REST_Controller.php zastępuję funkcję delault _parse_delete () przez:
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); }
;) mi to pasuje!
źródło