Jump to content
  • 0

ЧПУ в PHP


novickOk
 Share

Question

Здравствуйте, у меня сейчас все урлы на сайте выглядят так:

example.com/blog.php?id=23

example.com/article.php?id=15

example.com/about.php

А теперь вопрос: модно ли преобразовать урлы, например в такой вид?

example.com/blog/23/

example.com/article/15/

example.com/about

Надеюсь на вашу помощь.

Link to comment
Share on other sites

Recommended Posts

  • 0

Здравствуйте, у меня сейчас все урлы на сайте выглядят так:

example.com/blog.php?id=23

example.com/article.php?id=15

example.com/about.php

А теперь вопрос: модно ли преобразовать урлы, например в такой вид?

example.com/blog/23/

example.com/article/15/

example.com/about

Надеюсь на вашу помощь.

Да, конечно можно. Погуглите htaccess rewriterule или рерайты для вашего веб-сервера, если у вас не apache

Link to comment
Share on other sites

  • 0

Вот написал немного простой реализации

1. Создаёшь файл .htaccess

2. Закидываешь туда строки

RewriteEngine on
Options +FollowSymlinks
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L,QSA]

3. В обработчике (index.php) делаешь это

// проверяем на корректность адреса в адресной строке
if(ltrim(strpos($_SERVER['REQUEST_URI'], 'index.php'), '/') == 1 AND $_SERVER['REQUEST_METHOD'] == 'GET'){
//Преобразование URL`а
$link = getUrlToSef('index.php?' . $_SERVER['QUERY_STRING']);

// Переадресация на SEF-адрес
header("Location: " . $link, TRUE, 301);
exit(301);
}

// получаешь массив страниц
$url = explode('/', $_SERVER['REQUEST_URI']);

// определяешь основной переход
$pages = (isset($url[1])) ? $url[1] : '';

switch ($pages) {
// обрабатываем страницу blog
case 'blog':

// получаем ID
$id = (isset($url[2])) ? intval($url[2]) : 0;

// передаём на обработку
fBlog($id);

break;

// обрабатываем страницу article
case 'article':

// получаем ID
$id = (isset($url[2])) ? intval($url[2]) : 0;

// передаём на обработку
fArticle($id);

break;

// обрабатываем страницу about
case 'about':

// передаём на обработку
fAbout();

break;
default :
fDefault();
}

// функция для обработки страницы по умолчанию
function fBlog($id=0){
// .......
}

// функция для обработки страниц Blog
function fBlog($id=0){
// .......
}

// функция для обработки страниц Article
function fArticle($id=0){
// .......
}

// функция для обработки страниц About
function fAbout(){
// .......
}

// функция для "нормализации" адреса
function getUrlToSef($link){
// Оснавная обработка
$link = str_replace('&', '&', $link);

// Разбирает URL и возвращает его компоненты
$url = parse_url($link);

// проверяем часть fragment (после знака диеза #)
$fragment = '';
if(isset($url['fragment'])){
// Проверка на валидность
if(preg_match('@^[A-Za-z][A-Za-z0-9:_.-]*$@', $url['fragment'])){
$fragment = '#' . $url['fragment'];
}
}

// проверяем часть query после знака вопроса ?
if(isset($url['query'])){
// специальная обработка для javascript
$url['query'] = stripslashes(str_replace('+', '%2b', $url['query']));

// очистить возможные атаки XSS
$url['query'] = preg_replace("'%3Cscript[^%3E]*%3E.*?%3C/script%3E'si", '', $url['query']);

// разбиваем строку (URL) на части
parse_str($url['query'], $parts);

// формируем ссылку
$link = '';
foreach($parts as $value){
$link .= $value . '/';
}
}
// формируем ссылку
$link = $_SERVER['HTTP_HOST'] . '/' . $link . $fragment;

// возвращаем ссылку
return $link;
}

Edited by Gold Dragon
Link to comment
Share on other sites

  • 0

Gold Dragon, спасибо за код, но вот насколько я понял если я добавлю страницу rules.php, то придется лезть в обработчик и вручную добавлять код. Можно ли сразу у всех php-файлов обрубать расширение?

Link to comment
Share on other sites

  • 0

LunatiK, думаешь не будет работать?

всё вроде подробно прокомментировал

Да, не в работоспособности я не сомневался, развеселило слово простой

Думаю проще сделать регулярками правило нежели на пыхе разбирать всё это. (во всяком случае в данном случае :) )

Link to comment
Share on other sites

  • 0

novickOk, что значит "добавлю"?

модет ты про такое?

Допустим есть страница какая-то rules.php.

Значит чтобы на неё попасть нам нужно ввести адрес

example.com/rules

Теперь несколько вариантов решения.

1. Добавить в обработчик новое условие (я предпочитаю именно этот вариант)


// обрабатываем страницу about
case 'rules':

// передаём на обработку
fRules();

break;

2. И второй вариант получить из строки страницу 'rules'

и подключить соответствующий файл, что-то типа такого

$pages = (isset($url[1])) ? $url[1] : '';
if(file_exists('ПУТЬ_ДО_ФАЙЛА/' . $pages . 'php'){
require_once('ПУТЬ_ДО_ФАЙЛА/' . $pages . 'php');
}

Думаю проще сделать регулярками правило нежели на пыхе разбирать всё это.
Да куда проще-то :) ну просто я добавил несколько проверок, да переадресаций. Просто вдруг понадобится отключать ЧПУ..ну и уже с маленьким кодом реализации (как применять то всё это).

Просто сейчас пишу SEF для движка, по этому это очень простая реализация :rolleyes: А вот в движке уже проблема.. для каждого компонента свой Sef-файл и своя реализация... Вот там я уже все мозги зажарил...

Да, кстати, забыл... по нормальному ссылки будут такими

_http://example.com/index.php?page=blog&id=23

_http://example.com/index.php?page=article&id=15

_http://example.com/index.php?page=about

т.е. всё подключение через файл index.php

Edited by Gold Dragon
Link to comment
Share on other sites

  • 0

Да, кстати, забыл... по нормальному ссылки будут такими

_http://example.com/index.php?page=blog&id=23

_http://example.com/index.php?page=article&id=15

_http://example.com/index.php?page=about

т.е. всё подключение через файл index.php

Пичалька, не то, что мне надо. Но все равно спасибо.

Пойду искать и надеюсь мое божество не подведет меня.

Edited by novickOk
Link to comment
Share on other sites

  • 0

А причина не использовать такой способ? Вообще-то он более правильный и безопасный

Не нравятся мне все эти атрибуты "динамичности", мне больше нравятся такие адреса: example.com/blog/515/ потому что...

потому что нравятся.

Не могу объяснить, просто нравятся

Link to comment
Share on other sites

  • 0

ну так моим кодом это

_http://example.com/index.php?page=blog&id=23

_http://example.com/index.php?page=article&id=15

_http://example.com/index.php?page=about

и будет преобразовано в это

_http://example.com/blog/23

_http://example.com/article/15

_http://example.com/about

так что введя любой из адресов получится последний

но при этом вход один в систему. и это очень безопасно, т.к. контролировать придётся всё в одном месте, а не в каждом файле

Link to comment
Share on other sites

  • 0

ну так моим кодом это

_http://example.com/index.php?page=blog&id=23

_http://example.com/index.php?page=article&id=15

_http://example.com/index.php?page=about

и будет преобразовано в это

_http://example.com/blog/23

_http://example.com/article/15

_http://example.com/about

так что введя любой из адресов получится последний

но при этом вход один в систему. и это очень безопасно, т.к. контролировать придётся всё в одном месте, а не в каждом файле

ну извините, просто я вас неправильно понял.

Link to comment
Share on other sites

  • 0

А что мешает написать типа того:


Options +FollowSymLinks
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([A-Za-z0-9_-]+)/([A-Za-z0-9_-]+)/?$ /$1.php?id=$2 [L]
RewriteRule ^([A-Za-z0-9_-]+)/?$ /$1.php [L]

К чему эти вмешательства в код движка? Я ещё понимаю если он в стадии разработки, но вот если уж всё готово.

Link to comment
Share on other sites

  • 0

так в данном случае ничего не мешает, мы то знаем практически все адреса какие возможно.. :)

вот только структура адресной строки отдельных компонентов сайта бывает очень и очень разной.. всё не предусмотреть..

и всё таки ЧПУ это часть ядра, а не просто надстройка.. так что в код придётся лезть

а если понадобится строка не

_http://example.com/blog/23

а что-то такое

_http://example.com/blog/moya_pervaya_straniza.html

Link to comment
Share on other sites

  • 0

так в данном случае ничего не мешает, мы то знаем практически все адреса какие возможно.. :)

вот только структура адресной строки отдельных компонентов сайта бывает очень и очень разной.. всё не предусмотреть..

и всё таки ЧПУ это часть ядра, а не просто надстройка.. так что в код придётся лезть

а если понадобится строка не

_http://example.com/blog/23

а что-то такое

_http://example.com/blog/moya_pervaya_straniza.html

Я написал под конкретную структуру. На вашем примере в $_GET[id] уйдёт 'moya_pervaya_straniza.html' Если модуль это схавает то флаг ему вруки, если нет, то и такой страницы не будет

Я не вижу разницы написать правила под каждый модуль или фигачить эти правила в php с вашим множественным «case», даже правила писать удобней.

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

Link to comment
Share on other sites

  • 0

LunatiK, так я согласен с тобой полностью :) и даже не спорю..

Просто у этого способа есть некоторые "НО".. Например, передача ведь идёт на конкретный файл, а если файла не существует

Link to comment
Share on other sites

  • 0

Gold Dragon, проще уже в админке писать урл вида:

title: Блог

url: blog

или если хошь автоматом преобразовывать кириллицу в транслит типа:

title: Новости

url: novosti

в меню уже все это дело будет вытаскиваться из бд, а в .htaccess преобразовываться, да и отдельных файлов не нужно, все запросы обрабатываются в index.php ;)

Link to comment
Share on other sites

  • 0

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

ps

хотя все правила засовывать в .htaccess очень не гибко.. ну если только для простенького сайтика :boast:

pss

интересно, а много веб-серверов на апаче вообще..

Link to comment
Share on other sites

  • 0

Танкист здесь походу один я <_<.

Решение Gold Dragon я не переварил (ибо я несколько туповат) и пошел копать в сторону .htaccess.

Сначала, естественно, зашел в Википедию и нашел там реализацию

RewriteEngine on
RewriteRule ^article/([0-9]+)/? article.php?id=$1 [L]

Первая строчка включает mod_rewrite. Во второй указывается, что веб-сервер при запросе URL вида /article/450/ должен обратиться к /article.php?id=450 .

Это то, что мне нужно! Но так как я танкист(см первую строчку), то переделать "под себя" я не смог.

Поможете? :huh:

Edited by novickOk
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy