.htaccess de réécriture d'OBTENIR des variables

j'ai un index.php qui gère tout l'index de routage.le php?page=contrôleur (simplifié) pour séparer la logique de la vue.

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

ce qui essentiellement: http://localhost/index.le php?page=contrôleur

http://localhost/controller/

quelqu'un Peut-il m'aider à ajouter de la Réécriture pour

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

Qui serait être:

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

je ne peux pas le faire fonctionner avec des règles de réécriture.

Un contrôleur pourrait ressembler à ceci:

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

Et aussi:

    <?php
if (isset($_GET['action']) && isset($_GET['x'])) {
 if ($_GET['action'] == 'delete') {
do_Delete_stuff_here();
}
}
?>
25
demandé sur Tim Stone 2011-10-06 19:58:01

7 réponses

fondamentalement ce que les gens essaient de dire est, vous pouvez faire une règle de réécriture comme ceci:

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

Cela rendra votre fichier php comme ceci:

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

Et votre réelle adresse URL sera comme ceci:

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

Et dans votre fichier PHP, vous pouvez accéder à votre params par l'explosion de cette manière:

<?php

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

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

}

?>
44
répondu Wesley 2011-10-30 15:28:23

je pense que c'est mieux si vous rediriger toutes les requêtes à l'index.php, puis extraire le nom du contrôleur et tout autre paramètre en utilisant php. Comme tous les autres cadres tels que Zend Framework.

Voici une classe simple qui peut faire ce que vous recherchez.

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

Comment l'utiliser:

$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]
11
répondu satrun77 2011-11-01 00:10:00

votre règle de réécriture passerait l'URL entière:

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

votre index.php interpréterait ce chemin complet comme controller/param/value/param / value pour vous (mon PHP est un peu rouillé):

$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];
}
7
répondu Kevin Stricker 2011-11-03 16:58:51

Comment rediriger index.php?params=param/value/param/value, et que php divise le tout $_GET['params']? Je pense que c'est la façon dont wordpress manipulation.

6
répondu Rufus 2011-10-06 16:16:41

Est-ce ce que vous cherchez?

cet exemple montre comment masquer facilement les paramètres de la chaîne de requête en utilisant le drapeau de boucle. Supposons que vous avez une URL de la forme http://www.mysite.com/foo.asp?a=A&b=B&c=C et vous souhaitez accéder à http://www.myhost.com/foo.asp/a/A/b/B/c/C

essayez la règle suivante pour obtenir le résultat désiré:

RewriteRule ^(.*?\.php)/([^/]*)/([^/]*)(/.+)? ?= [NC,N,QSA]

5
répondu Doug Chamberlain 2011-11-03 14:21:12

pour une raison quelconque, la solution choisie n'a pas fonctionné pour moi. Il ne retournerait constamment " index.php " comme valeur de params.

Après quelques essais et erreurs, j'ai trouvé les règles suivantes pour bien travailler. En supposant que vous souhaitez yoursite.com/somewhere/var1/var2/var3 du point de yoursite.com/somewhere/index.php?params=var1/var2/var3 puis placez la règle suivante dans un .fichier htaccess dans le répertoire "somewhere":

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]

alors, en PHP ou dans n'importe quelle langue de votre choix, il suffit de séparer les valeurs en utilisant la commande explode comme indiqué par @Wesso.

à des fins de test, cela devrait suffire dans votre index.fichier php:

if (isset($_GET['params']))
{
    $params = explode( "/", $_GET['params'] );
    print_r($params);
    exit("YUP!");
}
3
répondu Nick 2013-01-04 15:30:46

Êtes-vous sûr d'utiliser apache server,.htaccess ne fonctionne que sur le serveur apache. Si vous utilisez IIS alors web.la config est reqired. Dans ce cas:

<?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>
1
répondu Sibu 2011-10-31 11:52:49