A maioria dos tutoriais trata das url amigáveis da seguinte forma:
RewriteEngine On RewriteCond %{SCRIPT_FILENAME} !-f RewriteCond %{SCRIPT_FILENAME} !-d RewriteRule ^(.*)$ index.php?page=$1
Só que desta forma fica extremamente difícil de fazer com mais de um parâmetro. Então como fazer para ser mais simples.
Os arquivos .htaccess (ou "arquivos de configuração distribuída") oferecem um meio de fazer mudanças nas configurações por-diretório. Um arquivo, contendo uma ou mais diretrizes de configurações, é colocado em um diretório em particular, e as diretrizes se aplicam para aquele diretório e todos os seu subdiretórios subseqüentes.
Leia mais: http://httpd.apache.org/docs/2.2/pt-br/howto/htaccess.html
Primeiro crie um arquivo .htaccess na pasta raiz do site ou sistema que você esta criando. A ele adicione o seguinte conteúdo.
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php [L]
Se você estiver usando Linux ou MAC, este arquivo se tornará oculto. Para visualizá-lo no terminal digite ls -a.
Agora vamos entender o que escrevi em cada uma das linhas acima.
RewriteEngine On
Ativa o suporte à reescrita de URL. Isso significa que as URL poderão ser direcionadas para um determinado arquivo no apache.
RewriteCond %{SCRIPT_FILENAME} !-f
Não aplica a condição para arquivos que existam. Isso significa que as imagens, CSS, JS e outros arquivos que já existem continuarão funcionando perfeitamente.
RewriteCond %{SCRIPT_FILENAME} !-d
Não aplica a condição para diretórios que existam
RewriteRule . index.php [L]
Arquivo para onde deve ser direcionado as requisições. Isso significa que tudo que for digitado no browser, após a pasta que esta este .htacces e que não exista, será direcionado para o arquivo index.php.
Se tiver dúvida acesse o site do apache em http://httpd.apache.org/docs/current/mod/mod_rewrite.html.
Mais agora você deve estar se perguntando. Como verifico as variáveis passadas para a minha aplicação? Simples, vamos criar uma classe Url que vai ler a URL, excluir tudo que não pertencer ao projeto.
Veja a classe abaixo:
<?php class Url { private static $url = null; private static $baseUrl = null; public static function getBase() { if( self::$baseUrl != null ) return self::$baseUrl; global $_SERVER; $startUrl = strlen( $_SERVER["DOCUMENT_ROOT"] ); $excludeUrl = substr( $_SERVER["SCRIPT_FILENAME"], $startUrl, -9 ); if( $excludeUrl[0] == "/" ) self::$baseUrl = $excludeUrl; else self::$baseUrl = "/" . $excludeUrl; return self::$baseUrl; } public static function getURL( $id ) { // Verifica se a lista de URL já foi preenchida if( self::$url == null ) self::getURLList(); // Valida se existe o ID informado e retorna. if( isset( self::$url[ $id ] ) ) return self::$url[ $id ]; // Caso não exista o ID, retorna nulo return null; } private static function getURLList() { global $_SERVER; // Primeiro traz todos as pastas abaixo do index.php $startUrl = strlen( $_SERVER["DOCUMENT_ROOT"] ) -1; $excludeUrl = substr( $_SERVER["SCRIPT_FILENAME"], $startUrl, -10 ); // a variável$request possui toda a string da URL após o domínio. $request = $_SERVER['REQUEST_URI']; // Agora retira toda as pastas abaixo da pasta raiz $request = substr( $request, strlen( $excludeUrl ) ); // Explode a URL para pegar retirar tudo após o ? $urlTmp = explode("?", $request); $request = $urlTmp[ 0 ]; // Explo a URL para pegar cada uma das partes da URL $urlExplodida = explode("/", $request); $retorna = array(); for($a = 0; $a <= count($urlExplodida); $a ++) { if(isset($urlExplodida[$a]) AND $urlExplodida[$a] != "") { array_push($retorna, $urlExplodida[$a]); } } self::$url = $retorna; } } ?>
Lembre-se: Para evitar problemas de compatibilidade, é necessário que todas as URL sejam absolutas. Ou seja, devem referenciar desde a raiz.
URL absoluta é uma URL que aponta sempre para o mesmo ponto, independente de qual local no site ele esteja sendo chamado. Uma URL absoluta pode iniciar com HTTP:// e conter todo o domínio ou somente com / e referenciar a raiz do domínio.
Ex de URL absoluta:<link rel="stylesheet" type="text/css" href="/code/10000/css/style.css"/>URL relativa é uma URL que muda conforme a sua localização no site.
Ex de URL relativa:<link rel="stylesheet" type="text/css" href="css/style.css"/>
Assim que chamamos pela primeira vês o método estático Url::getURL( $id ) ele verifica a URL e monta uma lista contendo as variaveis passadas ao sistema.
Então vamos criar um teste simples. Vou utilizar um exemplo do Maujor (goo.gl/60L5H) para isso.
Vamos ver o arquivo index.php usando a classe:
<?php require "classes/Url.class.php"; ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pt-br"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name="author" content="Mauricio Samy Silva / Eduardo Kraus" /> <link rel="stylesheet" type="text/css" href="<?php echo URL::getBase() ?>css/style.css"/> <title>Trabalhando com URL amigável no PHP</title> </head> <body> <div id="tudo"> <div id="topo">TOPO</div> <div id="principal"> <?php $modulo = Url::getURL( 0 ); if( $modulo == null ) $modulo = "modulo1"; if( file_exists( "modulos/" . $modulo . ".php" ) ) require "modulos/" . $modulo . ".php"; else require "modulos/404.php"; ?> </div> <div id="navegacao"> <p><a href="<?php echo URL::getBase(); ?>modulo1">Módulo 1</a></p> <p><a href="<?php echo URL::getBase(); ?>modulo2">Módulo 2</a></p> <p><a href="<?php echo URL::getBase(); ?>modulo3">Módulo 3</a></p> <p><a href="<?php echo URL::getBase(); ?>modulo4">Módulo 4</a></p> <p><a href="<?php echo URL::getBase(); ?>modulo5">Módulo 5</a></p> <p><a href="<?php echo URL::getBase(); ?>modulo6">Módulo 6</a></p> <p><a href="<?php echo URL::getBase(); ?>modulo7">Módulo 7</a></p> <p><a href="<?php echo URL::getBase(); ?>modulo8/parametro/sei-la/alguma_coisa/25/quase-nada"> Módulo 8 com sub-módulo</a></p> <p><a href="<?php echo URL::getBase(); ?>qualquer">Módulo 404</a></p> <p><a href="<?php echo URL::getBase(); ?>teste.php">Teste.php</a></p> </div> <div id="rodape">RODAPE</div> </div> </body> </html>
Então, no módulo8 eu criei uma programação PHP para receber estes dados e analiza-lo. Veva os dois links abaixo:
Veja o exemplo rodando completo em php.eduardokraus.com/code/10000/
Quer o código fonte completo deste exemplo? Clique aqui.