Создание пользовательских URL-адресов в конфигурации LAMP

#php #mysql #apache #mod-rewrite #vanity-url

#php #mysql #apache #модификация-переписать #тщеславие-url

Вопрос:

Каков наилучший способ создания пользовательских пользовательских URL-адресов в конфигурации LAMP?

Например, страница профиля пользователя может быть доступна следующим образом:

http://www.website.com/profile.php?id=1

Теперь, если пользователь вводит «URL тщеславия» для своего профиля, я бы хотел, чтобы URL тщеславия загружал страницу выше.

Например, если пользователь выбирает «i.am.a.user» в качестве своего пользовательского URL-адреса, а его идентификатор пользователя в базе данных равен 1, то http://www.website.com/profile.php?id=1 было бы доступно по этому URL и http://www.website.com/i.am.a.user .

Я знаю о перезаписи модов в .htaccess, но не уверен, как это будет работать здесь.

Как я уже упоминал, мой сайт написан на PHP, MySQL, Linux и Apache.

Спасибо.

Комментарии:

1. Как вы думаете, почему modrewite не будет работать?

2. Не могу понять, как mod-rewrite получит значение URL тщеславия

Ответ №1:

Допустим, на других ваших страницах были определенные URL-адреса, которые вы могли бы проверить, следующее должно помочь.

 RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9-_]*)$ /profile.php?user=$1 [L]
  

Это помогает поддерживать текущие URL-адреса, позволяя при этом использовать URL-адреса быстрого доступа пользователя. Кроме того, RewriteRule будут совпадать только URL-адреса, которые не содержат / , что поможет защитить от непреднамеренных перенаправлений. Итак,

 /i-am-a-user -> MATCHES
/i_am_a_user -> MATCHES
/i-!am-a-user -> NOT MATCHED
/i.am.a.user  -> NOT MATCHED
/i.am.a.user/ -> NOT MATCHED
/some/page/ -> NOT MATCHED
/doesnotexist.php -> NOT MATCHED
/doesnotexist.html -> NOT MATCHED
  

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

Редактировать

Я обновил приведенные выше правила, чтобы реальные файлы / каталоги не перенаправлялись, а также убедился, что ни один .php или .html файл также не отправляется в profile.php .

Комментарии:

1. Как бы я защитился от подобного 404 /doesnotexist.php ? Вместо отображения моей страницы 404, если пользователь пытается получить доступ к чему-то подобному, он получает страницу профиля, которая затем перенаправляется на мою домашнюю страницу, потому что там нет допустимых параметров (id или name)?

2. @Tom, я обновил правило, чтобы оно соответствовало только запросам без / и без . . Только что понял, что сейчас i.am.a.user не будет работать, тогда как i-am-a-user будет. Я настрою это снова…

3. Да, я думаю, если мы сможем заставить это правило работать «.» у нас будет решение.

4. На самом деле я вернулся к вашему оригиналу, поскольку не думаю, что разрешу пользователям выбирать URL-адрес тщеславия с «.» в них. Можно ли изменить это регулярное выражение, чтобы разрешать только тщеславные URL-адреса с буквенно-цифровыми символами и тире? Что-то вроде /iam!invalid должно отображать 404, в то время как / iam-valid не будет. Чувак, я ненавижу продолжать настраивать подобным образом, но я просто ужасен с регулярными выражениями.

5. Нет проблем 🙂 Обновил его снова, теперь должен включать только несуществующие буквенно-цифровые URL-адреса

Ответ №2:

Переписать для site.com/user/USERNAME:

В вашем корневом веб-каталоге поместите файл .htaccess:

 RewriteEngine on
RewriteRule ^user/(. )$ profile.php?name=$1 [L]
  

Это перенаправляет все запросы, начинающиеся с «user», на profile.php и передайте URI в $_GET['name'] . Этот метод предпочтительнее, если у вас много файлов / каталогов / других перезаписанных файлов.

Переписать для site.com/USERNAME:

 RewriteEngine on
# if directory or file exists, ignore
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/] )$ profile.php?name=$1 [L]
  

Это перенаправляет на profile.php ТОЛЬКО если запрашивающий файл или каталог не существует, И когда URI запроса не является пустым (т.Е., www.site.com )

Серверная часть PHP

Теперь в profile.php у вас может быть что-то вроде этого:

 if (!empty($_GET['name'])
    $user = ... // get user by username
else 
    $user = ... // get user by id
  

Комментарии:

1. Я бы не рекомендовал этого, поскольку, если у вас нет части /user /, файл htaccess либо станет действительно запутанным, либо весь URL-адрес после вашего домена будет передан $_GET('name')

2. Как Facebook тогда это делает? Они работают под управлением LAMP. Конечно, это масштабно, но концепция должна быть такой же.

3. Взгляните на martinmelin.se/rewrite-rule-tester чтобы протестировать вашу настройку mod_rewrite (отказ от ответственности: только что нашел этот сайт, но жаль, что я не догадался заглянуть пару лет назад).

4. Концепция аналогична, однако затем вы застряли с одним PHP-скриптом, который обрабатывает все запросы. Таким образом, вы должны проверять при каждом запросе, существует ли допустимый пользовательский ярлык, в противном случае найдите правильную страницу.

5. @Tom: У вас просто будет таблица DB с парами URL / PHP-страниц и сверьтесь с ней.

Ответ №3:

Сначала настройте свой файл .htaccess, чтобы отправлять все запросы на файлы и каталоги, которые не существуют, в один php-файл:

 RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) router.php [NC,L]
  

Затем внутри вашего router.php посмотрите на $_SERVER[‘REQUEST_URI’], чтобы получить имя пользователя, которое вы затем можете использовать в своем запросе для получения данных о пользователе.

Предполагается, что все URL-адреса, которые не являются страницами профиля пользователя, существуют в виде физических файлов на вашем сервере.

Если это не так, вы можете выполнить некоторую логику в router.php чтобы решить, что делать по каждому запросу. Выполните поиск в Google для маршрутизации URL-адресов в php, и вы получите множество примеров.

Ответ №4:

Ну, вы могли бы решить эту проблему, конечно, также с помощью apache RewriteMap. Карта перезаписи может быть обычным текстовым файлом (который вы регулярно обновляете на основе того, что вводят ваши пользователи), или, альтернативно, вы могли бы указать на скрипт (Perl, PHP, что вам подходит), который выполнит перезапись за вас.

Краткое описание того, как это настроить с помощью PHP, приведено в разделе Использование базы данных MySQL для управления mod_rewrite через PHP.