PHP'de PUT / DELETE bağımsız değişkenlerini işleme


84

Benim üzerinde çalışıyorum CodeIgniter REST istemcisi, kütüphanede ve PHP PUT ve DELETE argümanları göndermek için nasıl çalışmak mücadele ediyorum.

Birkaç yerde seçenekleri kullanan insanlar gördüm:

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

Can sıkıcı bir şekilde, bu hiçbir şey yapmıyor gibi görünüyor. PUT parametrelerini ayarlamanın doğru yolu bu mu?

Öyleyse, DELETE parametrelerini nasıl ayarlarım?

$ this-> option () kitaplığımın bir parçası, basitçe bir CURLOPT_XX sabiti dizisi oluşturur ve oluşturulan cURL isteği yürütüldüğünde bunları curl_setopt_array () 'e gönderir.

Aşağıdaki kodu kullanarak PUT ve DELETE parametrelerini okumaya çalışıyorum:

        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;

Burada iki seçenek var, buna yanlış bir şekilde yaklaşıyorum veya kütüphanelerimin bir yerinde bir hata var. Bunun teorik olarak işe yarayıp yaramayacağını bana bildirirseniz, çözene kadar hata ayıklama üzerinde çalışabilirim.

Temelde yanlış olan bir yaklaşım için daha fazla zaman harcamak istemiyorum.


PUT iyi çalışıyor, şimdi ayarlama konusunda endişelenmek için parametreleri SİLİN.
Phil Sturgeon

1
Bu soru kafa karıştırıcı. Bu konuda mı gönderme POST / DELETEparametreleri veya alıcı POST / DELETEparametrelerini?
jameshfisher

Yanıtlar:


68

Bunun yerine kullanmanın CURLOPT_PUT = TRUEkullanımını CURLOPT_CUSTOMREQUEST = 'PUT' ve CURLOPT_CUSTOMREQUEST = 'DELETE'ile sonra sadece ayarlanan değerleri CURLOPT_POSTFIELDS.


API / sunucu tarafında POSTFIELDS'i nasıl alırım?
Daniel

48

İşte PUT ve DELETE parametrelerini işlemek isteyenler için yararlı olabilecek bazı kodlar. Ayarlayabilir $_PUTve $_DELETEüzerinden erişebilirsiniz $GLOBALS[], ancak bildirilmedikçe globalveya aracılığıyla erişilmedikçe işlevlerde doğrudan erişilebilir olmayacaklardır $GLOBALS[]. Bunu aşmak için GET / POST / PUT / DELETE istek argümanlarını okumak için basit bir sınıf yaptım. Bu aynı zamanda $_REQUESTPUT / DELETE parametreleriyle de doldurulur .

Bu sınıf PUT / DELETE parametrelerini ayrıştıracak ve GET / POST'u da destekleyecektir.

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

Unutmayın, çoğu web sunucusu PUT & DELETE isteklerini işlemez. Bir kütüphane kurduğunuz için, bunun muhasebesini düşünmenizi öneririm. Genellikle, POST yoluyla PUT & DELETE'i taklit etmek için kullanabileceğiniz iki kural vardır.

  1. POST'u geçersiz kılan özel bir POST değişkeni (ör. _METHOD = PUT) kullanın
  2. özel bir HTTP üst bilgisi ayarlayın (ör. X-HTTP-Method-Override: PUT)

Genel olarak, PUT & DELETE'e doğrudan izin vermeyen çoğu RESTful hizmeti bu stratejilerden en az birini destekleyecektir. CURLOPT_HTTPHEADERSeçenek aracılığıyla ihtiyacınız varsa özel bir başlık ayarlamak için cURL'yi kullanabilirsiniz .

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

3

Sanırım fiillerinizi karıştırıyorsunuz - PUT bir dosya koymak içindir, POST değişkenleri göndermek içindir (bir dosyayı POST yapabilmenize rağmen).

Post değişkenlerini ayarlamak için, CURLOPT_POSTFIELDSbir dizi param1=val1&param2=val2veya bir ilişkilendirilebilir dizi kullanın.

SİLME yapmak için curl seçeneğini kullanmak isteyeceksiniz CURLOPT_CUSTOMREQUEST


1
PUT ve DELETE, ek argümanların gönderilmesini destekler. Curl ile çalışırken bunu komut satırı aracılığıyla yapabilirsiniz, ancak PHP-cURL ile nasıl gönderileceğini çözemiyorum. Örneğin, bu REST için olduğu için, neyi sildiğimi işaretlemek için bir yola ihtiyacım var. Kullanıcı kimliğini siliyorsam, URL'yi karıştırmadan kimliği iletebilmek istiyorum. Twitter gibi API'ler yalnızca GET / POST'u destekliyor, bu yüzden URL'ye koyabilirsiniz, ancak diğer REST API'leri bu tür şeyleri desteklemeyebilir, bu yüzden bunun için bir silme parametresi göndermem gerekiyor.
Phil Sturgeon

1
Tamam, çalışan PUT parametrelerim var, CURLOPT_CUSTOMREQUEST = 'PUT' ile CURLOPT_PUT = TRUE değiştirdim ve bu iyi çalışıyor. Şimdi, nasıl SİL ayarlayabilirim?
Phil Sturgeon

CURLOPT_CUSTOMREQUEST = 'DELETE', sonra parametreler için sorgu dizesi kullanın belki
Adam Hopkinson

1
Kapat, daha önce bahsettiğim gibi onları sorgu dizesinde kullanmaktan kaçınmaya çalışıyordum. CURLOPT_CUSTOMREQUEST = 'DELETE kullanırken PUT ve DELETE ile CURLOPT_POSTFIELDS kullanabileceğiniz ortaya çıktı. Geri bildiriminiz için teşekkürler, ama sonunda kendim
çözdüm

2
Yaptın mı O zaman hiç yardım etmedim mi?
Adam Hopkinson

2

Bu benim CI için DELETE sürümüm. DELETE için GET-tarzı argümanları, hatta aynı isim argümanlarını kabul eder, yani: GET / some / url? İd = 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 sorunumu şu şekilde çözüyorum:

== >> REST_Controller.php içinde delault _parse_delete () işlevini şu şekilde değiştiriyorum :

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

;) benim için çalışıyor!


1
$ _DELETE ;? Sadece hata tanımlanmamış değişken olsun: _DELETE
Valor_
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.