Reputation: 3060
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
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();
}
}
?>
Upvotes: 30
Views: 112125
Reputation: 623
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
Upvotes: -1
Reputation: 2200
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 />";
}
?>
Upvotes: 54
Reputation: 2613
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!");
}
Upvotes: 6
Reputation: 17388
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];
}
Upvotes: 10
Reputation: 11351
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]
Upvotes: 5
Reputation: 3220
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]
Upvotes: 15
Reputation: 4617
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>
Upvotes: 1
Reputation: 4560
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.
Upvotes: 6