Как реализовать грамотный ЧПУ? И как потом передавать данные...

R
На сайте с 03.08.2012
Offline
131
5470

Здравствуйте! Мне на сайт нужны грамотные ЧПУ, чтобы было легче программировать (php+mysqli+javascript), и чтобы при большой посещаемости не было проблем.

Я реализовываю ЧПУ следующим образом:

В .htaccess прописал:

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Далее в php файле получаю введенный адрес:

$page = $_SERVER['REQUEST_URI'];

Ну и соответственно далее подгружаю нужную страницу (Не через mysqli, а через include_once('page.php');)

Вопросы:

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

2) Вот я реализовал ЧПУ методом как написал выше. Но я не могу понять, как передавать POST и GET запросы. Ведь там тупо адрес преобразуется в страницу, и если написать page?a=1 то выдаст 404, да и некрасиво так.

Прошу отвечать действительно знающих и разбирающихся людей.

Буду очень благодарен!

Glueon
На сайте с 26.07.2013
Offline
172
#1

Можно придумать какую-нибудь структуру в ЧПУ, по типу /модуль/функция/параметры/параметры/...

На основании этого решать что делать в коде.

Либо изначально жестко задать в RewriteRule различные варианты.

POST/GET обрабатываются точно так же, как и до ЧПУ.

Вы делаете


rewrite .* index.php?params=$1 break

Тогда в $_GET['params'] будет строка типа '/user/showProfile/4', которую вы можете без труда распарсить, а какие-нибудь параметры, типа '/user/showProfile/4?debug=1' будут в $_GET['debug'] отдельно, соотвественно.

В совсем простых случаях делают URL типа /page/страница/параметры. "Страница" выдирается при помощи RewriteRule, затем в коде index.php делается include соотвествующего PHP файла, например, "/page/products/12" - подключается products.php, в котором код уже разбирается что такое 12, которое в том же RewriteRule помещается в GET-параметр params:


rewrite /page/(.+?)/(.+?) /index.php?page=$1&params=$2 break

Но надо быть в таких участках очень осторожным и проверять параметр после page, чтобы злоумышленик не мог в итоге заинклудить что угодно.

Есть много IP-сетей в аренду под прокси, парсинг, рассылки (optin), vpn и хостинг. Телега: @contactroot ⚒ ContactRoot команда опытных сисадминов (/ru/forum/861038), свой LIR: сдаем в аренду сети IPv4/v6 (/ru/forum/1012475).
R
На сайте с 03.08.2012
Offline
131
#2

Я понял. Т.е. можно сделать: /cat/page/parametr1/123

И в итоге получить:

категория = cat;

страница = page;

array (

"parametr1" -> "123"

);

И дальше этот параметр использовать как обычный GET запрос, например выводить статью с id=123.

Правильно я понял? И такая реализация на 2013 год, хорошее решение? Стоит так делать?

Но я не понимаю все равно как передать POST. Допустим пользователь регисрируеться, заполняет данные... Дальше нажимает "ОК". И что происходит? Если в action формы вписано допустим: page2.php, откроется эта страница и будет фиг пойми что.

Или просто в форме в поле action, нужно вписать нормальный адрес типа : /registr

И данные нормально передадутся?

VHS-1980
На сайте с 21.05.2010
Offline
91
#3

а с какого перепуга откроется page2.php?

Все инклуд-скрипты должны быть защищены от самостоятельного вызова. Делается это к примеру так - в файл, через который идут вызовы модулей добавляется определение константы

define("_CMSREQUEST", TRUE);

а в модулях пишется

if(!defined("_CMSREQUEST")) {

die();

}

вообще это одно из основных правил безопасности при создании модульного сайта.

Вообще лучше один раз попробовать, чем спрашивать про передачу параметров из форм.

Пост запрос из

<form action="/">

<input type=hidden name=mod value=page>

идентичен гет запросу /?mod=page

т.е. идентичен с <form action="/page/"> и т.п.

ukrdev
На сайте с 15.11.2011
Offline
31
#4

Насколько я понял, вы собираетесь писать сайт с нуля, поэтому рекомендую потратить немного времени и посмотреть в сторону какого нибудь mvc фреймворка на php(например Yii). Сэкономите кучу времени и нервов. Для того что бы ездить на велосипеде - не обязательно его придумывать заново, можно взять либо готовый велосипед(CMS) либо собрать его самому(Framework).

Что же касается ЧПУ, то рекомендую использовать такой вариант:

RewriteRule ^(.*)\?*$ index.php?r=$1 [L,QSA]

Т.е. основной запрос(маршрут) будет в $_GET['r'], а все остальные параметры если они будут необходимы так же брать из get.

$_GET['r'] - обрабатывать с помощью регулярных выражение или путем разбиения строки(explode) и писать правила.

R
На сайте с 03.08.2012
Offline
131
#5

Проблемка есть: я получаю ссылку вида /категория/страница/

Все работает отлично, НО:

если открыть /категория/ - и вписать название папки (например: /include/), то откроется папка и все её содержание. Прочитал, чтобы скрыть папку нужно в .htaccess прописать: deny from all.

Ну а толку от этого? Мне нужно чтобы если прописывали /категория/, то автоматом открывалась определенная страница: /категория/определенная_страница/ (т.е. в адресной строке также написано сайт.ру/категория/, а на самом деле открыто сайт.ру/категория/определенная_страница/)

У меня на сайте много ajax запросов. (читал что они не работают, если прописывать deny from all).

Помогите, пожалуйста, как реализовать, чтобы все окей работало.

siv1987
На сайте с 02.04.2009
Offline
427
#6
revered:
если открыть /категория/ - и вписать название папки (например: /include/), то откроется папка и все её содержание. Прочитал, чтобы скрыть папку нужно в .htaccess прописать: deny from all.

http://www.google.ru/search?client=opera&q=%D0%B7%D0%B0%D0%BF%D1%80%D0%B5%D1%82+%D0%BB%D0%B8%D1%81%D1%82%D0%B8%D0%BD%D0%B3%D0%B0+%D0%BA%D0%B0%D1%82%D0%B0%D0%BB%D0%BE%D0%B3%D0%BE%D0%B2+apache&sourceid=opera&ie=utf-8&oe=utf-8&channel=suggest

R
На сайте с 03.08.2012
Offline
131
#7

Запретил и что дальше? Просто выдает ошибку... а нужно чтобы открывалась страница другая...

Можно положить в категорию индексный файл, который будет делать перенаправление. Но это как мне кажется плохая идея. Хотелось бы услышать более профессиональное и грамотное решение.

ukrdev
На сайте с 15.11.2011
Offline
31
#8
revered:
Проблемка есть: я получаю ссылку вида /категория/страница/
Все работает отлично, НО:
если открыть /категория/ - и вписать название папки (например: /include/), то откроется папка и все её содержание.

1. Используйте роутинг через параметр get как я вам выше привел пример

2.


#ставим перед обработкой route
RewriteRule ^very_secret_directory/.*$ - [PT]

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

#hide directory
RewriteRule ^very_secret_directory/.*$ - [PT]
RewriteRule ^include/.*$ - [PT]
RewriteRule ^etc/.*$ - [PT]

#RewriteRule ^(.*)\?*$ index.php?route=$1 [L,QSA]
siv1987
На сайте с 02.04.2009
Offline
427
#9
revered:
Запретил и что дальше? Просто выдает ошибку... а нужно чтобы открывалась страница другая...

http://www.google.ru/search?newwindow=1&site=&source=hp&q=errordocument+403

Glueon
На сайте с 26.07.2013
Offline
172
#10
revered:
Я понял. Т.е. можно сделать: /cat/page/parametr1/123
И в итоге получить:
категория = cat;
страница = page;
array (
"parametr1" -> "123"
);
И дальше этот параметр использовать как обычный GET запрос, например выводить статью с id=123.
Правильно я понял? И такая реализация на 2013 год, хорошее решение? Стоит так делать?

Но я не понимаю все равно как передать POST. Допустим пользователь регисрируеться, заполняет данные... Дальше нажимает "ОК". И что происходит? Если в action формы вписано допустим: page2.php, откроется эта страница и будет фиг пойми что.

Или просто в форме в поле action, нужно вписать нормальный адрес типа : /registr
И данные нормально передадутся?

С POST-ом очень просто.

В примере с регистрацией у вас будет страница /page/register. В качество action будет тоже указываться /page/register.

Произойдет include файла register.php в котором будет


if ( isset($_POST['login']) && ... )

Где и будете регистрацию проводить.

В целом можно сказать, что на 2013 год так делать, наверное, не надо. Просто потому, что есть фреймворки, которые уже это делают, учитывая все проверки необходимые :)

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий