web-dev-qa-db-ja.com

PHPでのPUT / DELETE引数の処理

私は 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;

ここには2つのオプションがあります。間違った方法でこれに近づいているか、ライブラリのどこかにバグがあります。これが理論的に機能するかどうかを教えていただければ、解決するまでデバッグに打ち込むことができます。

基本的に間違っているアプローチにこれ以上時間を無駄にしたくありません。

83
Phil Sturgeon

CURLOPT_PUT = TRUEを使用する代わりに、CURLOPT_CUSTOMREQUEST = 'PUT'CURLOPT_CUSTOMREQUEST = 'DELETE'を使用し、CURLOPT_POSTFIELDSで値を設定するだけです。

68
Phil Sturgeon

PUTおよびDELETEパラメータを処理したい他の人に役立つかもしれないいくつかのコードがあります。 $_PUT$_DELETE$GLOBALS[]経由で設定できますが、globalを宣言するか、$GLOBALS[]経由でアクセスしない限り、関数で直接アクセスできません。これを回避するために、GET/POST/PUT/DELETEリクエスト引数を読み取るための簡単なクラスを作成しました。また、$_REQUESTにPUT/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;
    }
  }
}
48
Bryan Drewery

覚えておいてください、ほとんどのウェブサーバーはPUT&DELETEリクエストを処理しません。あなたは図書館を作っているので、このための会計処理について考えることをお勧めします。通常、POSTを介してPUT&DELETEを模倣するために使用できる2つの規則があります。

  1. pOSTをオーバーライドするカスタムPOST変数(例:_METHOD = PUT)を使用する
  2. カスタムHTTPヘッダーを設定します(例:X-HTTP-Method-Override:PUT)

一般的に、PUTおよびDELETEを直接許可しないほとんどのRESTfulサービスは、これらの戦略の少なくとも1つをサポートします。 CURLOPT_HTTPHEADERオプションを介して必要な場合、cURLを使用してカスタムヘッダーを設定できます。

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

私はあなたの動詞を混ぜていると思います-PUTはファイルを置くため、POSTは変数を投稿するためです(ただし、POSTファイル))。

ポスト変数を設定するには、CURLOPT_POSTFIELDSの文字列または連想配列のいずれかでparam1=val1&param2=val2を使用します。

DELETEを実行するには、カールオプションCURLOPT_CUSTOMREQUESTを使用します。

3
Adam Hopkinson

これは私のDELETE問題をどのように解決するかです:

== >> in REST_Controller.php iをデフォルトの_ 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
okobsamoht

これは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
Patrick Savalle