php - amigables - reescribir url htaccess
.htaccess reescribe las variables GET (7)
Tengo un index.php que maneja todo el enrutamiento index.php? Page = controller (simplificado) solo para dividir la lógica con la vista.
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([/w/d~%.:_/-]+)$ index.php?page=$1 [NC]
Que básicamente: http://localhost/index.php?page=controller To
¿Alguien puede ayudarme a agregar la Reescritura para
http://localhost/controller/param/value/param/value (y soforth)
Eso sería:
http://localhost/controller/?param=value¶m=value
No puedo hacer que funcione con la Reescritura.
Un controlador podría verse así:
<?php
if (isset($_GET[''action''])) {
if ($_GET[''action''] == ''delete'') {
do_Delete_stuff_here();
}
}
?>
Y también:
<?php
if (isset($_GET[''action'']) && isset($_GET[''x''])) {
if ($_GET[''action''] == ''delete'') {
do_Delete_stuff_here();
}
}
?>
¿Es esto lo que estás buscando?
Este ejemplo muestra cómo ocultar fácilmente los parámetros de cadena de consulta utilizando el indicador de bucle. Supongamos que tiene una URL como http://www.mysite.com/foo.asp?a=A&b=B&c=C y quiere acceder a ella como http://www.myhost.com/foo.asp/a/A/b/B/c/C
Pruebe la siguiente regla para lograr el resultado deseado:
RewriteRule ^(.*?/.php)/([^/]*)/([^/]*)(/.+)? $1$4?$2=$3 [NC,N,QSA]
¿Estás seguro de que estás utilizando el servidor apache? .Htaccess solo funciona en el servidor apache. Si está utilizando IIS, entonces se requiere web.config. En ese caso:
<?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>
¿Qué tal redirigir a index.php?params=param/value/param/value
, y dejar que php divida todo $_GET[''params'']
? Creo que esta es la forma en que WordPress lo maneja.
Básicamente, lo que las personas intentan decir es que puedes hacer una regla de reescritura como esta:
RewriteRule ^(.*)$ index.php?params=$1 [NC]
Esto hará que tu archivo php real así:
index.php?params=param/value/param/value
Y su URL real sería así:
http://url.com/params/param/value/param/value
Y en su archivo PHP puede acceder a sus parámetros explotando esto de la siguiente manera:
<?php
$params = explode( "/", $_GET[''params''] );
for($i = 0; $i < count($params); $i+=2) {
echo $params[$i] ." has value: ". $params[$i+1] ."<br />";
}
?>
Creo que es mejor si redirigir todas las solicitudes al archivo index.php y luego extraer el nombre del controlador y cualquier otro parámetro utilizando php. Lo mismo que cualquier otro marco como Zend Framework.
Aquí hay una clase simple que puede hacer lo que está buscando.
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, ''_'');
}
}
Cómo usarlo:
$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
archivo .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]
Por alguna razón, la solución seleccionada no funcionó para mí. Constantemente solo devolverá "index.php" como valor de params.
Después de algunos intentos de prueba y error, encontré que las siguientes reglas funcionan bien. Suponiendo que desea que yoursite.com/somewhere/var1/var2/var3 apunte a yoursite.com/somewhere/index.php?params=var1/var2/var3, coloque la siguiente regla en un archivo .htaccess en el "lugar" directorio:
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]
Luego, en PHP o en el idioma que elija, simplemente separe los valores usando el comando de explosión tal como lo señala @Wesso.
Para fines de prueba, esto debería bastar en su archivo index.php:
if (isset($_GET[''params'']))
{
$params = explode( "/", $_GET[''params''] );
print_r($params);
exit("YUP!");
}
Su regla de reescritura pasará la URL completa:
RewriteRule ^(.*)$ index.php?params=$1 [NC]
Su index.php interpretaría esa ruta completa como controller / param / value / param / value para usted (mi PHP está un poco oxidado):
$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];
}