我无法掌握处理RESTful网址的最佳方式。
我的网址是这样的:
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.
}
我见过有人将GET查询创建为一个字符串,如:
if ($_GET['handler'] == 'products/123/color')
然后,您是否使用正则表达式从查询字符串中获取值?
这是处理这些网址的更好方法吗? 这些不同方法的优缺点是什么? 还有更好的方法吗?
答案 0 :(得分:6)
您可以使用不同的方法而不是匹配所有参数使用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;
}
}
这种方法有很多好处:
答案 1 :(得分:4)
此.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;
}
这就是我一般所做的事情。