User-friendly URL using HTACCESS

Asked

Viewed 3,443 times

11

I have the following link: dominio.com/?p=filmes_v&m=tt081692 Man .htaccess

<IfModule mod_rewrite.c>
  RewriteEngine On

  RewriteRule ^film/?$ index.php?p=filmes [NC,L]
  RewriteRule ^film/([a-z0-9-]+)/?$ index.php?p=filmes_v&?m=$2 [NC]
</IfModule>

My goal is: dominio.com/film/tt081692

But I can’t put the variable $m of the link on .htaccess

I have another problem:

dominio.com/film  -> O site fica certo

dominio.com/film/ -> O CSS não é carregado
  • Change the line: RewriteRule ^film/([a-z0-9-]+)/?$ index.php?p=filmes_v&?m=$1 [NC], about CSS would be better to post as you are doing.

  • Thank you @Papacharlie, the $2 was my own distraction.

  • @Kaduamaral, that was my problem, I managed to solve, thank you.

  • By the way, the CSS problem from this I think I can solve :)

1 answer

16


Resolution

Remove the ? before the m and use variable $1:

RewriteRule ^film/([a-z0-9\-]+)/?$ index.php?p=filmes_v&m=$1 [NC]

The htaccess will be as follows:

<IfModule mod_rewrite.c>
  RewriteEngine On

  RewriteRule ^film/?$ index.php?p=filmes [NC,L]
  RewriteRule ^film/([a-z0-9\-]+)/?$ index.php?p=filmes_v&m=$1 [NC]
</IfModule>

Note that within [] in regular expressions it is recommended to escape -, because they are used in the syntax of the expression, as an example [a-z] indicating of a until z. - @Guilhermenascimento

Links and Scripts

Using URL friendly you accurate can use absolute paths or just reference the files indicating a / at the beginning of the way:

<link href="http://meudominio.com/css/meucss.css">
<!-- ou -->
<link href="/css/meucss.css">

<a href="http://meudominio.com/contato">
<!-- ou -->
<a href="/contato">

<script src="http://meudominio.com/js/jquery.min.js"></script>
<!-- ou -->
<script src="/js/jquery.min.js"></script>

Relative Paths

Heed: Relative paths has to be initiated with / which indicates the site root, because if the current page has an address similar to http://meudominio.com/contato and the user click on a link <a href="sobre">Sobre</a> he will end up at the address http://meudominio.com/contato/sobre.

A very interesting resource to use with relative paths is the RewriteBase. For example imagine that you have a blog and it’s structured more or less like this on the server:

/root
| - /www
|   | - /blog
|       | - /css
|       | - /js

And the URL to access this blog is http://meusite.com/blog/ then in all your code you will have to reference your scripts and links using the semi-relative URL /blog/.

<link href="/blog/css/estilos.css" rel="stylesheet" type="text/css">
<script src="/blog/js/scripts.js" type="text/javascript"></script>
<a href="/blog/sobre">Sobre</a>

But if in the htaccess of Blog is defined the RewriteBase for blog, will no longer need the /blog/ in the URL:

RewriteBase /blog/

And your Urls can stay:

<link href="/css/estilos.css" rel="stylesheet" type="text/css">
<script src="/js/scripts.js" type="text/javascript"></script>
<a href="/sobre">Sobre</a>

And so if at some point you decide to change the address http://meusite.com/blog/ for http://blog.meusite.com just need to change the RewriteBase for / or remove it:

RewriteBase /

So you don’t need to change all the links removing the one /blog of Urls. :)

You can also have this feature through tag base. But I prefer the htaccess.

Other means

A very interesting way to make friendly Urls is the way I call it Dynamic Friendly Urls, the implementation would be so:

<IfModule mod_rewrite.c>
  RewriteEngine On

  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f

  RewriteRule ^(.*)$ index.php?uri=$1
</IfModule>

This way you can treat the URI in PHP to receive as many variables as you want, example:

$tmp = !empty($_GET['uri']) ? $_GET['uri'] : 'home'; // Página padrão home

$uri = explode('/', $tmp);

$vars = Array();

if (count($uri) > 1){
    $key = 'page';
    foreach ($uri as $val) {
        if (is_null($key))
            $key = $val;
        else {
            $vars[$key] = $val;
            $key = NULL;
        }
    }
}

In the previous example, you can send the URL http://meudominio/catalogo/categoria/eletrodomestico/preco/100~500/voltagem/220 and you would have the following structure in the variable $vars:

page        => catalogo
categoria   => eletrodomestico
preco       => 100~500
voltagem    => 220

So the first argument is always the page and the following are any parameter you want, in any order and should always be sent in pairs chave/valor. This form is quite useful for making filters.

Model MVC

Using this concept it is simple to apply a MVC model that would be:

controller/action/demais/parametros

For example:

$tmp = !empty($_GET['uri']) ? $_GET['uri'] : 'home'; // Página padrão home

$uri = explode('/', $tmp);

$vars = Array(
    // Controller `index` caso não tenha parâmetros na URI, caso tenha armaza e remove-o da URI
    'controller'   => (count($uri) > 0 ? array_shift($uri) : 'index'),
    // Action `index` caso não tenha parâemtros na URI
    'action'       => (count($uri) > 0 ? array_shift($uri) : 'index'),
    // Demais parâmetros
    'params'       => Array()
);

$key = NULL;
if (count($uri) > 1){
    foreach ($uri as $val) {
        if (is_null($key))
            $key = $val;
        else {
            $vars['params'][$key] = $val;
            $key = NULL;
        }
    }
}

Thus accessing the URL:

www.meudominio.com/sobre/empresa/page/3

We will have the following result:

$vars = Array(
    'controller' => 'sobre',
    'action'     => 'empresa',
    'params'     => Array(
        'page' => '3'
    )
);

Another Example for MVC

  • There’s no other way?

  • Add to your htaccess RewriteBase /, see if it works, the test I did didn’t work @xdam98.

  • No, it didn’t work @Kaduamaral

  • Actually it’s not what I thought. Here’s a reply in English about its use. Really need to use Absolute URL, I usually create a constant define('SITE', 'http://meusite/'); with the address and use in the references: href="<?=SITE?>css/meucss.css" @xdam98

  • Okay, thanks for the tip :) For now I will do as I said. However I will study more about . htaccess

  • Fine, then I’ll supplement that answer. @xdam98

  • Just a hint, instead of using <a href="http://meudominio.com/contato"> and <a href="http://meudominio.com/level1/level2"> prefer <a href="/contato"> and <a href="/level1/level2">, so avoid difficulties chance use https or "mirror domains", because with the whole url can end up directing to a non-existent page. @xdam98

  • @Guilhermenascimento disagree, in case he is on the page http://meudominio.com/contato and click on the link /level1/level2 it will probably fall on the address http://meudominio.com/contato/level1/leve2. To solve the problem you indicated, just take the http: and leave <a href="//meudominio.com/contato">.

  • No @Kaduamaral to / of href="/level1/level2" at first leads to "root", sorry but I think you got confused. The problem would only occur if it was href="level1/level2" without the bar at first.

  • It’s true @Guilhermenascimento, I didn’t pay much attention, the same works for CSS and Javascript files, since started with / indicating the site root works normally.

  • @Kaduamaral I just did not recommend pro CSS and JS because it is generally recommended a CDN server the part chance you share these static files with multiple domains, for example multiple news portals that can use the same technology, but this is a little relative to each project and so I did not mention it and I do not recommend mentioning.

  • It is also worth commenting to the author that instead of using ^film/([a-z0-9-]+)/?$ use ^film/([a-z0-9\-]+)/?$, I don’t know if this makes a difference in Apache, but in Regex we must "escape" the - inside [...]

  • Yes @Guilhermenascimento, but since the question is about URL Friendly I do not think it necessary to spend explanations with CDN that "does not have" much to do with the topic.

  • @Kaduamaral But that’s exactly what I said about the CDN: "this is a little relative to each project and so I did not mention it and nor recommend to mention.", as I said, that is only a justification of why I did not mention the CDN, because it is not relative, both for the question and for the project, since it can vary.

  • kkkk did not annoy me the.0 -- exaggeration of yours, I just explained :p

  • @Kaduamaral when we pass all the urls through index php. we have to make a script to receive the gets and send to destination on the specifications of gets

  • 1

    Exactly @Marcosvinicius, in the answer I put only the script who catches the gets, but after that comes the part where it is called the desired code, be it the execution of a controller and action or a require of a file, depends on the structure of each project.

  • Regarding your css not to load just use the <base href="your completed" address tag in your project index.

  • @Developerwebsistem... the attribute RewriteBase /blog/ has the same function.

  • @Kaduamaral I tried and did not obtain result: Rewritebase /urlAmigavel/

Show 15 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.