use*_*487 7 php rest url mod-rewrite query-string
我无法掌握处理RESTful url的最合适方式.
我有这样的网址:
http://localhost/products
http://localhost/products/123
http://localhost/products/123/color
Run Code Online (Sandbox Code Playgroud)
本来:
http://localhost/index.php?handler=products&productID=123&additional=color
Run Code Online (Sandbox Code Playgroud)
至于现在我正在使用mod_rewrite:
RewriteRule ^([^/]*)([/])?([^/]*)?([/])?(.*)$ /index.php?handler=$1&productID=$3&additional=$5 [L,QSA]
Run Code Online (Sandbox Code Playgroud)
然后我把index.php中的请求拼凑起来,比如:
if ($_GET['handler'] == 'products' && isset($_GET['productID'])) {
// get product by its id.
}
Run Code Online (Sandbox Code Playgroud)
我见过有人创建一个GET查询作为一个字符串,如:
if ($_GET['handler'] == 'products/123/color')
Run Code Online (Sandbox Code Playgroud)
那么,您是否使用正则表达式从查询字符串中获取值?
这是处理这些网址的更好方法吗?这些不同方法的优缺点是什么?有更好的方法吗?
您可以使用不同的方法而不是匹配所有参数使用apache重写您可以使用preg_match匹配PHP中的完整请求路径.应用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;
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法有很多好处:
这个 .htaccess 条目会将除现有文件之外的所有内容发送到 index.php:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php
Run Code Online (Sandbox Code Playgroud)
然后你可以做这样的事情来将 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
Run Code Online (Sandbox Code Playgroud)
然后你可以这样使用开关:
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;
}
Run Code Online (Sandbox Code Playgroud)
反正我一般都是这么干的。
| 归档时间: |
|
| 查看次数: |
2861 次 |
| 最近记录: |