.htaccess重写GETvariables

我有一个index.php处理所有的路由index.php?page = controller(简化)只是为了与视图分离的逻辑。

Options +FollowSymlinks RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([\w\d~%.:_\-]+)$ index.php?page=$1 [NC] 

其中基本上: http://localhost/index.php?page = controller到

HTTP://本地主机/控制器/

任何人都可以帮我添加重写

http:// localhost / controller / param / value / param / value (和soforth)

那将是:

HTTP://本地主机/控制器/ PARAM =值&PARAM =值

我不能让它与重写软件一起工作。

一个控制器可能看起来像这样:

  <?php if (isset($_GET['action'])) { if ($_GET['action'] == 'delete') { do_Delete_stuff_here(); } } ?> 

并且:

  <?php if (isset($_GET['action']) && isset($_GET['x'])) { if ($_GET['action'] == 'delete') { do_Delete_stuff_here(); } } ?> 

基本上人们试图说的是,你可以这样做一个重写规则:

 RewriteRule ^(.*)$ index.php?params=$1 [NC] 

这将使你的实际的PHP文件如下所示:

 index.php?params=param/value/param/value 

而您的实际url将如下所示:

 http://url.com/params/param/value/param/value 

而在你的PHP文件中,你可以通过这样的爆炸来访问你的参数:

 <?php $params = explode( "/", $_GET['params'] ); for($i = 0; $i < count($params); $i+=2) { echo $params[$i] ." has value: ". $params[$i+1] ."<br />"; } ?> 

我认为如果你把所有请求redirect到index.php文件,然后使用php提取控制器名称和任何其他参数,会更好。 和其他框架一样,比如Zend Framework。

这是简单的课程,可以做你以后的事情。

 class HttpRequest { /** * default controller class */ const CONTROLLER_CLASSNAME = 'Index'; /** * position of controller */ protected $controllerkey = 0; /** * site base url */ protected $baseUrl; /** * current controller class name */ protected $controllerClassName; /** * list of all parameters $_GET and $_POST */ protected $parameters; public function __construct() { // set defaults $this->controllerClassName = self::CONTROLLER_CLASSNAME; } public function setBaseUrl($url) { $this->baseUrl = $url; return $this; } public function setParameters($params) { $this->parameters = $params; return $this; } public function getParameters() { if ($this->parameters == null) { $this->parameters = array(); } return $this->parameters; } public function getControllerClassName() { return $this->controllerClassName; } /** * get value of $_GET or $_POST. $_POST override the same parameter in $_GET * * @param type $name * @param type $default * @param type $filter * @return type */ public function getParam($name, $default = null) { if (isset($this->parameters[$name])) { return $this->parameters[$name]; } return $default; } public function getRequestUri() { if (!isset($_SERVER['REQUEST_URI'])) { return ''; } $uri = $_SERVER['REQUEST_URI']; $uri = trim(str_replace($this->baseUrl, '', $uri), '/'); return $uri; } public function createRequest() { $uri = $this->getRequestUri(); // Uri parts $uriParts = explode('/', $uri); // if we are in index page if (!isset($uriParts[$this->controllerkey])) { return $this; } // format the controller class name $this->controllerClassName = $this->formatControllerName($uriParts[$this->controllerkey]); // remove controller name from uri unset($uriParts[$this->controllerkey]); // if there are no parameters left if (empty($uriParts)) { return $this; } // find and setup parameters starting from $_GET to $_POST $i = 0; $keyName = ''; foreach ($uriParts as $key => $value) { if ($i == 0) { $this->parameters[$value] = ''; $keyName = $value; $i = 1; } else { $this->parameters[$keyName] = $value; $i = 0; } } // now add $_POST data if ($_POST) { foreach ($_POST as $postKey => $postData) { $this->parameters[$postKey] = $postData; } } return $this; } /** * word seperator is '-' * convert the string from dash seperator to camel case * * @param type $unformatted * @return type */ protected function formatControllerName($unformatted) { if (strpos($unformatted, '-') !== false) { $formattedName = array_map('ucwords', explode('-', $unformatted)); $formattedName = join('', $formattedName); } else { // string is one word $formattedName = ucwords($unformatted); } // if the string starts with number if (is_numeric(substr($formattedName, 0, 1))) { $part = $part == $this->controllerkey ? 'controller' : 'action'; throw new Exception('Incorrect ' . $part . ' name "' . $formattedName . '".'); } return ltrim($formattedName, '_'); } } 

如何使用它:

 $request = new HttpRequest(); $request->setBaseUrl('/your/base/url/'); $request->createRequest(); echo $request->getControllerClassName(); // return controller name. Controller name separated by '-' is going to be converted to camel case. var_dump ($request->getParameters()); // print all other parameters $_GET & $_POST 

.htaccess文件:

 RewriteEngine On RewriteCond %{REQUEST_FILENAME} -s [OR] RewriteCond %{REQUEST_FILENAME} -l [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^.*$ - [NC,L] RewriteRule ^.*$ index.php [NC,L] 

您的重写规则会传递整个url:

 RewriteRule ^(.*)$ index.php?params=$1 [NC] 

你的index.php会将你的完整path解释为controller / param / value / param / value(我的PHP有点生疏):

 $params = explode("/", $_GET['params']); if (count($params) % 2 != 1) die("Invalid path length!"); $controller = $params[0]; $my_params = array(); for ($i = 1; $i < count($params); $i += 2) { $my_params[$params[$i]] = $params[$i + 1]; } 

如何redirect到index.php?params=param/value/param/value ,并让PHP分裂整个$_GET['params'] ? 我认为这是wordpress处理它的方式。

这是你想要的吗?

这个例子演示了如何使用循环标志容易地隐藏查询string参数。 假设您有像http://www.mysite.com/foo.asp?a=A&b=B&c=C这样的URL,并且您想以http://www.myhost.com/foo.asp/a/A的身份访问它/ b / b / C / C

尝试以下规则以达到所需的结果:

RewriteRule ^(.*?\.php)/([^/]*)/([^/]*)(/.+)? $1$4?$2=$3 [NC,N,QSA]

出于某种原因,选定的解决scheme不适合我。 它会不断返回“index.php”作为params的值。

经过一些试验和错误,我发现以下规则运作良好。 假设您希望yoursite.com/somewhere/var1/var2/var3指向yoursite.com/somewhere/index.php?params=var1/var2/var3,然后将以下规则放在.htaccess文件的“某处”目录:

 Options +FollowSymLinks RewriteEngine On # The first 2 conditions may or may not be relevant for your needs # If the request is not for a valid file RewriteCond %{REQUEST_FILENAME} !-d # If the request is not for a valid directory RewriteCond %{REQUEST_FILENAME} !-f # This rule converts your flat link to a query RewriteRule ^(.*)$ index.php?params=$1 [L,NC,NE] 

然后,在PHP或者您select的语言中,只需使用@Wesso指出的explode命令分开这些值即可。

出于testing目的,这应该足以在你的index.php文件中:

 if (isset($_GET['params'])) { $params = explode( "/", $_GET['params'] ); print_r($params); exit("YUP!"); } 

你确定你使用的是Apache服务器,.htaccess只能在Apache服务器上运行。 如果您使用IIS,则需要web.config。 在这种情况下:

 <?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <rewrite> <rules> <rule name="Homepage"> <match url="Homepage"/> <action type="Rewrite" url="index.php" appendQueryString="true"/> </rule> </rules> </rewrite> <httpErrors errorMode="Detailed"/> <handlers> <add name="php" path="*.php" verb="*" modules="IsapiModule" scriptProcessor="C:\Program Files\Parallels\Plesk\Additional\PleskPHP5\php5isapi.dll" resourceType="Unspecified"/> </handlers> </system.webServer> </configuration>