2012-12-01 15 views
7

RESTful URLを処理する最も適切な方法が何であるか把握できません。RESTful URLのPHPの処理

http://localhost/products 
http://localhost/products/123 
http://localhost/products/123/color 

もともと:

RewriteRule ^([^/]*)([/])?([^/]*)?([/])?(.*)$ /index.php?handler=$1&productID=$3&additional=$5 [L,QSA] 

そして私は不可解だ:私はmod_rewriteのを使用している今のよう

http://localhost/index.php?handler=products&productID=123&additional=color 

私は、URLのこれらのように抱えていますindex.phpのリクエストをまとめて:

if ($_GET['handler'] == 'products' && isset($_GET['productID'])) { 
    // get product by its id. 
} 

私はいくつかのように1つの文字列としてGET-クエリを作成見てきました。そして、

if ($_GET['handler'] == 'products/123/color') 

、あなたが例えば行うクエリ文字列から値を取得するために正規表現を使うのか?

これは、これらのURLを処理するためのより良いアプローチですか? これらの異なるアプローチの長所と短所は何ですか? もっと良い方法がありますか?

+0

」これは私がこれらのタイプのURLが気に入らない理由です。このような位置パルムは、名前/値パームとしては扱いにくいものではありません。 '' –

答えて

6

preg_matchを使用してPHPで完全なリクエストパスに一致させることができるApacheの書き換えを使用して、すべてのパラメータを一致させる代わりに別のアプローチを使用できます。 PHP正規表現を適用すると、すべてのパラメータが$args配列に移動されます。

$request_uri = @parse_url($_SERVER['REQUEST_URI']); 
$path = $request_uri['path']; 
$selectors = array(
    "@^/products/(?P<productId>[^/]+)|/[email protected]" => 
      (array("GET" => "getProductById", "DELETE" => "deleteProductById")) 
); 

foreach ($selectors as $regex => $funcs) { 
    if (preg_match($regex, $path, $args)) { 
     $method = $_SERVER['REQUEST_METHOD']; 
     if (isset($funcs[$method])) { 
      // here the request is handled and the correct method called. 
      echo "calling ".$funcs[$method]." for ".print_r($args); 
      $output = $funcs[$method]($args); 
      // handling the output... 
     } 
    } 
} 

このアプローチは、多くの利点があります。

  • あなたが開発している各RESTサービスのリライトを持っていません。私は書き換えが好きですが、この場合は自由度が必要です。書き換えを使うと、新しいサービスを配備/インストールするたびにApacheの設定を変更する必要があります。
  • すべての着信要求に対して1つのPHPフロントエンドクラスを設定できます。フロントエンドは、すべての要求を正しいコントローラにディスパッチします。
  • 到着したリクエストに正規表現の配列を繰り返し適用し、正常な一致に応じて適切な関数またはクラスコントローラ/メソッドを呼び出すことができます。
  • 最後にコントローラがリクエストを処理するようにインスタンス化されると、

    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteCond %{REQUEST_FILENAME} !-d 
    RewriteRule . /index.php 
    

    を次にあなたにURLを変換するために、このような何かを行うことができます。これは.htaccessエントリはindex.phpに既存のファイル以外のすべてを送信しますhttpリクエスト

+0

コントローラのphpファイルを指すためにhtaccessのマッピングが必要なのですか、それともどのように配線されていますか? –

+1

@NickHumphreyすべてのリクエストはindex.php( 'DirectoryIndex'のデフォルトファイル)で処理できるので、本当に何かを' .htaccess 'にマップする必要はありません。まあ...あなたのWebサーバーは、少なくともPHPページを実行できる必要があります。したがって、このコードをindex.phpファイルに埋め込み、要求を正しいハンドラにディスパッチするだけで済みます。 – freedev

3

に使用されるHTTPメソッド配列:

$url_array = explode('/', $_SERVER['REQUEST_URI']); 
array_shift($url_array); // remove first value as it's empty 
array_pop($url_array); // remove last value as it's empty 

は次に、あなたは以下のようなものをスイッチを使用することができます。私は、一般的にとにかく仕事だ

switch ($url_array[0]) { 

    case 'products' : 
     // further products switch on url_array[1] if applicable 
     break; 

    case 'foo' : 
     // whatever 
     break; 

    default : 
     // home/login/etc 
     break; 

}