как сделать правило htaccess из id в name

у меня есть список уникальных данных:

Предположим, у меня есть следующие данные:

id    name
1     Jhon
2     Peter 
3     Mark
4     Scotty
5     Marry

Я .htaccess правила id:

RewriteRule brandlisting/(.*)/ site/brandlisting?id= [L]
RewriteRule brandlisting/(.*) site/brandlisting?id= [L]

мой URL:

http://localhost/mate/admin/site/brandlisting/3

это работает для ID.

теперь мне нужно .htaccess правило для имени, поэтому я делаю правило для него:

RewriteRule brandlisting/(.*)/ site/brandlisting?name= [L]
RewriteRule brandlisting/(.*) site/brandlisting?name= [L]

http://localhost/mate/admin/site/brandlisting/Mark

когда я использовал вышеуказанный URL, я столкнулся со следующей ошибкой в консоли:

" NetworkError: 400 Плохой Запрос - http://localhost/mate/admin/site/brandlisting/Mark"

и в браузере он показывает:

ошибка 400 ваш запрос недействителен.

мой нынешний .htaccess файл

RewriteEngine on

RewriteCond %{HTTP_HOST} ^localhost/mate/admin$ [NC,OR]
RewriteCond %{HTTP_HOST} ^localhost/mate/admin$

RewriteCond %{REQUEST_URI} !wordpress/
RewriteRule (.*) /wordpress/ [L]

Options +FollowSymLinks -MultiViews
RewriteEngine On

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php/ [PT,L]

#RewriteRule brandlisting/(.*)/ site/brandlisting?id= [L]
#RewriteRule brandlisting/(.*) site/brandlisting?id= [L]

RewriteRule brandlisting/(.*)/ site/brandlisting?name= [L] 
RewriteRule brandlisting/(.*) site/brandlisting?name= [L] 

4 ответов


.htaccess правила полагаются на порядок. Если вы планируете использовать много маршрутов, сохраните правила htaccess простыми и поместите свои маршруты в PHP, используя одну из нескольких уже написанных фреймворков маршрутизации.

вот объяснение, почему твой .htaccess файл не работает, строка за строкой:

RewriteEngine on

это включило RewriteEngine. Пока никаких проблем.

RewriteCond %{HTTP_HOST} ^localhost/mate/admin$ [NC,OR]
RewriteCond %{HTTP_HOST} ^localhost/mate/admin$    
RewriteCond %{REQUEST_URI} !wordpress/

только RewriteRule это WordPress. Кажется, это работает, так что давайте игнорируйте этот блок правил.

RewriteRule (.*) /wordpress/ [L]

Options +FollowSymLinks -MultiViews

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

только ниже, если запрашиваемое имя файла не файл или каталог.

RewriteRule .* index.php/ [PT,L]

переписать любой путь PATH проиндексировать.на PHP/PATH. Остановите обработку, если она совпала (обратите внимание на L as последние). Это означает, что ничто ниже не будет активировано.

#RewriteRule brandlisting/(.*)/ site/brandlisting?id= [L]
#RewriteRule brandlisting/(.*) site/brandlisting?id= [L]

RewriteRule brandlisting/(.*)/ site/brandlisting?name= [L] 
RewriteRule brandlisting/(.*) site/brandlisting?name= [L] 

предполагая, что он не соответствует .* (ака, никогда), проверьте путь для других моделей. Обратите внимание также, что две строки, которые вы прокомментировали, и две линии, которых у вас нет, совпадают по одному шаблону. Если одно сработает, то другое-нет.

-- Pro Tip: Regex имеет стенографию для включения правила с косой чертой и без нее:/? эквивалентно, либо с одной косой чертой, либо без косой черты. Другой способ написать это /{0,1}.

как исправить

.htaccess правила перенаправления-это боль. Мое эмпирическое правило состоит в том, чтобы сделать их как можно проще писать, что делает их легко читать и поддерживать. Как это сделать? Нажмите логику перенаправления на свою PHP-программу, а не заставляйте Apache полагаться на нее.

Решение 1

на htaccess-только подход здесь будет гарантировать, что вы понимаете, что Apache переписать флаги говорят вашему серверу, чтобы сделать и настроить соответственно. Вы можете сделать это одним из двух способов:

  1. Сделайте ваши более конкретные правила появляются первыми. то есть, двигаться /site/brandlisting?name= правила К перед .* правила.

  2. добавить отдельные условия перезаписи для любой последующей обработки. Согласно документации Apache2, связанной выше:

флаг [L] заставляет mod_rewrite прекратить обработку набора правил. В большинстве контекстов это означает, что если правило совпадает, дальнейшие правила обрабатываться не будут. Это соответствует последней команде в Perl или команде break В C. используйте этот флаг, чтобы указать, что действующее правило должно применяться незамедлительно без рассмотрения дополнительных правил.

ключевым моментом здесь является то, что это в пределах каждого набора правил. Построение нового набора правил будет продолжено.

пример, который должен работать (не проверял):

RewriteEngine on

RewriteCond %{HTTP_HOST} ^localhost/mate/admin$ [NC,OR]
RewriteCond %{HTTP_HOST} ^localhost/mate/admin$

RewriteCond %{REQUEST_URI} !wordpress/
RewriteRule (.*) /wordpress/ [L]

Options +FollowSymLinks -MultiViews
RewriteEngine On

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php/ [PT,L]

#New Rule Set
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# Note that /? is the same as writing two separate rules,
# one with a slash at the end, and one without.
RewriteRule brandlisting/(.*)/? site/brandlisting?name= [L] 

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

решение 2

вы можете использовать маршрутизаторы PHP в сочетании с .htaccess файл, который я предоставил выше, например:

// Slim example
$app = new Slim\Slim();
$app->get('/brandlisting/:key', function ($key) {
    if (is_numeric($key)) {
        $id = $key;
        // call/run $id logic
    } else {
        $name = $key;
        // call/run $name logic
    }
});
// ...
$app->run();

если вы это сделаете, вы можете удалить любой из ваших brandlisting логику .htaccess и вместо положите его в свой index.php.

вывод

если вы можете помочь, опыт говорит мне, что лучше не писать логику приложения в .htaccess правила. Вместо этого сделайте свой .htaccess правила просты и используют библиотеку маршрутизации. Если вы хотите использовать .htaccess, убедитесь, что вы понимаете Apache переписать флаги вы используете, и этот Apache читает все сверху вниз. Например, если [L] флаг используется, Apache перестает читать все остальные правила в наборе правил. Это означает, что вы должны создать новый набор правил с дополнительными правилами, которые необходимо обработать, или поставить более конкретные правила на первое место. Имейте в виду, что если эти правила есть [L] флаг, они также остановят выполнение любых последующих правил.


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

ваше правило в соответствии с вашим требованием должно быть таким, если вы пытаетесь в корневом каталоге,

RewriteEngine on

RewriteBase /mate/admin/

RewriteRule site/brandlisting/([\d]+)/?$ site/brandlisting.php?id= [L]
RewriteRule site/brandlisting/([a-zA-Z]+)/?$ site/brandlisting.php?name= [L]

и для wordpress вы можете создать отдельный каталог .откройте файл. htaccess, где вы можете положить ваш указательный правило.РНР.


Вы можете использовать перенаправления здесь.

Если у вас есть следующие папки:

<server root>/mate/admin

место .htaccess в mate / admin

RewriteBase /mate/admin/
RewriteRule "site/brandlisting/([^\]+)/" "site/brandlisting?id=" [R,L]
RewriteRule "site/brandlisting/([^\]+)" "site/brandlisting?id=" [R,L]

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

см. документацию для Флаги Перезаписи: L.

в частности, имеет значение следующий цитируемый текст:

Если вы используете RewriteRule в любом .файлы htaccess или в разделы, важно иметь некоторое понимание как обрабатываются правила. Этот упрощенная форма это то, что когда-то правила обработаны, переписанный запрос возвращен механизм синтаксического анализа URL, чтобы сделать то, что он может с ним. Возможно, что как обрабатывается переписанный запрос, то .файл htaccess или раздел может быть обнаружен снова, и, таким образом, набор правил может быть запущен опять с самого начала. Чаще всего это произойдет, если один из правила вызывают перенаправление-внутреннее или внешнее-вызывая процесс запроса начать заново.

поэтому важно, если вы используете директивы RewriteRule в один из этих контекстов, что вы предпринимаете явные шаги, чтобы избежать правил цикл, а не рассчитывать только на флаг [L] для завершения выполнения ряд правил, как показано ниже.

возможно, Вам потребуется добавить условие перезаписи или предпринять другие шаги для предотвращения цикла.