У меня есть URL-адрес, который выглядит так:
url.com/picture.php?id=51
Как я могу конвертировать этот URL-адрес в:
picture.php/Some-text-goes-here/51
Я думаю, что WordPress делает то же самое.
Как мне сделать дружественные URL-адреса в PHP?
У меня есть URL-адрес, который выглядит так:
url.com/picture.php?id=51
Как я могу конвертировать этот URL-адрес в:
picture.php/Some-text-goes-here/51
Я думаю, что WordPress делает то же самое.
Как мне сделать дружественные URL-адреса в PHP?
Вы можете сделать это двумя способами:
Добавьте в корневую папку файл с именем .htaccess
и добавьте что-то вроде этого:
RewriteEngine on
RewriteRule ^/?Some-text-goes-here/([0-9]+)$ /picture.php?id=$1
Это скажет Apache, чтобы включить mod_rewrite для этой папки, и если ему будет задан URL-адрес, соответствующий регулярному выражению, он переписывает его внутри того, что вы хотите, без того, чтобы конечный пользователь его видел. Легко, но негибко, поэтому, если вам нужно больше энергии:
Поместите вместо этого в свой .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]
Этот файл имеет четыре директивы:
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
заполняется без каких-либо проверок параметров.
/picture/some+text/51 Array ( [0] => /picture/some text/51 [text] => some text [1] => some text [id] => 51 [2] => 51 ) picture.php?text=some+text&id=51 Array ( [text] => some text [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 в качестве приложения перенаправления.