webew
Войти » Регистрация
 
PHP
MySQL/MariaDB

Организация пространства адресов страниц веб-сайта средствами PHP и MySQL/MariaDB

31 июля 2014, 2:05

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

Настоящий подход опирается на два программных компонента: маршрутизатор и обработчик шаблонов. Они будут описаны в статье далее.

Виртуальное пространство адресов и централизация обработки запросов

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

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

Исключение составляют реально существующие физические файлы (например, изображения, и др.), которые серверу следует продолжать отдавать напрямую, не задействуя PHP.

Настройка Apache

Описанная задача решается с помощью модуля mod_rewrite. Один из способов — разместить в корневом каталоге веб-сервера файл .htaccess примерно следующего содержания1,2,3:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} \.php$
RewriteRule .* _showpage.php

Настройка nginx

Директивы для nginx выглядят следующим образом:

set $vertex /_showpage.php;
set $php_socket unix:/run/php/php5.6-fpm.sock;

location / {
    index $vertex;
    error_page 404 = @vertex;
    location ~ \.php$ {
        return 404;
    }
}

location @vertex {
    fastcgi_pass $php_socket;
    fastcgi_param SCRIPT_FILENAME $document_root$vertex;
    include fastcgi_params;
}

Маршрутизатор

Любой сайт есть совокупность страниц, имеющих адреса. Механизм сайта должен уметь анализировать приходящий HTTP-запрос и определять, к какой конкретно странице он относится.

Средство, позволяющее задать пространство адресов страниц и сопоставляющее адрес приходящего запроса этому пространству, называется маршрутизатором (или роутером).

В рамках настоящего подхода результатом работы маршрутизатора является HTTP-код ответа и данные для генерации HTML-кода страницы. Эти данные затем передаются обработчику шаблонов, который подставляет их в шаблон, формируя таким образом конечный HTML:

$mysqli = mysqli_connect( ... ); // можно также использовать mysql_connect

require_once 'router.php'; // подключаем код маршрутизатора

$router_cfg = array( ... );   // перечисляем настройки маршрутизатора (см. ниже)
$R = new Router($router_cfg); // создаем объект маршрутизатора

$R->analyzeURL(); // проводим анализ адреса; в результате объект
                  // содержит данные страницы - свойство pageData
                  // и путь к файлу с шаблоном - свойство template

require_once 'websun.php'; // подключаем код шаблонизатора

$HTML = websun_parse_template_path( // формируем HTML-код страницы
        $R->pageData, // данные страницы для подстановки
        $R->template  // путь к файлу с шаблоном
    );
                                           
echo $HTML;

Код маршрутизатора можно скачать одним файлом (требуется также библиотека для работы с MySQL), код шаблонизатора можно скачать здесь. Техника использования будет подробно описана ниже.

Организация хранения страниц

По большому счету, страница сайта — это HTML-код, имеющий адрес.

HTML-код страницы всегда имеет определенную структуру: каркас остается неизменным, а меняются лишь некоторые части. Обычно его можно описать следующим шаблоном:

<!DOCTYPE HTML>
<html>
<head>
    <title>{* заголовок *}</title>
    <meta name="description" content="{* описание для поисковых систем *}">
    <meta name="keywords" content="{* ключевые слова *}">
    <!-- далее может следовать подключение CSS и javascript-файлов и др. -->
</head>
<body>
    {* содержимое *}
</body>
</html>

С этой точки зрения страницу сайта можно считать некой сущностью, уникально идентифицируемой адресом, которая имеет заголовок и содержимое, а также ключевые слова и описание для поисковых систем. Такие сущности удобно хранить в виде записей (строк) в таблице базы данных, а универсальный шаблон для подстановки — в виде отдельного файла.

Рассмотрим конфигурацию маршрутизатора в самом простом случае:

$router_cfg = array(
        'table' => 'pages', // имя таблицы со страницами
        'template' => '$/templates/_page.tpl', // путь к файлу шаблона
    );                                        // ($ - корневой каталог веб-сервера)

Таблица pages должна иметь следующий минимальный набор колонок:

CREATE TABLE pages (
    url VARCHAR(255) NOT NULL,
    title TEXT,
    description TEXT,
    keywords TEXT,
    content MEDIUMTEXT,
    code TEXT,             -- назначение полей
    template VARCHAR(255), -- code, template и headers
    headers TEXT,          -- разъясняется далее
    UNIQUE KEY (url)
);

Шаблон страницы содержит метки для подстановки данных:

<!DOCTYPE HTML>
<html>
<head>
    <title>{* + >*title* *}</title>
    <meta name="description" content="{* + >*description* *}">
    <meta name="keywords" content="{* + >
*keywords* *}">
    <!-- далее может следовать подключение CSS и javascript-файлов и др. -->
</head>
<body>
    {* + >*content* *}
</body>
</html>

Более подробно языковые конструкции шаблона обсуждаются ниже.

Страницы со статическим адресом

Перейдем теперь непосредственно к технике создания страниц и рассмотрим самый простой случай — страницу со статическим адресом.

Для иллюстрации этого примера как нельзя лучше подходит главная страница, которая есть у любого сайта. Чтобы создать главную страницу, необходимо вставить в таблицу pages вот такую строку:

INSERT INTO pages SET
    url = '/',
    title = 'webew.ru — портал о веб-технологиях',
    description = 'Портал посвящен веб-технологиям.
                   Здесь можно задать вопросы или поделиться своими идеями'
,
    keywords = 'веб-технологии, php, mysql, html, css, javascript',
    content = '
                <h1>Вас приветствует webew.ru</h1>
               
                <h2>Последние статьи</h2>
                <ul>
                   ...
                </ul>
               
                <h2>Новые темы и комментарии</h2>
                <ul>
                   ...
                </ul>
               
                ...
               
                <footer>2014 &copy; webew.ru</footer>
              '
;

Кириллические (и другие нелатинские) символы в адресах страниц следует указывать без url-кодирования: /мы, а не /%D0%BC%D1%8B, и т.п.

GET-паметры не считаются частью адреса страницы. Другими словами, адреса /page.html, /page.html?a=1 и /page.html?b=2&c=3 с точки зрения маршрутизатора соответствуют одной и той же странице. (Это, однако, вовсе не означает, что GET-параметры нельзя использовать: с ними следует работать, назначив странице исполняемый PHP-код.)

Переменные в данных страницы. Назначение странице исполняемого кода.

Вообще говоря, title, description, keywords и content страниц сами по себе обрабатываются как полноценные шаблоны и могут содержать метки для подстановки переменных, наряду с прочими инструкциями. Например:

INSERT INTO pages SET
    url = '/',
    title = '{*SITENAME*} — портал о веб-технологиях',
    description = 'Портал посвящен веб-технологиям.
                   Здесь можно задать вопросы или поделиться своими идеями'
,
    keywords = 'веб-технологии, php, mysql, html, css, javascript',
    content = '
                <h1>Вас приветствует {*SITENAME*}</h1>
                <h2>Последние статьи</h2>
                <ul>
                    {* + $/mainpage/newarticles.tpl *}
                </ul>
                <h2>Новые темы и комментарии</h2>
                <ul>
                    {* + $/mainpage/newposts.tpl *}
                </ul>
                ...
                <footer>{*year*} &copy; {*SITENAME*}</footer>
              '
;

Инструкция вида {* + $/mainpage/newarticles.tpl *} предписывает вызвать вложенный шаблон, находящийся по адресу mainpage/newarticles.tpl относительно корневого каталога веб-сервера (сокращение "$")4. Также поддерживаются условия, циклы и многое другое5; подробнее эти возможности описаны в уже упоминавшейся выше статье про обработчик шаблонов.6

Теперь о том, как же задавать значения для подстановки.

Посмотрим еще раз, как выглядит вызов обработки шаблона:

$HTML = websun_parse_template_path(
        $R->pageData, // данные страницы для подстановки
        $R->template  // путь к шаблону
    );

Массивом для подстановки служит свойство pageData объекта маршрутизатора.

Каждой странице можно назначить исполняемый PHP-код. Этот код может выполнять совершенно любые действия (никакие ограничения не накладываются), но прежде всего он используется как раз для заполнения массива pageData.

Назначить исполняемый код можно несколькими способами.

Первый способ — записать в поле code страницы путь к некоторому PHP-файлу. Например:

INSERT INTO pages SET
    url = '/',
    ...
    code = '$/mainpage/get-data.php';

Этот файл будет подключен маршрутизатором с помощью require.7

Предположим, на главной странице нужно показать общее количество опубликованных статей и сообщений:

INSERT INTO pages SET
    url = '/',
    ...
    content = '<h1>...</h1>
               ...
               <p>Статьи: {*articles_total*}, сообщения: {*posts_total*}.</p>
               <footer>...</footer>
              '
;

Тогда содержимое mainpage/get-data.php будет примерно таким:

<?php

$arts = ...;  // тут некоторым образом получаем
$posts = ...; // общее количество статей и сообщений

// а теперь записываем полученную информацию в объект маршрутизатора
$this->pageData["articles_total"] = $arts;
$this->pageData["posts_total"] = $posts;

$this->pageData["SITENAME"] = "webew.ru"; // добавляем в массив также
$this->pageData["year"] = date('Y');        // элементы с ключами SITENAME и year

?>

Как видно из примера, обращение к объекту маршрутизатора осуществляется через ссылку $this8.

Следует отметить, что title, description, keywords и content страниц также содержатся в массиве pageData, но изменять эти элементы непосредственно в исполняемом коде не рекомендуется.

Глобальные переменные, при необходимости, делаются доступными с помощью инструкции global (аналогично тому, как это делается в функциях и классах).

Второй способ назначить странице исполняемый код — это записать его прямо в поле code, заключив в <?php ?>:

INSERT INTO pages SET
    url = '/',
    ...
    content = '<h1>...</h1>
               ...
               <p>Статьи: {*articles_total*}, сообщения: {*posts_total*}.</p>
               <footer>...</footer>
              '
,
    code = '<?php
           
            $arts = ...;
            $posts = ...;
           
            $this->pageData["articles_total"] = $arts;
            $this->pageData["posts_total"] = $posts;
           
            $this->pageData["SITENAME"] = "webew.ru";
            $this->pageData["year"] = date(Y);
           
            ?>'
;

Есть и третий способ. О нем будет рассказано в следующем разделе.

Страницы с динамическим адресом

Страница может обслуживать набор однородных сущностей.

Предположим, сообщения, публикуемые на сайте, имеют адрес вида /posts/(id сообщения).html. Тогда соответствующая запись в таблице будет выглядеть примерно так:9

INSERT INTO pages SET
    url = '/posts/(\d+).html',
    code = 'Posts->getData(1) [post]',
    title = '{*post.title*}',
    description = '{*post.snippet*}',
    keywords = '{*post.tags*}',
    content = '<h1>{*post.title*}</h1>
               <p class="date">{*post.date*}</p>
               <div class="text">{*post.text*}</div>
               ...
              '
;

Здесь в качестве url страницы указано Perl-совместимое регулярное выражение (PCRE).

Следует отметить, однако, что в данном случае по одному лишь виду пути запроса нельзя определить, что отдать в ответ — нужно еще как минимум убедиться в том, что имеется конкретная сущность (в данном случае сообщение), а также получить ее данные. Для этого нужно назначить странице исполняемый PHP-код.

Запись Posts->getData(1) [post], содержащаяся в code, реализует вышеупомянутый третий способ назначения странице исполняемого кода и в совокупности с url = '/posts/(\d+).html' означает буквально следующее: «проанализировать адрес запроса регулярным выраженем ^/posts/(\d+).html$10, в случае совпадения создать объект класса Posts и вызвать его метод getData, передав методу в качестве аргумента элемент массива вхождений с индексом 1 (то есть, строку, соответствующую первой паре скобок регулярного выражения); если результат работы getData не пуст — записать его в pageData['post'] объекта маршрутизатора».

Можно также использовать запись вида Posts->getData(1) [post] $/posts/single.php, которая, в дополнение к вышеперечисленному, предписывает в случае успеха подключить файл posts/single.php11.

Нулевой элемент массива вхождений всегда содержит полный путь запроса без ведущего слэша, поэтому при необходимости анализа полного пути можно обращаться к нулевому элементу: Posts->getData(0). Если индекс не указан — Posts->getData() — в качестве аргумента методу будет передан весь массив вхождений целиком.

Альтернативные шаблоны страниц

Отдельным страницам можно назначать альтернативные шаблоны для каркаса HTML-разметки.

Представим себе, что на всех страницах сайта, кроме главной, присутствует левая колонка, незименная от страницы к странице:

<!DOCTYPE HTML>
<head>...</head>
<body>
   
    <!-- header одинаковый у всех страниц без исключения,
         поэтому его вынесем в отдельный шаблон -->

    {* + $/templates/header.tpl *}
   
    <div id="left-column">
        <!-- левая колонка не обязательно статична по своему содержимому
             здесь вполне могут быть переменные, например: -->

        {*left_menu*}
    </div>
   
    <div id="center-column">
        <!-- а здесь собственно содержимое страницы -
             то, что в ячейке content таблицы в БД -->

        {* +> *content* *}
    </div>
   
    <!-- footer - аналогично header -->
    {* + $/templates/footer.tpl *}
   
</body>

В таком случае следует сделать для главной страницы отдельный шаблон, в котором левой колонки нет:

<!DOCTYPE HTML>
<head>...</head>
<body>
   
    {* + $/templates/header.tpl *}
   
    <!-- а тут левой колонки нет -->
   
    <div id="center-for-mainpage">
        {* +> *content* *}
    </div>
   
    {* + $/templates/footer.tpl *}
</body>

Сохраним этот шаблон, например, в файле mainpage/_page.tpl и укажем это в записи для главной страницы, заполнив поле template:

INSERT INTO pages SET
    url = '/',
    ...
    template = '$/mainpage/_page.tpl' ;

У остальных страниц поле template будет пустым, и это послужит инструкцией использовать для них общий шаблон, указанный при создании объекта маршрутизатора — $/templates/_page.tpl.

Постраничное подключение javascript- и css-файлов

Помимо общих файлов, которые можно перечислить в секции <head> прямо в шаблоне, для отдельных страниц могут потребоваться специальные файлы. Чтобы обеспечить их подключение, нужно выполнить два действия:

1. Заполнить для страницы поле headers, перечислив файлы через перевод строки. Например:

INSERT INTO pages SET
    url = '/',
    ...
    headers = '/mainpage/style.css
               http://code.jquery.com/jquery.min.js
               /mainpage/intro.js
               /mainpage/document-ready.js'
;

Пути к файлам будут вставлены в HTML-код страницы ровно в том виде, в котором они указаны.

При отсутствии расширения в адресе тип файла следует явно указать в начале:
js https://api-maps.yandex.ru/2.1/?load=package.full&lang=ru-RU

2. Отредактировать шаблон страниц, поместив внутрь тега <head> следующую конструкцию:

{%*headers.css*} <link rel="stylesheet" href="{*headers.css:*}" /> {*headers.css*%}
{%*headers.js*} <script src="{*headers.js:*}"></script> {*headers.js*%}

В результате шаблон примет приблизительно такой вид:

<!DOCTYPE HTML>
<html>
<head>
    <title>{* + >*title* *}</title>
    <meta name="description" content="{* + >*description* *}">
    <meta name="keywords" content="{* + >
*keywords* *}">
   
    <!-- тут можно без всяких условий подключить файлы, необходимые для всех страниц -->
    <link rel="stylesheet" href="/css/common.css" />
    <script src="/js/jquery.min.js"></script>
   
    <!-- а вот указание на постраничные файлы: -->
    {%*headers.css*} <link rel="stylesheet" href="{*headers.css:*}" /> {*headers.css*%}
    {%*headers.js*} <script src="{*headers.js:*}"></script> {*headers.js*%}
</head>
<body>
    ...
</body>
</html>

Разделение однородного пространства адресов

Встречаются случаи, когда разнородные сущности имеют одинаковые по виду адреса страниц.

Рассмотрим пример. Предположим, речь идет об интернет-магазине, где товары разбиты на категории, у каждой из которых должна быть своя страница с адресом вида /название категории. У каждого производителя товаров тоже должна быть своя страница с адресом вида /название производителя.

Оба этих случая описываются регулярным выражением /[^/]+12, которое не позволяет отличить один от другого. При этом составить более точные выражения, подходящие для каждого из этих случаев в отдельности, нельзя.13

В такой ситуации потребуется выполнить следующие действия.

Для начала нужно добавить в таблицу pages запись, соответсвующую такому адресу, при этом снабдив её специальными инструкциями:

INSERT INTO pages SET
    url = '/[^/]+',
    code = 'Categories->getData(1)    [cat]          category
            Manufacturers->getData(1) [manufacturer] manufacturer'
;

Формально эта запись является страницей, но фактически она представляет собой «развилку»14, от которой идут две «дорожки» — к категориям (category) и к производителям (manufacturer).

Разберем эти инструкции подробнее.

Вспомним инструкцию Posts->getData() [post] $/posts/single.php, которая предписывала проверить адрес и в случае успеха записать данные в pageData['post'], передав затем управление файлу posts/single.php.

Похожим образом действует и инструкция Categories->getData(1) [cat] category, однако в третьей ее части стоит не путь к PHP-файлу, а указатель на другую запись в таблице pages15,16, которой и будет передано управление. Этот указатель представляет собой значение поля url целевой записи.

Вот как примерно выглядит эта запись:

INSERT INTO pages SET
    url = 'category',
    title = '{*cat.title*}',
    description = '{*cat.description*}',
    keywords = '...',
    content = '<h1>{*cat.title*}</h1>
                    ...
              '
,
    code = '(здесь можно пользоваться $this->pageData[cat])';

Это обычная страница17, которой уже доступны данные категории в pageData['cat']. Они используются в полях страницы в виде переменных {*cat.ключ*} и, при необходимости, могут быть задействованы в назначенном ей PHP-коде.

Если проверка адреса с помощью Categories->getData() потерпела неудачу, маршрутизатор немедленно переходит к следующей инструкции — Manufacturers->getData(1) [manufacturer]  manufacturer (которой соответствует страница с url = 'manufacturer') и так далее до тех пор, пока проверка адреса не завершится успешно или не закончатся инструкции. В последнем случае код HTTP-ответа будет установлен маршрутизатором в 404.

Выделение подпространства адресов

Бывает, что адреса некоторой группы страниц попадают в другую, более широкую, группу.

Допустим, имеется интернет-магазин, в котором страницы товаров имеют адреса вида /производитель/модель.html, а страницы точек розничной продажи — /shops/(id точки).html. Первые при этом описываются регулярным выражением /[^/]+/[^/]+\.html, а вторые — /shops/\d+\.html. Тогда адрес страницы конкретной розничной точки, например /shops/1.html, совпадет с обоими выражениями.

В таком случае маршрутизатору нужно сообщить, что более строгое выражение должно обрабатываться первым. Для этого его нужно предварить числом. Например:
10 /shops/\d+\.html. Это число маршрутизатор рассматривает как приоритет, обрабатывая первыми страницы с б́ольшим приоритетом.18

Аналогичного эффекта можно достичь, если менее строгому выражению указать отрицательный приоритет — -10 /[^/]+/[^/]+, а более строгое оставить без изменений.

Ошибка 404

Маршрутизатор считает, что запрошенная страница не существует на сайте, в следующих случаях:

  • не обнаружена запись в таблице pages
  • проверка всех инструкций Класс->метод() [ключ] указатель закончилась неудачей

В такой ситуации маршрутизатор установит HTTP-код ответа в 404.

Можно создать специальную страницу, которую маршрутизатор автоматически будет отдавать в таких случаях19. Её url должен быть равным '404':

INSERT INTO pages SET
    url = '404',
    title = 'Ошибка 404 - страница не найдена.',
    content = '<h1>Ошибка: страница не найдена</h1>
               <p>Страницы с адресом {*$_SERVER.REQUEST_URI*} на сайте нет.</p>
               <!-- в шаблонах можно использовать суперглобальные переменные -->
              '
,
   code = '(и в этом случае тоже можно назначать исполняемый код)';

Об адресах для AJAX-запросов

Ответы на AJAX-запросы не являются полноценными страницами сайта, поэтому включать их в общее виртуальное пространство адресов под управлением маршрутизатора не рекомендуется.

Следует принять соглашение, по которому адреса таких запросов содержат некоторый фрагмент (например, "ajax"), дополнив соответствующим образом настройки веб-серверов.

Apache

Нужная директива записывается так: RewriteCond %{REQUEST_URI} !ajax. Весь набор директив примет вид20:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} \.php$
RewriteCond %{REQUEST_URI} !ajax
RewriteRule .* _showpage.php

nginx

Директиву location для *.php потребуется дополнить, и она примет вот такой вид:

location ~ \.php$ {
    if ($uri !~ ajax) {
        return 404;
    }
    fastcgi_pass $php_socket;
    fastcgi_param SCRIPT_FILENAME $document_root$uri;
    include fastcgi_params;
}

1. Подробнее об использовании mod_rewrite и .htaccess можно прочитать в этой немного устаревшей статье.

2. Директива RewriteCond %{REQUEST_FILENAME} \.php$ воспрепятствует исполнению файлов *.php в ответ на прямой запрос через веб-сервер.

3. Менее строгим, но и менее ресурсоемким (засчет отсутствия проверки существования физического файла) является явное перечисление фрагментов имен файлов (обычно расширений), встречая которые, веб-серверу не следует задействовать PHP:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !\.(css|js|png|jpg|gif)$
RewriteRule .* _showpage.php

4. При желании можно поместить содержимое страницы во вложенный шаблон полностью. Например:

INSERT INTO pages SET
    url = '/',
    ...
    content = '{* + $/mainpage/content.tpl *}';

5. В том числе инструкция вида {* + >*имя* *}, предписывающая не просто подставить значение переменной, но еще и обработать само это значение как шаблона: искать в содержимом переменной ссылки на другие переменные, а также все остальные синтаксические выражения обычных шаблонов. Именно использование таких инструкций ({* + >*title* *}, {* + >*content* *} и т.п.) в общих шаблонах для страниц обеспечивает динамическую обработку полей title, description, keywords и content.

6. Вообще говоря, в связке с маршрутизатором может быть использован любой схожий по возможностям с websun обработчик шаблонов. Websun является вариантом, к использованию рекомендуемым, но не обязательным. Никаких специальных взаимных требований друг к другу маршрутизатор и обработчик не имеют.

7. Сокращение "$", как и в случае путей к шаблонам, обозначает корневой каталог веб-сервера.

8. Технически файл подключается внутри одного из методов маршрутизатора, поэтому код файла выполняется в контексте объекта.

9. Нотация с точкой соответствует в языке шаблонизатора следующему уровню вложенности массива: {*post.title*}pageData['post']['title'], {*post.date*}pageData['post']['date'] и т.п.

10. Механизм маршрутизатора автоматически добавляет символы начала и конца строки перед анализом пути, т.е. запись /posts/(\d+).html на самом деле приведет к сопоставлению с выражением ^/posts/(\d+).html$. Поэтому ошибочное совпадение с частью пути запроса (например, /something/posts/13.html или /posts/13.html/something) исключено.
Сопоставление проводится в режиме регистронезависимости (флаг i).

11. Запись Posts->getData(1) [post] $/posts/single.php в code страницы равносильна следующей:

<?php

// Код будет выполняться только в случае успешного сопоставления
// пути запроса регулярному выражению; при этом маршрутизатор  
// записывает массив с результатами этого сопоставления в свойство matches.

$Obj = new Posts;
$data = $Obj->getData($this->matches[1]);
if ($data) {
    http_response_code(200);
    $this->pageData['post'] = $data;
    require_once "$_SERVER[DOCUMENT_ROOT]/posts/single.php";
    // а точнее - $this->requireFile('$/posts/single.php');
}
else
    http_response_code(404);

?>
Аналог для Posts->getData(1) [post], очевидно, выглядит так же, за исключением отсутствия require файла.

12. Круглые скобки нужны в данном случае лишь для того, чтобы дать маршрутизатору указание рассматривать адрес этой страницы как динамический и использовать его в качестве регулярного выражения, а не для простой проверки на равенство (как это делается для страниц со статическим адресом).

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

14. Именно поэтому у неё не указаны никакие поля, кроме url и code.

15. Если третья часть инструкции заканчивается фрагментом .php, она считается путем к PHP-файлу, в противном случае — указателем на страницу.

16. В случае, если указатель ссылается на несуществующую запись, маршрутизатор будет считать, что страница с запрошенным адресом не существует. Подробнее см. соответствующий раздел статьи.

17. Нужно сказать, однако, что доступ к этой странице напрямую невозможен в принципе: любой адрес начинается со слэша, а здесь в поле url ведущего слэша нет. Потому такая страница может быть задействована только через описанное указание-«развилку».

18. Число-приоритет должно быть целым. Его можно отделять от регулярного выражения пробелом — для удобочитаемости.

19. Если специальную страницу не заводить, то маршрутизатор все равно будет отдавать код 404, но пользователь увидит либо пустой экран, либо результат замены меток для подстановки данных в основном шаблоне на пустые строки.

20. Или

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !\.(css|js|png|jpg|gif)$
RewriteCond %{REQUEST_URI} !ajax
RewriteRule .* _showpage.php
для менее ресурсоемкой конфигурации, упоминавшейся ранее.


© Все права на данную статью принадлежат порталу webew.ru. Перепечатка в интернет-изданиях разрешается только с указанием автора и прямой ссылки на оригинальную статью. Перепечатка в печатных изданиях допускается только с разрешения редакции.
Добавить комментарий
Отображение комментариев: Древовидное | Плоское

1234ru

В версии 1.0.1 исправлен небольшая неточность обработки третьего случая исполняемого кода.
То, что не убивает нас, делает нас инвалидами.
08.05.2015, 14:22
Ответить

1234ru

В версии 1.1.1 добавлена возможность выделять подпространства адресов с помощью установки приоритетов.
То, что не убивает нас, делает нас инвалидами.
15.05.2015, 23:38
Ответить

1234ru

В версии 1.1.3 добавлена возможность явно задавать тип подключаемого в заголовке файла, указав его в начале строки. Например:
js https://api-maps.yandex.ru/2.1/?load=package.full&lang=ru-RU
То, что не убивает нас, делает нас инвалидами.
24.11.2015, 02:45
Ответить

1234ru

В версии 1.1.4 исправлен недочет, связанный с проверкой адресов, имеющих пробелы в конце.
То, что не убивает нас, делает нас инвалидами.
10.12.2015, 13:17
Ответить

1234ru

В статью добавлен пример конфигурации nginx.
То, что не убивает нас, делает нас инвалидами.
14.06.2017, 12:54
Ответить
Добавить комментарий
Отображение комментариев: Древовидное | Плоское
© 2008—2017 webew.ru, связаться: x собака webew.ru
Сайт использует Flede и соответствует стандартам WAI-WCAG 1.0 на уровне A.
Rambler's Top100

Реклама: