.htaccess 重写 GET 变量

发布于 2024-12-08 15:50:57 字数 1193 浏览 0 评论 0 原文

我有一个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://localhost/controller/

的重写

任何人都可以帮我添加http://localhost/controller/param/value/param/value (等等)

那就是:

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

我无法让它与重写规则一起使用。

控制器可能如下所示:

    <?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();
}
}
?>

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

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

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

http://localhost/controller/

Can anyone help me add the Rewrite for

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

That would be:

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

I can't get it to work with the 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();
}
}
?>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

比忠 2024-12-15 15:50:57

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

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

这将使你的实际 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 />";

}

?>

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

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

This will make your actual php file like so:

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

And your actual URL would be like so:

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

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

<?php

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

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

}

?>
深者入戏 2024-12-15 15:50:57

我认为最好将所有请求重定向到 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]

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.

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:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
無處可尋 2024-12-15 15:50:57

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

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

您的 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];
}

Your rewrite rule would pass the entire URL:

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

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

$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];
}
月寒剑心 2024-12-15 15:50:57

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

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.

绝情姑娘 2024-12-15 15:50:57

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

经过一番尝试和错误后,我发现以下规则效果很好。假设您希望 yoursite.com/somewhere/var1/var2/var3 指向 yoursite.com/somewhere/index.php?params=var1/var2/var3,然后将以下规则放入“somewhere”中的 .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 或您选择的任何语言中,只需使用爆炸命令分隔值,如 @Wesso 所指出的。

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

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

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

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:

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]

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

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

if (isset($_GET['params']))
{
    $params = explode( "/", $_GET['params'] );
    print_r($params);
    exit("YUP!");
}
∝单色的世界 2024-12-15 15:50:57

这是您要找的吗?

此示例演示如何使用循环标志轻松隐藏查询字符串参数。假设您的 URL 类似于 http://www.mysite。 com/foo.asp?a=A&b=B&c=C 并且您希望以 http://www.myhost.com/foo.asp/a/A/b/B/c/C

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

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

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=C and you want to access it as 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]

暮色兮凉城 2024-12-15 15:50:57

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

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:

<?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>
那支青花 2024-12-15 15:50:57

使用 QSA

blabla.php?originalquery=333
RewriteRule ^blabla.php index.php?addnewquery1=111&addnewquery2=222 [L、NC、QSA]
您将获得全部 111,222,333

use QSA

blabla.php?originialquery=333
RewriteRule ^blabla.php index.php?addnewquery1=111&addnewquery2=222 [L,NC,QSA]
you will get all 111,222,333

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文