За последние 24 часа нас посетили 22535 программистов и 1017 роботов. Сейчас ищут 704 программиста ...

ЧПУ, mod_rewrite, MVC

Тема в разделе "PHP для новичков", создана пользователем Qumo, 19 фев 2016.

  1. Qumo

    Qumo Активный пользователь

    С нами с:
    6 июн 2013
    Сообщения:
    160
    Симпатии:
    0
    Привет, ребята. Нашел в инете код простой MVC https://habrahabr.ru/post/150267/.У меня все то же самое, кроме .htaccess.
    Вот мой:
    Код (PHP):
    1. AddDefaultCharset utf-8
    2. RewriteEngine On
    3. RewriteCond %{REQUEST_FILENAME} !-f
    4. RewriteCond %{REQUEST_FILENAME} !-d
    5. RewriteRule .* index.php?id=$1 [QSA,L]
    В БД у меня хранятся URL типа index, gallery и т.д. В меню ссылки у меня так:
    Код (PHP):
    1. <a href='.$menu['url'].'?id='.$menu['id'].'>
    НО, при переходе выдает 404. Не пойму, как передать при подобном mod_rewrite в URL id страницы, чтобы переход по страницам работал и ЧПУ тоже? Или его(htaccess) надо как-то править?

    P.S.: на инъекции пока что пофиг=)
     
  2. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    во-первых мне кажется у тебя неправильный рерайт-рул. что в бакс-один хранится? откуда оно берется?
    во-вторых у тебя кажется не совсем правильное понятие того как на самом деле работает чпу.
    вот ты привел ссылку на хабре. представим себе что есть простой пхп-сайт. и представим урл вида /index.php?module=post&id=150267 - красивый? не очень-то. теперь меняем урл на /post/150267/ - красивый? ну да, что-то сексуальное в нем есть. но пхп о нем не знает. поэтому через правильно вида ^/(.+)/(\d+)/$ /index.php?module=$1&id=$2 мы уведомляем пхп-машину о том какой некрасивый адрес соответствует этому красивому. приходит запрос к красивому адресу. рерайтер его переделывает в другой урл и передает дальше. браузер об этом не знает ничего на самом деле. это стадия разрешения запроса вебсервером.

    теперь про то как хранятся у тебя урлы.
    ничего не находишь? у тебя в урле который хранится есть ?id=что-то. то есть когда пхп-машина сформирует исходный код страницы там будут ссылки похожие на первый пример - ?id=что-то. а тебе нужно чтоб было как во втором примере. рерайтер ничего не знает про ссылки в исходном коде страницы. он их не переписывает из некрасивой формы в красивую. рерайтер работает только со входящим запросом. чтоб чпу успешно работал - ссылки в отдаче уже должны быть в красивом виде. то есть и в базе тоже.
     
  3. Qumo

    Qumo Активный пользователь

    С нами с:
    6 июн 2013
    Сообщения:
    160
    Симпатии:
    0
    Спасибо за ответ. Так у меня из БД в меню передаются параметры, если вместо переменных, то это выглядит вот так:
    index?id=1(тут ид может и другой быть). Как я понимаю, он(mod_rewrite) работает так: при получении ссылки в строке браузера, он ее подменяет. Если я тебя правильно понял, то мне в БД надо будет написать вот так(?):
    Код (PHP):
    1. index?id= 
    Попробовал, но нет. Что-то не совсем понял, почему он не хочет подменять ид? 404 и все...=( ID на любом айте автоматом берут5я. Типа вида, который ты написал- /index.php?module=post&id=150267 Реврайт их обрабатывает, т.к. при нажатии на ссылку, она автоматом принимает из /index.php?id='.$id.' в такой index/12 (например). Или не?
     
  4. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.553
    Симпатии:
    1.754
    Qumo, перечитай внимательно то, что Ganzal написал, даже с примером. mod_rewrite ничего в адресной строке не подменяет, он просто говорит серверу, что обрабатывать запрос будет не файл, который буквально вытекает из пришедшего запроса, а какой-то другой файл.

    Если тебя устраивает ?id=, для чего тебе рерайтер?

    И ещё раз. Вот пример с хабра. https://habrahabr.ru/post/150267/. Если мы предположим, что там нету рерайтера (или аналога из ngnix), то получается, что сервер должен в корне сайта найти каталог post, в нём каталог 150267, а в нём - файл index.html, index.php или что-то в этом роде в зависимости от настройки. Но включив рерайтер, мы можем сказать серверу: подобные урлы будет обрабатывать файл index.php в корне сайта, там есть программа, которая сама разберётся, что выдать, не беспокойся. В адресной строке всё равно мы видим тот же урл, как если бы рерайтера не было.
     
  5. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    из строки браузера. браузер отсылает к серверу запрос по протоколу передачи гипертекста. в этом запросе обязательным полем является строка вида GET /path/to/resource HTTP/1.1 - собственно метод запроса к ресурсу, адрес ресурса относительно корня виртуального хоста, и желаемый протокол обмена сообщениями.

    неправильно понял. хранить надо /id/твой-айди или как-то так. сами чпу хранить. чтоб когда браузер делает к ним запрос - рерайтеру было что во что-то превращать. когда ты хранишь index?id - у тебя уже явно указан какой-то аргумент. а это немного не чпу подход.
     
  6. Qumo

    Qumo Активный пользователь

    С нами с:
    6 июн 2013
    Сообщения:
    160
    Симпатии:
    0
    Про5то я думал, что можно будет передавать id через глобальный массив $_GET['id'] в другую переменную, типа вот так:
    $id = $_GET['id'], чтобы потом юзать переменную $id в нужных мне местах. Что-то такое, зависимо на какой мы странице, если ее id = 1(например), то он и выводит для нее данные в определенных местах.
     
  7. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    при чем тут тогда чпу? если тебе надо айдишник передать - сделай урл через например echo '/path/'.$_GET['id'] . '/'; - на выходе будет чпу который ты потом разгребешь через рерайтер. впрочем ты же можешь сочетать чпу и передачу аргументов.
     
  8. Qumo

    Qumo Активный пользователь

    С нами с:
    6 июн 2013
    Сообщения:
    160
    Симпатии:
    0
    Смотри=)
    Код (PHP):
    1. <?php foreach (select_pages() as $menu){
    2.             $i = $menu['id'];
    3.             echo '<li class="menu__item"><a href='.$menu['url'].' class="menu__link">'.$lang[$i]['menu'].'</a>
    4.                 </li>';}?>
    Так вот id бы он получал из $menu['id'], соответственно, я бы смог юзать глобальный массив $_GET['id'], и передавать его куда мне нужно. Но вот если я изменяю текущий код из того, что выше на этот:
    Код (PHP):
    1. echo '<li class="menu__item"><a href='.$menu['url'].'?id='.$menu['id'].' class="menu__link">'.$lang[$i]['menu'].'</a>';}
    то 404. + ко всему я не могу использовать адреса для языков: ?lang=rus и ?lang=eng - тоже 404.
     
  9. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    а html на выходе как выглядит? и какие правила рерайтера?
     
  10. Qumo

    Qumo Активный пользователь

    С нами с:
    6 июн 2013
    Сообщения:
    160
    Симпатии:
    0
    Правила те же:
    Код (PHP):
    1. AddDefaultCharset utf-8
    2. RewriteEngine On
    3. RewriteCond %{REQUEST_FILENAME} !-f
    4. RewriteCond %{REQUEST_FILENAME} !-d
    5. RewriteRule .* index.php?id=$1 [QSA,L] 
    html на выходе 404=))
     
  11. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    ну давай расскажи мне суть всех директив рерайтера, которые тут написаны. дословно. как ты это понимаешь.
     
  12. Qumo

    Qumo Активный пользователь

    С нами с:
    6 июн 2013
    Сообщения:
    160
    Симпатии:
    0
    Включаем рерайтер
    Не обрабатываем все существующие файлы
    То же самое, что и 2, но только папки
    При любой строке запроса, открываем index.php, и добавляем строку запроса в $_SERVER['REQUEST_URI']
     
  13. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    ты флаги забыл описать.

    вот этот момент немного не так. .* - это действительно захватывает любой адрес запроса. но index.php переадресует к файлу индекс.пхп лежащему в директории текущего запрашиваемого ресурса.
    изначальный адрес запроса и так всегда доступен в REQUEST_URI. из имени этой переменной же видно что это именно запрошенный ресурс. а кто у нас ресурсы запрашивает? правильно. браузер у сервера.
    далее. ?id=$1 - добавить при вызове аргумент "айди" содержащим ничего. почему ничего? потому что бакс-ван-у не соответствует никакой группы захвата. это же регулярные выражения. слева видно .* - это просто соответствие. любой символ ноль и более раз. но это не создает группу.
    кстати зачем её создавать и передавать как аргумент? у тебя же REQUEST_URI и так содержит оригинальный адрес запроса.
     
  14. Qumo

    Qumo Активный пользователь

    С нами с:
    6 июн 2013
    Сообщения:
    160
    Симпатии:
    0
    Я уже до такого уже запарился, что капец...все из-за получения глобального массива $_GET['id']. Мне нужно его получить для использования в других местах, но что-то не дает мне этого сделать. Всегда 404.
     
  15. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    а как ты отлаживаешь?
     
  16. Qumo

    Qumo Активный пользователь

    С нами с:
    6 июн 2013
    Сообщения:
    160
    Симпатии:
    0
    var_dump=) и функция, чтобы читабельнее был вид массива:
    Код (PHP):
    1. function view($array){
    2.     echo "<pre>" . print_r($array, true) ."</pre>";
    3. }
    Добавлено спустя 5 минут 16 секунд:
    Офигеть, как у меня в глобальном массиве $_GET['id'] оказался url, который в БД?! WTF?!
     
  17. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    ну молодец. вардамьпь дальше. аутистом можно назвать? я очень люблю так называть людей которые не любят пользоваться головой. у тебя что гугла нет? ты не знаешь где мануалы по используемым технологиям лежат? почему ты запарился вардампить пхп-скрипт если у тебя запрос даже не доходит до пхп-машины? почему не отлаживать рерайтер? я выше уже указал на очевидные проблемы. почему ты продолжаешь париться перед компом вместо того чтоб получить из первоисточника всю необходимую информацию, родить нужный алгоритм и пойти париться в баньку? в баньке всяк полезнее париться. твой аргумент айди переданный в адресе - никуда не пропадет. потому что есть флаг куэса назначения которого ты очевидно не очень понимаешь. мне кажется ты пытаешься сочетать технологии по которым у тебя просто нет еще нужного уровня знаний. ты видимо как-то бегло всё пропустил. но как видишь тебе этот бег создает огромные трудности. возможно стоит тормознуть и пойти почитать мануал. пописать простые скриптики на базе которых понять как что на самом деле работает. а потом уже пытаться внедрить это куда-то еще.
     
  18. Qumo

    Qumo Активный пользователь

    С нами с:
    6 июн 2013
    Сообщения:
    160
    Симпатии:
    0
    Блин, вот я косячнул=) В рерайтере сам же прописал, и теперь туплю, почему же так=)
     
  19. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    воооот, похоже на правду))) ты включи дебаг рерайтера, сделай запрос, и прочитай какая логика случилась у рерайтера при обработке этого запроса.
     
  20. machetero

    machetero Активный пользователь

    С нами с:
    25 окт 2014
    Сообщения:
    499
    Симпатии:
    21
    А зачем хранить ссылки сайта в бд ?
     
  21. Qumo

    Qumo Активный пользователь

    С нами с:
    6 июн 2013
    Сообщения:
    160
    Симпатии:
    0
    Алиас=)
     
  22. Qumo

    Qumo Активный пользователь

    С нами с:
    6 июн 2013
    Сообщения:
    160
    Симпатии:
    0
    Блин, реально уже не пойму, почему не принимает id, а 404 выдает. Передаю алиас, передаю ид, он 404 выдает=(
    Так. Есть алиас, который при переходе по страницам передается в адресную строку, также есть у всех страниц свой id, который тоже должен передаваться в адресную строку, но по непонятным мне причинам, ничего, кроме алиаса не хочет восприниматься, а если передавать id, то 404 выходит. Получается должно получится в строке gallery?id=1(например). А получается 404.
     
  23. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    отладочный лог рерайтера в студию
     
  24. Qumo

    Qumo Активный пользователь

    С нами с:
    6 июн 2013
    Сообщения:
    160
    Симпатии:
    0
    Код (PHP):
    1. [Sat Feb 20 22:15:31 2016] [error] [client 127.0.0.1] File does not exist: Z:/home/test.ru/www/gallery, referer: http://test.ru/404
    2. [Sat Feb 20 22:15:34 2016] [error] [client 127.0.0.1] File does not exist: Z:/home/test.ru/www/price, referer: http://test.ru/404
    3. [Sat Feb 20 22:15:36 2016] [error] [client 127.0.0.1] File does not exist: Z:/home/test.ru/www/learn, referer: http://test.ru/404
    4. [Sat Feb 20 22:15:38 2016] [error] [client 127.0.0.1] File does not exist: Z:/home/test.ru/www/learn, referer: http://test.ru/404
    Это он типа не может найти файл, но т.к. у меня под MVC(по примеру на хабре). Все представления хранятся в папке core/view. Файл запуска MVC хранится в корне - index.php. Он запускает MVC. В роутере прописаны пути к моделям, контроллерам и пред5тавлениям. Факт в том, что 404- это тоже файл представления, который имеет свой контроллер. Eго он видит, а другие страницы при добавлении к ним ид, не видит.
    Если сделать в рерайтере вот так:
    Код (PHP):
    1. RewriteEngine On
    2. RewriteCond %{REQUEST_FILENAME} !-f
    3. RewriteCond %{REQUEST_FILENAME} !-d
    4. RewriteRule ^([0-9]) index.php?id=$1 [QSA,L]
    то, определяет файлы из корневой папки, и берет их, но надо то файлы представления брать, а не из корневого каталога.
     
  25. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    это похоже на отладочный лог рерайтера? по мне так это похоже на журнал ошибок веб-сервера. вывод: за прошедшие сутки ты так и не удосужился почитать мануал по рерайтеру. аутист?