За последние 24 часа нас посетили 19225 программистов и 1643 робота. Сейчас ищут 930 программистов ...

ЧПУ

Тема в разделе "PHP для профи", создана пользователем gritts80, 12 сен 2017.

  1. gritts80

    gritts80 Новичок

    С нами с:
    12 сен 2017
    Сообщения:
    8
    Симпатии:
    0
    Подскажите, может кто знает?
    Как сделано в известных соц.сетях, когда вводишь адрес:

    vn.com/vasya

    на самом деле отрабатывает

    vn.com/profile.php?id=vasya

    А если вручную ввести второй адрес, то отобразится все равно первый!

    Как они это делают?
     
  2. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    ну через рерайтер например. хотя можно просто в парсинг урла поиграть.
     
  3. gritts80

    gritts80 Новичок

    С нами с:
    12 сен 2017
    Сообщения:
    8
    Симпатии:
    0
    Создал в корне сайта файл profile.php.
    При обращении к нему по полному пути (вида vn.com/profile.php?id=vasya) все хорошо.

    Вставил в .htaccess код:

    Код
    RewriteEngine On
    RewriteRule ^([^/]*)$ /profile.php?id=$1 [L]

    Стала выходить ошибка 500 Internal Server Error.

    Что-то я запутался...
     
  4. gritts80

    gritts80 Новичок

    С нами с:
    12 сен 2017
    Сообщения:
    8
    Симпатии:
    0
    Конечно это пример, скрипт и путь может быть любой. Но у них явно нет папки на сервере под каждого пользователя.
     
  5. gritts80

    gritts80 Новичок

    С нами с:
    12 сен 2017
    Сообщения:
    8
    Симпатии:
    0
    miketomlin, а где вклинить свой код роутинга? и не просто ведь нужен редирект, а полноценная подмена адреса в строке.

    Если вводят:
    vn.com/vasya
    vn.com/profile.php?id=vasya

    Всегда должен отрабатывать скрипт vn.com/profile.php?id=vasya
    А отображаться адрес должен только vn.com/vasya
     
  6. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.861
    Симпатии:
    657
    @gritts80, а кто вам сказал, что на самом деле отрабатывает vn.com/profile.php?id=vasya ? Вы что ли нашли такой дубль или хакнули сайт?
    --- Добавлено ---
    P.S. Возможности Web-сервера для рерайта лучше использовать по минимуму. Обычно все запросы (быть может кроме статика, если конечно он не на отдельном хосте висит) направляются в один фронт, в котором парсится урл, как выше сказал Ganzal.
    --- Добавлено ---
    Парсинг может выполняться непосредственно по одной предопределенной маске, либо путем последовательного обхода списка роутов (масок), отсортированного по приоритету (роуты могут конфликтовать друг с другом; если срабатывает более приоритетный роут, менее приоритетрый уже не обрабатывается).
    --- Добавлено ---
    Зацикливание?
    --- Добавлено ---
    Либо слеш уберите в подстановке, либо добавьте условие, препятствующее зацикливанию.
    --- Добавлено ---
    Например:
    Код (Text):
    1. RewriteCond %{REQUEST_FILENAME} !-f
    Гляньте эту мою статью и этот мой коммент к ней.
     
  7. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.819
    Симпатии:
    1.333
    Адрес:
    Лень
    вк ищет паге зарегистрированных страниц, и если не находит, он начнет выяснять условиями, а не юзер ли это а не хрень какая нибудь ?
     
  8. gritts80

    gritts80 Новичок

    С нами с:
    12 сен 2017
    Сообщения:
    8
    Симпатии:
    0
    miketomlin, читаю вашу статью...
     
  9. gritts80

    gritts80 Новичок

    С нами с:
    12 сен 2017
    Сообщения:
    8
    Симпатии:
    0
    miketomlin,
    огромное вам спасибо за статью, я понял, что можно организовать единую точку входа в index.php, частично уже сделал!
    Получилось отловить, когда введен адрес "vn.com/vasya".

    Единственный к вам вопрос, как внутри index.php сделать вызов profile.php?id=vasya ?
    Так чтобы не было перехода.
    При использовании "header('Location: http..." делается переход, меняется адрес в адресной строке браузера.
     
  10. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    фантазию включить....
     
  11. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.819
    Симпатии:
    1.333
    Адрес:
    Лень
    надо чтобы выглядело так:
    vn.com/vasya
    чтобы потом код понимал вот так:
    profile.php?id=vasya
    в итоге получили бы переменную с значением уася.

    зашкварно..

    PHP:
    1. trim ( parse_url ( $_SERVER['REQUEST_URI'], PHP_URL_PATH ), ' /' )
    explode
    first array value... [0]
     
  12. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Ну раз пошла такая пьянка, на Nginx парсим URL, передавая PHP-машине запрос уже в нормальном виде с гетами.
     
  13. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.861
    Симпатии:
    657
    @gritts80, выше уже сказали, что нужно фантазию включить, и даже пример накидали.
    Зачем вам внутри index.php делать вызов profile.php?id=vasya ? Можете, например, внутри фронта подключить profile.php и передать туда в переменной $id первый компонент пути (vasya). Если вы про редирект в коде из статьи, то он для другого нужен.
     
  14. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    А можно вообще забить на ЧПУ, потому что это дичь, придуманная СЕОшниками, верящими в мифы и предания, которые они сами же придумывать горазды.

    Это такой вот лайвхак - если не создавать себе проблемы, не придется их решать.
     
  15. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    геты не нужны
    и вы это знаете

    есть $_SERVER['REQUEST_URI'] и parse_url()
     
  16. gruth

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

    С нами с:
    13 май 2017
    Сообщения:
    224
    Симпатии:
    18
    Что бы один раз подключить все необходимые либы, а не делать одно и то же в разных файлах.
     
  17. gritts80

    gritts80 Новичок

    С нами с:
    12 сен 2017
    Сообщения:
    8
    Симпатии:
    0
    Задача решена. Спасибо всем откликнувшимся.
    Очень помогла статья http://gency.ru/single-entry-point

    Решил таким способом:
    Вклинился в корневой файл index.php, вставил вызов функции (при true сразу выхожу из index.php):

    Код (Text):
    1.  
    2. function checkUserAccount()
    3. {
    4.     $p=strtolower(preg_replace('#//+#','/',$_SERVER['REQUEST_URI']));
    5.     if (strlen($_SERVER['QUERY_STRING'])) $p=substr($p,0,-(strlen($_SERVER['QUERY_STRING'])+1));
    6.     if (count($pa=explode('/',$px=trim($p,'/'),2))<2) $pa[]='';
    7.     if ((count($pa) >= 1) and ($pa[0] является аккаунтом))
    8.     {
    9.         $_GET['id'] = $pa[0];
    10.         include './profile/index.php';
    11.         return true;
    12.     }
    13.     return false;
    14. }
     
  18. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.861
    Симпатии:
    657
    @gritts80, что-то присваивать элементам $_GET как-то не очень. Что мешает использовать $id, как я выше писал?

    Как минимум один элемент в массиве будет уже после explode (при обращении к главной в нем будет пустая строка), а после if (count($pa=... всегда будет ровно два (второй может содержать пустую строку).
    --- Добавлено ---
    if (strlen(... $p=... можно сделать попроще, например:
    Код (Text):
    1. list($p)=explode('?',$_SERVER['REQUEST_URI'],2);
    В оригинале преследовался тайный умысел, что для вас походу не актуально.

    Еще ф-цию parse_url гляньте.
     
  19. gritts80

    gritts80 Новичок

    С нами с:
    12 сен 2017
    Сообщения:
    8
    Симпатии:
    0
    @miketomlin
    вам спасибо огромное, только благодаря вам вообще смог решить эту задачу. столько дней уже бился над ней.
    как здесь вам плюс поставить?
    сейчас буду код улучшать ))