Переписывание URL-адресов с помощью PHP

У меня есть URL-адрес, который выглядит так:

url.com/picture.php?id=51 

Как мне перейти на преобразование этого URL-адреса в:

 picture.php/Some-text-goes-here/51 

Я думаю, что WordPress делает то же самое.

Как мне сделать дружественные URL-адреса в PHP?

Solutions Collecting From Web of "Переписывание URL-адресов с помощью PHP"

Вы можете сделать это двумя способами:

Маршрут .htaccess с mod_rewrite

Добавьте в корневую папку файл .htaccess и добавьте что-то вроде этого:

 RewriteEngine on RewriteRule ^/?Some-text-goes-here/([0-9]+)$ /picture.php?id=$1 

Это скажет Apache, чтобы включить mod_rewrite для этой папки, и если ему будет задан URL-адрес, соответствующий регулярному выражению, он перезаписывает его внутри того, что вы хотите, без того, чтобы конечный пользователь его видел. Легкая, но негибкая, поэтому, если вам нужно больше энергии:

Маршрут PHP

Вместо этого поставьте вместо этого следующее .htaccess:

 FallbackResource index.php 

Это скажет, что он запускает ваш index.php для всех файлов, которые он обычно не может найти на вашем сайте. Там вы можете, например:

 $path = ltrim($_SERVER['REQUEST_URI'], '/'); // Trim leading slash(es) $elements = explode('/', $path); // Split path on slashes if(empty($elements[0])) { // No path elements means home ShowHomepage(); } else switch(array_shift($elements)) // Pop off first item and switch { case 'Some-text-goes-here': ShowPicture($elements); // passes rest of parameters to internal function break; case 'more': ... default: header('HTTP/1.1 404 Not Found'); Show404Error(); } 

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

Если вы хотите изменить маршрут для picture.php то добавление правила перезаписи в .htaccess будет отвечать вашим потребностям, но если вы хотите переписать URL-адрес, как в WordPress, то PHP – это способ. Вот простой пример для начала.

Структура папок

В корневой папке есть два файла .htaccess и index.php , и было бы неплохо разместить остальные .php файлы в отдельной папке, например inc/ .

 root/ inc/ .htaccess index.php 

.htaccess

 RewriteEngine On RewriteRule ^inc/.*$ index.php RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php [QSA,L] 

Этот файл имеет четыре директивы:

  1. RewriteEngine – включить механизм перезаписи
  2. RewriteRule – запрещает доступ ко всем файлам в папке inc/ , перенаправляет любой вызов этой папки на index.php
  3. RewriteCond – разрешает прямой доступ ко всем другим файлам (например, изображениям, css или скриптам)
  4. RewriteRule – перенаправить что-нибудь еще в index.php

index.php

Поскольку все теперь перенаправлено на index.php, будет определено, правильно ли указатель, все параметры присутствуют, и если тип параметров правильный.

Чтобы проверить URL-адрес, нам нужно иметь набор правил, и лучшим инструментом для этого является регулярное выражение. Используя регулярные выражения, мы ударим двух мух одним ударом. Url, чтобы пройти этот тест, должны иметь все необходимые параметры, которые проверяются на допустимых символах. Вот несколько примеров правил.

 $rules = array( 'picture' => "/picture/(?'text'[^/]+)/(?'id'\d+)", // '/picture/some-text/51' 'album' => "/album/(?'album'[\w\-]+)", // '/album/album-slug' 'category' => "/category/(?'category'[\w\-]+)", // '/category/category-slug' 'page' => "/page/(?'page'about|contact)", // '/page/about', '/page/contact' 'post' => "/(?'post'[\w\-]+)", // '/post-slug' 'home' => "/" // '/' ); 

Далее следует подготовить запрос uri.

 $uri = rtrim( dirname($_SERVER["SCRIPT_NAME"]), '/' ); $uri = '/' . trim( str_replace( $uri, '', $_SERVER['REQUEST_URI'] ), '/' ); $uri = urldecode( $uri ); 

Теперь, когда у нас есть запрос uri, последний шаг – проверить uri на правила регулярных выражений.

 foreach ( $rules as $action => $rule ) { if ( preg_match( '~^'.$rule.'$~i', $uri, $params ) ) { /* now you know the action and parameters so you can * include appropriate template file ( or proceed in some other way ) */ } } 

Успешное совпадение будет, поскольку мы используем именованные подшаблоны в regex, заполняем массив $params почти таким же, как PHP заполняет массив $_GET . Однако при использовании динамического url массив $_GET заполняется без каких-либо проверок параметров.

     / Изображение / текст + некоторые / 51

     массив
     (
         [0] => / картинка / текст / 51
         [текст] => текст
         [1] => некоторый текст
         [id] => 51
         [2] => 51
     )

     picture.php? текст = некоторые + текст & ID = 51

     массив
     (
         [текст] => текст
         [id] => 51
     )

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

Полный источник

 define( 'INCLUDE_DIR', dirname( __FILE__ ) . '/inc/' ); $rules = array( 'picture' => "/picture/(?'text'[^/]+)/(?'id'\d+)", // '/picture/some-text/51' 'album' => "/album/(?'album'[\w\-]+)", // '/album/album-slug' 'category' => "/category/(?'category'[\w\-]+)", // '/category/category-slug' 'page' => "/page/(?'page'about|contact)", // '/page/about', '/page/contact' 'post' => "/(?'post'[\w\-]+)", // '/post-slug' 'home' => "/" // '/' ); $uri = rtrim( dirname($_SERVER["SCRIPT_NAME"]), '/' ); $uri = '/' . trim( str_replace( $uri, '', $_SERVER['REQUEST_URI'] ), '/' ); $uri = urldecode( $uri ); foreach ( $rules as $action => $rule ) { if ( preg_match( '~^'.$rule.'$~i', $uri, $params ) ) { /* now you know the action and parameters so you can * include appropriate template file ( or proceed in some other way ) */ include( INCLUDE_DIR . $action . '.php' ); // exit to avoid the 404 message exit(); } } // nothing is found so handle the 404 error include( INCLUDE_DIR . '404.php' ); 

это файл .htaccess, который перенаправляет почти все на index.php

 # if a directory or a file exists, use it directly RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-l RewriteCond %{REQUEST_URI} !-l RewriteCond %{REQUEST_FILENAME} !\.(ico|css|png|jpg|gif|js)$ [NC] # otherwise forward it to index.php RewriteRule . index.php 

то вам придется разбирать $ _SERVER ["REQUEST_URI"] и направлять на picture.php или что угодно

PHP не то, что вы ищете, посмотрите mod_rewrite

Хотя уже ответили, и автор намерен создать приложение типа front controller, но я отправляю буквальное правило для заданной проблемы. если у кого-то проблема такая же.

 RewriteEngine On RewriteRule ^([^/]+)/([^/]+)/([\d]+)$ $1?id=$3 [L] 

Выше должно работать для url picture.php/Some-text-goes-here/51 . без использования index.php в качестве приложения перенаправления.