Подтвердить что ты не робот

.htaccess переписать переменные GET

У меня есть 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/

Может кто-нибудь помочь мне добавить Rewrite для

http://localhost/controller/param/value/param/value (и так далее)

Это будет:

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

Я не могу заставить его работать с Rewriterule.

Контроллер может выглядеть так:

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

Ответ 1

По сути, люди пытаются сказать, что вы можете создать правило переписывания следующим образом:

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 />";

}

?>

Ответ 2

Мне кажется, что лучше перенаправить все запросы в файл 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]

Ответ 3

Ваше правило перезаписи будет содержать весь URL-адрес:

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

Ваш index.php будет интерпретировать этот полный путь как 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];
}

Ответ 4

Как насчет перенаправления на index.php?params=param/value/param/value, и пусть php разбивает все $_GET['params']? Я думаю, что это способ обработки WordPress.

Ответ 5

Это то, что вы ищете?

В этом примере показано, как легко скрыть параметры строки запроса с помощью флага цикла. Предположим, у вас есть 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]

Ответ 6

По какой-то причине выбранное решение не сработало для меня. Он постоянно возвращал бы "index.php" как значение параметров.

После некоторых проб и ошибок, я нашел следующие правила, чтобы работать хорошо. Предполагая, что вы хотите, чтобы 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 или любом другом языке по вашему выбору, просто отделяйте значения, используя команду explode, как указано @Wesso.

Для целей тестирования это должно быть достаточно в файле index.php:

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

Ответ 7

Вы уверены, что используете сервер 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>