How to rewrite a URL?

Asked

Viewed 2,116 times

5

Hi, I want to rewrite a URL and I know it needs to be by .htaccess.

I have this URL: www.nomedomeusite.com/visualizar?id=8

My page visualizar.php at the very beginning of body take this one id and make a query in my database to get the rest of the information, this way:

$id = $_GET['id'];
$sql = "SELECT 'nome-da-empresa', 'logo', 'descricao' FROM 'cadastro' WHERE 'id' = $id"

I’d like to know how to rewrite my URL, to achieve this form:

www.nomedomeusite.com/empresas/nome-da-empresa

I need a very detailed explanation of each term used and each variable used to do this, because I have no knowledge of the programming involved in .htaccess

  • It is a site made only by html and php even without any framework

  • That page visualizar.php is one of the common pages of my site, in it I make a call of various elements of my database and display them on the screen

  • Already read this post here ?

  • Yes, I came to see this post, but I couldn’t understand that code very well, so I couldn’t do it. If you could really explain to me how I can do this id, which takes the name of the database and puts it in the url, it would be of great help.

  • This question actually already exists, and it has also been answered, but the fact that it has a reward does not allow it to be marked as duplicate. But in any case, it would be something like, by clicking on link article (the link itself would be the title of the article), would open a specific page that would show the content of that article, that’s it ?

  • For that you’ll have to wait, because at the moment I am somewhat physically conditioned, unless someone would please give me that answer before I do. If no one answers, probably by tomorrow at the end of the day I will pass the answer.

  • Okay, I’m trying some stuff here, using that post there that you mentioned, anything, if I find an answer I’ll let you know

Show 2 more comments

3 answers

2

For you, the solution would be this one demonstrated, but because I do not know exactly what the structure of your table is, I will base myself on the details provided in the comments. Although you are using a different table, the example is very simple. The only problem you would have is perhaps the slug which is basically the title of the article, but with some arrangements, for this has this, and this here.

config.php

<?php

// configuracao (nao importante)
$config = array(
    'mysql' => array(
        'host'=> 'localhost',
        'usr' => 'root',
        'pwd' => '',
        'db'  => 'nuwie'
    ),
    'site' => array(
        'nome' => 'Site sem Nome',
        'inicio' => 'http://127.0.0.1:8080' . dirname($_SERVER['SCRIPT_NAME'])
    )
);

// agilizar a busca dos valores da configuração (nao importante) 
function conf($nome){
    $p = preg_split('/[\s-@]/', $nome);
    global $config;
    foreach($config as $nome => $valor){
        if($nome === $p[0] && array_key_exists($p[1], $valor)){
            return $config[$nome][$p[1]];
        }
    }
    return false;
}



// conexao
$mysqli = new  mysqli(conf('mysql-host'), conf('mysql-usr'), conf('mysql-pwd'), conf('mysql-db'));

if($mysqli->errno){
    die('Erro ao conectar banco de dados');
}

// buscar todos os artigos
function buscarArtigos($tabela){
    global $mysqli;
    $resultados = array();
    if($stmt = $mysqli->query("SELECT id,titulo,seo_url FROM {$tabela}")){
        if($stmt->num_rows > 0){
            while($rs = $stmt->fetch_assoc()){
                array_push($resultados, $rs);
            }
            return $resultados;
        }
    }
    return false;
}

// buscar um artigo pela sua ID
function buscarArtigo($id, $tabela){
    global $mysqli;
    if($stmt = $mysqli->query("SELECT * FROM {$tabela} WHERE id = {$id}")){
        if($stmt->num_rows > 0){
            return $stmt->fetch_assoc();
        }
    }
    return false;
}

// reajustar os titulos para que se adequem a url
// retirada de: http://www.visualscope.com/seo-friendly-urls.html
function friendly_seo_string($vp_string){

    $vp_string = trim($vp_string);

    $vp_string = html_entity_decode($vp_string);

    $vp_string = strip_tags($vp_string);

    $vp_string = strtolower($vp_string);

    $vp_string = preg_replace('~[^ a-z0-9_.]~', ' ', $vp_string);

    $vp_string = preg_replace('~ ~', '-', $vp_string);

    $vp_string = preg_replace('~-+~', '-', $vp_string);

    return $vp_string;
}

This file here contains basically the only two functions you’d need to make the idea work searchArticles and searchArticle, what’s there to spare (nothing important) created in the heat of the moment since they were simple except the last that may be useful and is not of my own making. The function friendly_seo_string is only required when you want to create a new article, for example:

  • When you create a new article, in the database table for the fields titulo and conteudo you can use the desired title and content respectively, the same applies to the field adicionado, but to the countryside seo_url would have to be the return of this function passing the title used as argument friendly_seo_string(titulo_usado_no_artigo). Or if you prefer you can always write your own function, so that it does the same thing.

.htaccess

RewriteEngine On
RewriteRule ^artigos/[0-9]\/(.*)$ ver_artigo.php?artigo=$0

For this example, you wouldn’t need much in the file .htaccess, only these two lines would be sufficient, or you can still check if the module rewrite is enabled before activating it.

sql table

CREATE TABLE `artigos` (
  `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `titulo` varchar(60) NOT NULL,
  `conteudo` text NOT NULL,
  `seo_url` varchar(60) NOT NULL,
  `adicionado` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

index php.

<?php

require_once 'config.php';

print "<a href=\"" .  conf('site-inicio') ."\"><h1>" . conf('site-nome') . "</h1></a>";

// - inicio do conteudo
if(($artigos = buscarArtigos('artigos')) != false){
    foreach($artigos as $artigo){
        print "<div id=\"artigo\">";
        print  "<a href=\"artigos/{$artigo['id']}/{$artigo['seo_url']}\" target=\"_blank\"><h4>{$artigo['titulo']}</h4></a>";
        print "</div>";
    }
} else {
    print "Nenhum artigo encontrado";
}
// - fim do conteudo

?>

The file index php., simply make available the respective titles and links of existing articles. Attention to article link:

print  "<a href=\"artigos/{$artigo['id']}/{$artigo['seo_url']}\" target=\"_blank\"><h4>{$artigo['titulo']}</h4></a>";

IN url which stores, for articles, must precede artigos at the beginning of href.

ver_article.php

<?php

require_once 'config.php';

if(isset($_GET['artigo'])){
    $artigo_id = explode('/', $_GET['artigo']);

    if(($artigo = buscarArtigo($artigo_id[0], 'artigos')) != false){
        print "<div id=\"artigo\">";
        print "<h2>{$artigo['titulo']}</h2>";
        print $artigo['conteudo'];
        print "</div>";
    } else {
        print "Artigo não encontrado";
    }

    print "<p><a href=\"" .  conf('site-inicio') ."\">voltar</a></p>";

} else {
    print "<h1>Erro</h1>";
}

?>

This part would be the equivalent of your page visualize.pph. Search the details of this article using your id and returns them, if you do not find the article, provides a message saying that you did not find the article.

In that case, yours url would look in this format similar to ptSO:

www.nomedomeusite.com/articles/id/article title

For the format:

www.nomedomeusite.com/companies/any-company

You’d have to match your own slug instead of id on the tab showing the details of the selected item.

ps.: I worked on the idea, but I didn’t give a damn about the safety factor, so I recommend before, that you research mainly on the .htaccess, and of course, you can always adapt or even , improve the code so that it works more closely to what you want. If there are still doubts, leave them in the comments, and good luck.

Recommended Reading

Apache

2


Nicolas you can use the following rule in your . htaccess

<IfModule mod_rewrite.c>
RewriteEngine On
# informa que será aplicada uma condicao no arquivo solicitado 
RewriteCond %{REQUEST_FILENAME} !-f [OR] 
RewriteCond %{REQUEST_FILENAME} \.php$

#cria a condicao
RewriteRule ^empresa/([a-z0-9-]+)/?$ /visualizar.php?nome=$1 [L,NC]

</IfModule>

Already in your file visualize.php you will have to make some modifications, such as changing your search in the bank, instead of looking for the id you will search for the company name.

$id = $_GET['nome'];
$sql = "SELECT 'nome-da-empresa', 'logo', 'descricao' FROM 'cadastro' WHERE 'nome-da-empresa' = $id"
  • Hello, thank you for answering. I made the appropriate changes to make the search by name. But my question, is whether I have to change the href of the articles: visualizar.php?nome=$nome for empresas/$nome. 'Cause if I don’t put that last one href expressly, the URL does not change. However, when placing this href, it opens a whole blank page, without the css and the images that the visualizar.php had. How to solve?

  • Nicolas should change all calls to your site.com.br/companies/company name he alone will not redirect the calls in the old url. As for your css and js files you can use the google Chrome console to see which path is being called for your Assets and change them or even create a new rule in yours. htaccess to avoid that files are not found due to URL friendly.

1

What you seek is a Front controller.

For such a solution in PHP you need something a little more elaborate, I recommend using a framework like Symfony or derivatives. In case you insist on doing it yourself.

The . htaccess to redirect content to your.php view keeping your URI as /. but that’s only part.

#.htaccess
<IfModule mod_rewrite.c>
 RewriteEngine On
 #Sua front controller
 DirectoryIndex visualizar.php
 # Desabilita MultiViews,assim quando "/visualizar"
 #   ele vai resolver internamente para "/visualizar.php/visualizar".
 <IfModule mod_negotiation.c>
    Options -MultiViews
 </IfModule>
<IfModule mod_rewrite.c>
    RewriteEngine On


    # Define um header HTTP_AUTHORIZATION, o apache se encarrega disso.
    RewriteCond %{HTTP:Authorization} .
    RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    #redirecionamento inicial caso tente entrar /visualizar.php joga para /.
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^visualizar\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L]

    # Se existir o arquivo ele permanece disponivel.
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule ^ - [L]

    # Redireciona o restante para a front controller.
    RewriteRule ^ %{ENV:BASE}/visualizar.php [L]
</IfModule>

#saida para quando o mod_rewrite não esta disponivel
<IfModule !mod_rewrite.c>
    <IfModule mod_alias.c>
        RedirectMatch 302 ^/$ /visualizar.php/
    </IfModule>
</IfModule>

In PHP you can get the URI with $uri = $_SERVER['REQUEST_URI'];

If your system has many routes, I suggest using a ready-made library like the Fastroute of the nikic. has a post of him explaining in more detail in the repository.

Now for dynamic routes, the ones you search in the database. if the access is large and/or the query is too expensive for your system. Create a cache. but there would be something much more specific, where would recommend you to use a framwork

  • Sorry, for inexperience in this, I didn’t understand how this code of yours can fix my URL the way I want it, I didn’t see any calls to my id or any way you picked up the company name

  • Then, see the contents of $_SERVER['REQUEST_URI']; on your system. The idea of front controller is like a router, it gets all the requests of the system and based on URI which would be the end of his URL the part including the first / decides which controller to trigger.. these controllers may be functions, classes, or even their own .php . being something very specific of its implementation

  • And after I see the contents of this request, what I do?

  • What about this Symfony you mentioned, is it an easier solution? How to use it?

  • Symfony is a framework, I find it easier. This is for me, unaware of your knowledge I do not know, if you are from the area or wanted to enter I recommend to start using a framework and learn design Pattern, read the Gof

Browser other questions tagged

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