7

RESTful URL を処理する最も適切な方法を把握するのに苦労しています。

私は次のようなURLを持っています:

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

元は:

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

今のところ、私は mod_rewrite を使用しています:

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

そして、次のような index.php でリクエストをまとめています。

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

次のような 1 つの文字列として GET クエリを作成する例を見てきました。

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

次に、たとえば正規表現を使用してクエリ文字列から値を取得しますか?

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

4

2 に答える 2

6

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

$request_uri = @parse_url($_SERVER['REQUEST_URI']);
$path = $request_uri['path'];
$selectors = array(
     "@^/products/(?P<productId>[^/]+)|/?$@" => 
            (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...
        }
        break;
     }
}

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

  • 開発中の REST サービスごとに書き直す必要はありません。私は書き換えが好きですが、この場合は多くの自由が必要であり、書き換えを使用すると、新しいサービスをデプロイ/維持するたびに Apache 構成を変更する必要があります。
  • すべての受信リクエストに対して単一の PHP フロントエンド クラスを使用できます。フロントエンドはすべてのリクエストを正しいコントローラーにディスパッチします。
  • 着信リクエストに正規表現の配列を繰り返し適用し、成功した一致に応じて正しい関数またはクラスコントローラー/メソッドを呼び出すことができます
  • 最終的にコントローラーがリクエストを処理するためにインスタンス化されると、ここで http リクエストに使用される HTTP メソッドを確認できます。
于 2012-12-01T00:21:55.470 に答える
6

この .htaccess エントリは、既存のファイルを除くすべてを index.php に送信します。

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

次に、次のようにして URL を配列に変換できます。

$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;

}

それはとにかく私が一般的にしていることです。

于 2012-12-01T00:27:42.513 に答える