php .htaccess 重写 GET 变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7677070/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 03:09:23  来源:igfitidea点击:

.htaccess rewrite GET variables

php.htaccessmod-rewrite

提问by John

I have a index.php which handle all the routing index.php?page=controller (simplified) just to split up the logic with the view.

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

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

Which basically: http://localhost/index.php?page=controllerTo

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

http://localhost/controller/

http://localhost/controller/

Can anyone help me add the Rewrite for

谁能帮我添加重写

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

http://localhost/controller/param/value/param/value(等等)

That would be:

那将是:

http://localhost/controller/?param=value&param=value

http://localhost/controller/?param=value¶m=value

I can't get it to work with the Rewriterule.

我无法让它与 Rewriterule 一起使用。

A controller could look like this:

控制器可能如下所示:

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

And also:

并且:

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

回答by Wesley

Basically what people try to say is, you can make a rewrite rule like so:

基本上人们想说的是,您可以像这样制定重写规则:

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

This will make your actual php file like so:

这将使您的实际 php 文件如下所示:

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

And your actual URL would be like so:

你的实际 URL 是这样的:

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

And in your PHP file you could access your params by exploding this like so:

在你的 PHP 文件中,你可以通过像这样分解来访问你的参数:

<?php

$params = explode( "/", $_GET['params'] );
for($i = 0; $i < count($params); $i+=2) {

  echo $params[$i] ." has value: ". $params[$i+1] ."<br />";

}

?>

回答by satrun77

I think it's better if you redirect all requests to the index.php file and then extract the controller name and any other parameters using php. Same as any other frameworks such as Zend Framework.

我认为最好将所有请求重定向到 index.php 文件,然后使用 php 提取控制器名称和任何其他参数。与 Zend Framework 等任何其他框架相同。

Here is simple class that can do what you are after.

这是一个简单的课程,可以做你想做的事。

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, '_');
    }
}

How to use it:

如何使用它:

$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 file:

.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]

回答by Kevin Stricker

Your rewrite rule would pass the entire URL:

您的重写规则将传递整个 URL:

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

Your index.php would interpret that full path as controller/param/value/param/value for you (my PHP is a little rusty):

您的 index.php 会将完整路径解释为您的控制器/参数/值/参数/值(我的 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];
}

回答by Rufus

How about redirect to index.php?params=param/value/param/value, and let php split the whole $_GET['params']? I think this is the way wordpress handling it.

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

回答by Doug Chamberlain

Is this what your looking for?

这是您要找的吗?

This example demonstrates how to easily hide query string parameters using loop flag. Suppose you have URL like http://www.mysite.com/foo.asp?a=A&b=B&c=Cand you want to access it as http://www.myhost.com/foo.asp/a/A/b/B/c/C

此示例演示如何使用循环标志轻松隐藏查询字符串参数。假设你有像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

Try the following rule to achieve desired result:

尝试以下规则以获得所需的结果:

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

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

回答by Nick

For some reason, the selected solution did not work for me. It would constantly only return "index.php" as value of params.

出于某种原因,所选的解决方案对我不起作用。它会不断地只返回“index.php”作为参数的值。

After some trial and error, I found the following rules to work well. Assuming you want yoursite.com/somewhere/var1/var2/var3 to point to yoursite.com/somewhere/index.php?params=var1/var2/var3, then place the following rule in a .htaccess file in the "somewhere" directory:

经过一些试验和错误,我发现以下规则可以很好地工作。假设您希望 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= [L,NC,NE]

Then, in PHP or whichever language of your choice, simply separate the values using the explode command as pointed out by @Wesso.

然后,在 PHP 或您选择的任何语言中,只需使用 @Wesso 指出的爆炸命令分隔值。

For testing purposes, this should suffice in your index.php file:

出于测试目的,这在您的 index.php 文件中就足够了:

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

回答by Sibu

Are you sure you are using apache server,.htaccess works only on apache server. If you are using IIS then web.config is reqired. In that case:

您确定您使用的是 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>