PHPでのPUT / DELETE引数の処理


84

私は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つのオプションがあります。間違った方法でこれにアプローチしているか、ライブラリのどこかにバグがあります。これが理論的に機能するかどうかを教えていただければ、解決するまでデバッグを槌で打つことができます。

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


PUTは正常に機能しています。パラメータを削除するだけで、設定について心配する必要があります。
Phil Sturgeon

1
この質問は紛らわしいです。/パラメータの送信 についてですか、それとも/パラメータの受信についてですか?POSTDELETE POSTDELETE
jameshfisher 2014年

回答:


68

CURLOPT_PUT = TRUEuseを使用する代わりに、。を使用CURLOPT_CUSTOMREQUEST = 'PUT' してCURLOPT_CUSTOMREQUEST = 'DELETE'値を設定しますCURLOPT_POSTFIELDS


API /サーバー側でPOSTFIELDを受信するにはどうすればよいですか?
ダニエル

48

これは、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;
    }
  }
}

16

ほとんどのウェブサーバーは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') );

3

動詞を混ぜていると思います-PUTはファイルを置くためのものであり、POSTは変数を投稿するためのものです(ファイルをPOSTすることはできますが)。

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

DELETEを実行するには、curlオプションを使用する必要があります CURLOPT_CUSTOMREQUEST


1
PUTとDELETEはどちらも、追加の引数の送信をサポートしています。curlを使用する場合はコマンドラインからこれを行うことができますが、PHP-cURLを使用して送信する方法がわかりません。たとえば、これはRESTの場合なので、削除するものにマークを付ける方法が必要です。ユーザーIDを削除する場合、URLを乱雑にすることなくIDを渡せるようにしたいです。TwitterのようなAPIはGET / POSTのみをサポートしているため、URLに含めることができますが、他のREST APIはこの種の機能をサポートしていない可能性があるため、削除パラメーターを送信する必要があります。
Phil Sturgeon

1
OK、PUTパラメータが機能しています。CURLOPT_PUT= TRUEをCURLOPT_CUSTOMREQUEST = 'PUT'に交換しましたが、正常に機能しています。さて、どうやってDELETEを設定するのですか?
Phil Sturgeon

CURLOPT_CUSTOMREQUEST = 'DELETE'、次にパラメータにクエリ文字列を使用する可能性があります
Adam Hopkinson 2010年

1
最後に、すでに述べたように、クエリ文字列でそれらを使用しないようにしようとしていました。CURLOPT_CUSTOMREQUEST = 'DELETEを使用すると、PUTおよびDELETEとともにCURLOPT_POSTFIELDSを使用できることがわかります。フィードバックをありがとうございますが、最終的には自分で解決しました:-)
Phil Sturgeon

2
しましたか?私はその時全く助けませんでしたか?
アダムホプキンソン

2

これは私のバージョンのDELETEforCIです。同じ名前の引数であっても、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

これは私が私のDELETE問題を解決する方法です:

== >> REST_Controller.phpで、delault _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
$ _DELETE;?未定義の変数エラーが発生します:_DELETE
Valor_ 2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.