Как создать дружественные URL-адреса с помощью .htaccess?

Мне сложно с .htaccess. Я хочу создать дружественные URL-адреса для сайта, над которым я работаю...

В основном я хочу преобразовать это:

http://website.com/index.php?ctrl=pelicula&id=0221889
http://website.com/index.php?ctrl=pelicula&id=0160399&tab=posters

В это:

http://website.com/pelicula/0221889/
http://website.com/pelicula/0221889/posters/

В случае необходимости в дальнейшем я также хочу знать, как добавить заголовок статьи в конец URL-адреса, как это (я использую PHP):

http://website.com/pelicula/0221889/the-article-name/
http://website.com/pelicula/0221889/the-article-name/posters/

Примечание. Метод Stackoverflow также хорош для меня, например, URL-адрес этого вопроса:

http://stackoverflow.com/info/3033407/htacces-to-create-friendly-urls-help-needed

Но вы можете положить что-нибудь после id, и он также будет работать. например:

http://stackoverflow.com/info/3033407/just-anything-i-want

Я использовал некоторые автоматические веб-инструменты для создания файла .htacces, но он работает неправильно. Поэтому я прошу вас о помощи.

Я также буду рад, если вы порекомендуете .htacces лучшие практики и рекомендации.

РЕДАКТИРОВАТЬ: на основании некоторых ответов, которые я здесь приведу, я добавил следующее:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^/([^/]+)/([^/]+)/?([^/]*)/?$ index.php?ctrl=$1&id=$2&tab=$3 [QSA,L]
</IfModule>

Но я получаю сообщение об ошибке "Не найдена страница по умолчанию".

Я также пробовал:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^([^/]+)/(\d+)/([^/]+)/?$ index.php?ctrl=$1&id=$2&tab=$3 [QSA,L]
    RewriteRule ^([^/]+)/(\d+)/?$         index.php?ctrl=$1&id=$2 [QSA,L]
    RewriteRule ^([^/]+)/?$               index.php?ctrl=$1 [QSA,L]
</IfModule>

Это также не работает. Это приведет меня к моей странице 404.php по умолчанию.

mod_rewrite включен и работает.

Help!

Ответ 1

В корневом каталоге документа для http://website.com/ я бы поставил файл htaccess следующим образом:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>

Затем в вашем PHP script вы можете манипулировать переменной $_GET['url'], как вам угодно:

$path_components = explode('/', $_GET['url']);
$ctrl=$path_components[0];
$id=$path_components[1];
$tab=$path_components[2];

Ответ 2

Просто протестируйте это локально и, похоже, сделайте то, что вам нужно:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^([^/.]+)(?:/)?$ /index.php?ctrl=$1 [L]
    RewriteRule ^([^/.]+)/([^/.]+)(?:/)?$ /index.php?ctrl=$1&id=$2 [L]
    RewriteRule ^([^/.]+)/([^/.]+)/([^/.]+)(?:/.*)?$ /index.php?ctrl=$1&id=$2&tab=$3 [L]
</IfModule>

Это то, что он делает:

Эти перезаписи будут работать с или без трейальной косой черты - если вы хотите, чтобы они работали только без косой черты, удалите (?:/)? с конца первых двух перезаписи. Вы также можете использовать mod_rewrite для добавления или удаления конечной косой черты по мере необходимости.

Ответ 3

Первый, предположив, что ваш файл .htaccess находится в корне:

RewriteRule ^([a-zA-Z]+)/([0-9]+)(/)?$ index.php?ctrl=$1&id=$2

Второе:

RewriteRule ^([a-zA-Z]+)/([0-9]+)/([a-zA-Z]+)(/)?$ index.php?ctrl=$1&id=$2&tab=$3

или если он всегда posters, а не разные вкладки:

RewriteRule ^([a-zA-Z]+)/([0-9]+)/posters(/)?$ index.php?ctrl=$1&id=$2&tab=posters

Я добавил (/)?, который должен означать, что URI будет работать с косой чертой или без нее.

Что касается другого, я бы, вероятно, всегда оставил статью в конце, чтобы переписать или добавить еще один /value, чтобы переписать знает разницу между вкладкой и статьей или исключить тире из регулярного выражения.

Ответ 4

Чтобы иметь этот URL:

http://website.com/pelicula/0221889/posters

переписано:

http://website.com/index.php?ctrl=pelicula&id=0221889&tab=posters

Я бы сделал это:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^/([^/]+)/([^/]+)/?([^/]*)/?$ index.php?ctrl=$1&id=$2&tab=$3 [QSA,L]
</IfModule>

Вам нужно выбрать, хотите ли вы поместить заголовок после id и делать это все время, из-за того, что переменная tab находится в последней позиции: вы должны знать, будет ли она номером 3 или номером 4. Если вы это сделаете:

RewriteRule ^/([^/]+)/([^/]+)/?([^/]*)/?([^/]*)$ index.php?ctrl=$1&id=$2&tab=$4 [QSA,L]

третья скобка не фиксируется и может содержать что угодно.

Надеюсь, что поможет

Ответ 5

Убедитесь, что у вас нет другого файла .htaccess выше в дереве каталогов, который противоречит вашему сайту .htaccess.

Ответ 6

Я использую это в своем .htaccess файле

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

В принципе, если он не существует в виде файла или каталога, используйте rewrite.php и пусть это позаботится о синтаксическом анализе URL и т.д. Это я считаю самым основным способом переписать.

Кроме того, проверьте результаты var_dump($_SERVER) (где-то, что вы знаете, работает), чтобы узнать, действительно ли самая верхняя директория - это самая верхняя директория, например: вы можете писать в /var/www/domain/www/index.php вместо /var/www/domain/index.php

Ответ 7

Основываясь на опыте, я бы рекомендовал настроить вашу схему URI, чтобы упростить только применение правила к URI, которое вы ЗНАЕТ повторно переписываете. Например

Преобразуйте это:

http://website.com/index.php?ctrl=pelicula&id=0221889
http://website.com/index.php?ctrl=pelicula&id=0160399&tab=posters

В это (я положил слово "материал", но это действительно должно быть чем-то, что описывает то, что вы, вероятно, найдете, то есть "магазин" или "библиотека" или что-то еще такое):

http://website.com/stuff/pelicula/0221889/
http://website.com/stuff/pelicula/0221889/posters/

Чтобы достичь этого, вы должны поместить файл .htaccess в папку верхнего уровня вашего сайта, которая содержит следующие правила:

RewriteEngine on
RewriteRule ^stuff/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ index.php?ctrl=$1&id=$2&tab=$3 [L,NC,QSA]
RewriteRule ^stuff/([^/\.]+)/([^/\.]+)/?$ index.php?ctrl=$1&id=$2 [L,NC,QSA]

Имея "составную" часть адреса (переименованную в что-то подходящее), вы не будете случайно переписывать другие активы, такие как изображения, включая CSS и JavaScript.

В качестве дополнительной заметки вы упомянули:

Это также не работает. Это приведет меня к моей странице 404.php по умолчанию.

Где объявлено ваше перенаправление 404 ошибок?

Ответ 8

RewriteRule ^ stuff/([^/.]+)/([^/.]+)/([^/.]+)/?$ index.php? ctrl = $1 & id = $2 & tab = $3 [L, NC, QSA] RewriteRule ^ stuff/([^/.]+)/([^/.]+)/?$ index.php? Ctrl = $1 & id = $2 [L, NC, QSA]