Doubt about htaccess

Asked

Viewed 220 times

2

I have a friendly link that would be localhost/artists/nome-do-artista/, but I want to create pages inside it for example Biography. localhost/artists/nome-do-artista/biography, only that my htaccess does not allow, how to solve?

I’m using:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php [NC,QSA]

In artists/index.php is making a query in the database with name of the artist getting this way the link: artists/nome-do-artista.

But when I create artists/nome-do-artista/biography it searches the main index that would be: artists/nome-do-artista.

I hope you understand, if you can help me I’m flattered.

2 answers

4

As I don’t know how is your folder structure and how you are identifying the name of the artist and etc. I will leave a simple answer but you can adapt.

Structure of the Folder:

.
├── artists
│   ├── albums.php
│   ├── biography.php
│   └── index.php
└── index.php

.htaccess

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule artists/(.*)(?:/(.*))? /artists/index.php?artist=$1&page=$2 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php [L]

In the first rule of rewrite we define - through the regex -, that all access in http://www.example.com/artists/... should be redirected to the folder artists/index.php with the parameters defined.

Explaining the Regex:

artists/(.*)(?:/(.*))?
└───┬──┘└─┬─┘└──┬────┘
    │     │     └──────── Captura o nome da página. O `?` indica que ele é opcional.
    │     └────────────── Captura o nome do artista
    └──────────────────── Base

Artists/index.php

<?php

$artist = $_GET["artist"] ?? false;
$page   = $_GET["page"]   ?? "albums";

if ( $artist ) {

    $model = new ArtistModel();

    if( $model->has($artist) ) {        
        switch ($page) {
            case "biography":
                $content = $model->getBiography();
                require_once "biography.php";
                break;
            case "albums":
            default:
                $content = $model->getAlbums();
                require_once "biography.php";
                break;
        }

    }
} else {
    echo "Not found";
}

Heed! This is just a basic example. You should not use in production, only for studies and to be optimized/adapted to your code.

  • Valdeir, where can I contact you?

  • Your visual explanation of regex is what was missing on +1

2

Another answer (not as good as the previous one), would be this htaccess (comments in the code):

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# redirecionada todas as urls que terminarem com /biography para a 
# pagina biografia.php (foge um pouco do padrão front controller),
# mas imagino que seja o que você queria inicialmente. 
# O ([a-zA-Z0-9\-]+) captura qualquer caracter alphanumerico incluindo 
# o -, e armazena em $1, que posteriormente é passado para a query
# como nomeartista, que pode ser acessado pelo global 
# $_GET ($_GET['nomeartista']).
# Além disso é passado o argumento [L] indicando que se houver um match 
# esse é o ultimo rewrite.
RewriteRule ^artists/([a-zA-Z0-9\-]+)/biography biografia.php?nomeartista=$1 [NC,QSA,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php [NC,QSA,L]

I don’t know if it’s within your capabilities to use some framework to automate route creation, if you are, consider taking a look at Fastroute.

To get deeper into htaccess writing take a look at the guide apache mod_rewrite.

  • My friend Victor and I got it another way, where the directory is localhost/Artists/id/Biography

Browser other questions tagged

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