У меня есть URL-адрес, который выглядит так:
url.com/picture.php?id=51
Как мне преобразовать этот URL в:
picture.php/Some-text-goes-here/51
Я думаю, что WordPress делает то же самое.
Как мне сделать удобные URL-адреса в PHP?
php
.htaccess
url
mod-rewrite
url-rewriting
Джазерикс
источник
источник
mod_rewrite
это все, что вам нужно для этого, и здесь, на SO, есть много вопросов по этому поводу. И если вы «думаете», что wordpress делает то же самое, почему бы вам просто не поискать его ? ;)Ответы:
Вы можете сделать это двумя способами:
Маршрут .htaccess с mod_rewrite
Добавьте файл с именем
.htaccess
в вашу корневую папку и добавьте что-то вроде этого:RewriteEngine on RewriteRule ^/?Some-text-goes-here/([0-9]+)$ /picture.php?id=$1
Это скажет Apache включить mod_rewrite для этой папки, и если он получит запрос на URL-адрес, соответствующий регулярному выражению, он внутренне переписывает его на то, что вы хотите, чтобы конечный пользователь этого не видел. Легко, но негибко, поэтому, если вам нужно больше мощности:
Маршрут PHP
Вместо этого поместите в свой .htaccess следующее: (обратите внимание на ведущую косую черту)
Это скажет ему запустить ваш
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/invalid-text/51
также приведет к перенаправлению в то же место. Вы также можете добавить проверку, чтобы убедиться, что строка верна, а если нет, перенаправить снова в правильное место. Вот как я сделал это на одном из своих сайтов с помощью htaccess./blog/25
так же, как/picture/51
и/download/684
. Кроме того, это считается очень плохой практикой (и вы будете наказаны за PR в Google!), Если не все случайно сгенерированные URL-адреса будут правильно возвращать 404.FallbackResource /index.php
(обратите внимание на косую черту)FallbackResource
срабатывает только для файлов, которых на самом деле не существует в файловой системе, отсюда и откат . Итак, если у вас есть файл/static/styles.css
и вы ссылаетесь на него, так какhttp://mydomain.tld/static/styles.css
код никогда не выполняется, он работает так, как ожидалось, и прозрачно.if($elements[0] === NULL)
вместо этого, поскольку$elements
все равно будет возвращать счетчик, равный единице, даже если он пуст.Если вы хотите изменить только маршрут,
picture.php
тогда добавление правила перезаписи.htaccess
будет соответствовать вашим потребностям, но если вы хотите, чтобы URL-адрес переписывался, как в Wordpress, то подходящим вариантом является PHP. Вот простой пример для начала.Структура папки
В корневой папке нужны два файла,
.htaccess
иindex.php
, а остальные.php
файлы было бы хорошо поместить в отдельную папку, напримерinc/
..htaccess
В этом файле четыре директивы:
RewriteEngine
- включить движок перезаписиRewriteRule
- запретить доступ ко всем файлам вinc/
папке, перенаправить любой вызов в эту папку наindex.php
RewriteCond
- разрешить прямой доступ ко всем другим файлам (например, изображениям, CSS или скриптам)RewriteRule
- перенаправить все остальное наindex.php
index.php
Поскольку теперь все перенаправлено на index.php, будет определено, правильный ли URL-адрес, все параметры присутствуют и правильный ли тип параметров.
Чтобы проверить 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 ) */ } }
Успешное совпадение, поскольку мы используем именованные подшаблоны в регулярном выражении, заполнит
$params
массив почти так же, как PHP заполняет$_GET
массив. Однако при использовании динамического URL-адреса$_GET
массив заполняется без каких-либо проверок параметров.Этих нескольких строк кода и базовых знаний о регулярных выражениях достаточно, чтобы начать построение надежной системы маршрутизации.
Полный источник
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 или что-то еще
источник
FallbackResource
директиву несколько основных версий назад, которая сейчас является предпочтительным способом реализации этого поведения с меньшими затратами производительности, поскольку не требуется запускать весь механизм перезаписи. Документация здесь . Ваши правила также ошибочны, потому что вы не ссылаетесь на каталоги (!-d
), а все фильтры расширений устарели - они-f
уже должны их отловить.PHP - это не то, что вы ищете, проверьте mod_rewrite
источник
Хотя уже ответил, и намерение автора состоит в том, чтобы создать приложение типа фронт-контроллера, но я публикую буквальное правило для заданной проблемы. если у кого-то возникла проблема.
RewriteEngine On RewriteRule ^([^/]+)/([^/]+)/([\d]+)$ $1?id=$3 [L]
Выше должно работать для URL-адреса
picture.php/Some-text-goes-here/51
. без использования index.php в качестве приложения для перенаправления.источник