2010-10-31 1 views
1

Как почти каждый программист, я пишу свою собственную фреймворк PHP для образовательных целей. И теперь я рассматриваю проблему с разбором URL-адресов для маршрутизации MVC.Безопасная маршрутизация в моей собственной структуре с использованием PHP - как

Рамки будут использовать дружественные URL-адреса повсюду. Но вопрос заключается в том, как разбирать их на переднем контроллере. Например, ссылка /foo/bar/aaa/bbb может означать «Вызвать панель действий foo контроллера и передать параметр aaa со значением bbb. Но если кто-то установит фреймворк в подкаталог корня домена, часть каталога должна быть удалена до определения имени контроллера и имени действия . И я ищу способ сделать это безопасно.

Кроме того, я хотел бы поддержать резервный случай, если URL переписывания не поддерживается на сервере.

в разных системах разные наборы $ _SERVER переменных например, на моей локальной машине из набора PATH_INFO, REQUEST_URI, REQUEST_URL, ORIG_REQUEST_URI, SCRIPT_NAME, PHP_SELF только REQUEST_URI, SCRIPT_NAME и PHP_SELF. Интересно, могу ли я на них положиться.

Зрелые фреймворки, такие как Symfony или ZF, имеют некоторые сложные алгоритмы анализа URL-адресов (по крайней мере, это было так). Поэтому я не могу просто принять участие оттуда для себя.

ответ

1

В настоящее время я делаю то же исследование. Но все, что я вижу, настолько сложно, что я, скорее всего, продолжу использовать mod_rewrite. В конце концов, вы получаете то же самое, но используете SEF с PHP или mod_rewrite с apache. Во всяком случае, я буду внимательно следить за этой темой .. интересно :) Надежда на PHP гуру здесь есть больше информации об этом :)

Edit:
Это действительно зависит от того, что вы хотите сделать. Для моих нужд я жестко запрограммировал большинство страниц, чтобы они выглядели SEF. Но что-то вроде приведенного ниже примера должно работать.

RewriteEngine on 
RewriteRule ^/posts/([A-Za-z0-9_\-]+)/([A-Za-z0-9_\-]+)\.html$ posts.php?$1=$2 [NC] 

В этом примере выше:

http://localhost/posts/view/23 
http://localhost/posts/delete/23 

равно:

http://localhost/posts.php?view=23 
http://localhost/posts.php?delete=23 

Это действительно зависит от того, что именно вы делаете :) Приведенный выше пример должен работать, но Я их не тестировал.

+0

Какой конфиг mod_rewrite вы используете? –

+0

Извините за задержанный ответ. Проверьте мой отредактированный ответ :) – tftd

0

Возможно, вы могли бы взять PHP_SELF и удалить первые n символов, где n - длина SCRIPT_NAME.

Edit: Ой ... кажется, что вы можете просто взять PHP_SELF: http://php.about.com/od/learnphp/qt/_SERVER_PHP.htm

+0

На моей домашней машине SCRIPT_NAME = PHP_SELF –

2

Два пути решения проблемы:

  1. Добавить конфигурационный переменную URL/каталог инсталяция в приложение, и лишить его от $_SERVER['REQUEST_URI']
  2. Сделать апач переписать его, чтобы получить переменную

    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteCond %{REQUEST_FILENAME} !-d 
    RewriteRule (.*) index.php?myrequest=$1 [QSA,L] 
    
+0

Поскольку многие люди используют более быстрый сервер Nginx, я бы просто пошел с чередованием PHP, если вы планируете обмен файлами. – Xeoncross

+0

Как насчет того, чтобы взять dirname из PHP_SELF и удалить его с начала REQUEST_URI? И имеет ли это эквивалент на nginx и IIS? –

+1

Я не знаю об IIS, но это также должно быть возможно в nginx. Использовать только имя файла сценария во многих случаях будет недостаточно: символические ссылки, каталоги пользователей ('server.com/~ johndoe /' -> '/ home/johndoe/www /'), больше одного места для глубокого размещения в одной директории ('server. com/others/testit/yourapp') и, возможно, еще много –

1

Я обычно использую следующие для определения приложения базы URL-путь, предполагая, что все ваши запросы всегда проходит через тот же сценарий шлюза:

$base = dirname($_SERVER['PHP_SELF']); 

Для вашего второго вопроса, если вы хотите проверить, если mod_rewrite включен , вы можете использовать:

if (in_array('mod_rewrite', apache_get_modules())) { 
    // rewrite is enabled 
} 

Однако, это не обязательно означает, что RewriteEngine включена, так что вы, вероятно, следует использовать дополнительное условие:

if (in_array('mod_rewrite', apache_get_modules()) && 
    preg_match('/RewriteEngine +On/i', file_get_contents('/path/to/.htaccess'))) { 
    // rewrite is enabled and active 
} 
+0

Будет ли это также работать на случаи @ dev-null-dweller, указанные в его комментарии? –

+0

PHP_SELF содержит имя исполняемого скрипта, относящегося к корню документа, в соответствии с конфигурацией веб-сервера, а не файловой системой. Символы и другие материалы, упомянутые @ dev-null-dweller, не влияют на это. – netcoder

+0

Необходимо указать, что apache_get_modules() недоступен в системах с PHP в режиме CGI/FastCGI. –