Протокол http и работа с заголовками
Содержание:
- Настройка перенаправлений
- Заголовки Last-Modified и Content-Length
- MAMP Server
- Простой роутинг
- Проксирование
- Пояснения:
- Получение URL в PHP без GET-параметров
- Настраиваем отображение сайта
- Заголовки для кеширования
- Изменение кода статуса ответа и комментария статуса
- WAMP Server
- Получение ссылки текущей страницы в PHP
- С HTTP на HTTPS (другой порт)
- PHP $_SERVER
- Структура URL адресов в админке
- Пример двойного редиректа
- Latest Magento Tips, Guides, & News
- PHP
- Синтаксис .htaccess
- Оптимизируем работу сайта
- Why using PHP Server Stacks?
- Установка MySQL
Настройка перенаправлений
Настройки необходимо вносить в файлах конфигураций виртуальных доменов. В Linux на основе RPM (CentOS, Red Hat), как правило, они расположены в директории /etc/nginx/conf.d/. В Linux на основе Deb (Ubuntu, Debian) — в директории /etc/nginx/sites-enabled/. Во FreeBSD все в одном файле — /usr/local/etc/nginx/nginx.conf.
Саму настройку на перенаправление в NGINX можно прописать несколькими способами.
1. Первый:
rewrite ^ https://$host$request_uri? <флаг>;
* $host — имя хоста из запроса, если отсутствует — имя в поле «Host» заголовка, если тоже отсутствует — имя сервера; $request_uri — первоначальный запрос с аргументами (все, что идет после доменного имени).
** где флаги могут быть следующие:
- permanent — перенаправление с кодом 301.
- redirect — перенаправить с кодом 302.
- last — закончить обработку с переходом в новый location.
- break — закончить обработку и остаться в текущем location.
2. Второй:
return <код> https://$host$request_uri;
* где коды могут использоваться любые, но чаще всего — 301, 302, 404.
Есть различные мнения, какой из методов лучше и безопаснее, поэтому каким воспользоваться — решать по ситуации. В данных примерах используются оба варианта.
После внесения изменений, необходимо проверить их корректность:
nginx -t
И для их применения перезапустить веб-сервер:
systemctl restart nginx
service nginx restart
* в первом примере перезапуск выполняется на новых системах Linux. Второй пример — на устаревших или FreeBSD.
Проверяя редиректы в браузере, следует учесть, что настройки могут кэшироваться. Для обновления кэша используйте комбинацию Ctrl + F5. Если и это не помогает, закрывайте вкладку и открывайте новую.
Заголовки Last-Modified и Content-Length
Заголовки Last-Modified и Content-Length сообщаю когда документ был изменён последний раз и его размер. Поисковые роботы и браузеры отправляют в запросе заголовок If-Modified-Since, на который веб-сервер
может либо выдать новую страницу либо 304 Not Modified.
Для статических файлов эти параметры определяются легко.
Content-Type: image/png Content-Length: 5922 Last-Modified: Mon, 27 Jan 2020 10:48:16 GMT
Сложнее с динамическими файлами, например с php. ETag взаимосвязан с датой последней модификации и размером содержимого
Поэтому всё же определять эти значения придётся.
Во всех инструкциях по настройке кеширования сайта, которые нам удалось прочитать, этому вопросу не уделялось внимание. Предполагалось, что дата последней модификации известна.
Однако это не так
И это очень непростой вопрос.
Проблема в том, что дата последней моификации файла зависит от всех подключаемых php-файлов, от данных в базе данных, от заголовков запроса браузера, кук, IP-адреса посетителя,
курсов валют, времени, сторонних сервисов.
Для php можно использовать следующий код, который выдаст дату последней модификации всех подключаемых файлов:
Может изменяться сам код php-файла, а данные и html-код которые он выдаёт могут не измениться. В этом случае неправильно говорить, что Last-Modified изменился.
Но для простоты можно считать, что любое изменение файла ведёт к изменению Last-Modified.
Для данных мы должны ориентироваться на дату изменения данных в строке таблицы. Эта задача может быть нетривиальной для страниц, где отображается множество данных из разных таблиц.
Но если страница отображает одну сущность, например, конкретную новость, статью, счёт, платёж, то там дата последней модификации известна. Для страниц,
где собирается множество данных из разных таблиц нужно иметь таблицу в которой lastmodified соответствующей строки будет обновляться триггером.
Можно ориентироваться на хеш от выдаваемых данных. Если хеш md5 изменился, то меняем Last-Modified. Эту задачу лучше всего поручить проксирующему серверу Nginx.
Для проверки ответов веб-сервер вы можете испоьзовать следующие команды:
- curl -I —header ‘If-Modified-Since: Mon, 30 Apr 2029 18:13:12 GMT’ https://itsoft.ru
- curl -I —header ‘If-None-Match: «a49f2da878be351c6c73a1ec0524d8ea»‘ https://itsoft.ru
- curl -I —header ‘Accept-Encoding: gzip’ https://itsoft.ru
MAMP Server
MAMP Server creates a local server environment, especially for the Mac OS.
The pack includes Apache Web Server, MySQL, and PHP. In one click, the MAMP package installs tools required to create a PHP local server on Mac.
MAMP provides an excellent platform for developers to test and host their applications. The best part of MAMP is that it is not limited to the mentioned tools.
It also offers the convenience of using Nginx instead of Apache or using MariaDB instead of MySQL. There are also alternatives of PHP, such as Pearl, or Ruby that comes with MAMP.
MAMP does have a Pro version too. It has more advanced functionality.
Простой роутинг
Если единая точка входа настроена правильно, то при заходе по любому несуществующему URL-адресу, например /test должен запуститься файл index.php.
URL текущей страницы находится в переменной $_SERVER
Теперь мы можем написать очень простой роутер, который смотрит на текущий URL и подключает соответствующий скрипт:
Внесём ещё пару доработок. Во-первых, зачастую URL-адреса должны работать вне зависимости от наличия GET-параметров, поэтому вырежем их из URI:
Кроме этого, часто требуется получить доступ к определённой части URL. Для этого разобьём URL на части по слешу:
В переменной $segments для URL /products/15 будет лежать массив вида .
Теперь мы можем легко добавить маршруты для админки:
Это самый простой вариант роутинга. Не идеальный, конечно, но и не требующий знания регулярных выражений (хотя никто не мешает их использовать) и подключения сторонних библиотек.
При хранении URL адресов в базе данных роутинг будет выглядеть примерно так (реальный код зависит от библиотеки, которую вы используете для взаимодействия с БД):
Проксирование
Проксирование, в отличие от редиректа, не передает инструкции браузеру перейти на другой url — NGINX сам выполняет http-запрос по другому адресу и возвращает готовый ответ. Эта возможность может применяться для внутреннего распределения серверных ресурсов.
Хоть это и не совсем редирект, рассмотрим примеры его настройки, так как очень часто нужно не перенаправление, а, как раз, обратное проксирование.
1. На другой сервер
Пример внутреннего перенаправления http-запроса на другой веб-сервер:
…
location / {
proxy_pass $scheme://192.168.0.15:8080/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
* в данном случае, принимать запросы от браузера и отвечать на них будет NGINX, а сама обработка будет выполняться на сервере с IP-адресом 192.168.0.15 на порту 8080.
Использование NGINX в качестве http-прокси:
server {
…
server_name site1.ru www.site1.ru;
location / {
proxy_pass http://192.168.1.21/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
…
server_name site2.ru www.site2.ru;
location / {
proxy_pass http://192.168.1.22/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
* в данном примере запросы на site1.ru будут перекинуты на сервер 192.168.1.21, а запросы на site2.ru — 192.168.1.22.
HTTP proxy с авторизацией (если удаленный веб-сервер требует аутентификации):
server {
…
location / {
proxy_pass http://10.10.10.10/page/;
proxy_set_header Authorization «Basic dGVzdDp0ZXN0»;
…
}
}
* где 10.10.10.10/page — страница, на которую будут перекинуты запросы; dGVzdDp0ZXN0 — логин:пароль test:test, закодированные в формате base64.
2. Часть url на другой сервер
Выше мы рассмотрели пример перенаправления запроса по части веб-адреса. По схожему сценарию мы можем делать проксирование:
server {
…
location ~ ^/page1/(.*)$ {
proxy_pass $scheme://10.10.10.10/$1;
}
}
* и так, в данном примере при обращении по адресу site.ru/page1/<что-то еще>, nginx сделает внутренний запрос на сервер 10.10.10.10 по адресу 10.10.10.10/<что-то еще> и вернет готовый ответ.
3. На другой сайт
Мы можем сделать так, что при переходе по одному адресу у нас будет открываться совершенно другой сайт:
server {
…
location / {
proxy_pass https://www.dmosk.ru;
proxy_set_header Host www.dmosk.ru;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
* в данном случае мы при обращении к нашему серверу будем попадать на сайт https://www.dmosk.ru
Обратите внимание, что в proxy_set_header мы передаем хосту его имя — в противном случае, как правило, другой сервер вернет ошибку. Также мы не указываем proxy_redirect, иначе, nginx будет переводить запросы на реальный сайт (отправлять инструкции браузеру перейти на него), а не тот, что мы используем за http-прокси
4. Редиректы при проксировании
Если при проксировании хост возвращает инструкцию браузеру для выполнения редиректа, обозреватель может сменить адрес сайта. Это особенно не удобно, когда проксирование мы выполняем на другой сайт. Чтобы отловить редиректы и заменить их своими значениями, мы должны воспользоваться опцией proxy_redirect. Рассмотрим ее применение для предыдущего примера, когда мы проксировали запрос на сайт www.dmosk.ru:
server {
listen 80;
server_name dmosk.local www.dmosk.local;
location / {
proxy_pass https://www.dmosk.ru;
proxy_set_header Host www.dmosk.ru;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect https://www.dmosk.ru/url1 http://dmosk.local/url2;
proxy_redirect https://www.dmosk.ru/ http://dmosk.local/;
}
}
* в конкретном случае мы проксируем запросы http://dmosk.local на сайт www.dmosk.ru, но если он вернет инструкцию для редиректа https://www.dmosk.ru/url1, в браузере он должен быть заменен на http://dmosk.local/url2. А также любое перенаправление для https://www.dmosk.ru/ будет заменено на http://dmosk.local/.
Пояснения:
Условие RewriteCond обозначает совпадение с которым будет выполнено правило RewriteRule. При этом, используются символы:. – Точка — это любой символ (но только один!).^ — Эта метка означает начала строки.$ — Эта метка означает конец строки.\ — Эта экранирующий слэш, позволяет считать следующий за ним символ, обычным символом.() – Этот символ обозначает группировку.! – Метка отрицания.+ — Этот символ повторяется от 1 до 65536 раз.? — Этот символ повторяется 0 или 1 раз.* — А этот символ повторяется от 0 до 65536 раз.Флаги определяют дополнительные опции.R — (redirect) — По умолчанию останавливает процесс преобразования, возвращает результат в браузер клиента, как редирект на данную страницу 302, MOVED TEMPORARY. Например флагу можно указать другой код результата, R=301 и он возвратит редирект клиенту с кодом 301 MOVED PERMANENTLY.NC — (nocase) — Этот флаг отключает проверку регистра символов.L — (last) — Флаг останавливает процесс преобразования, текущая ссылка считается окончательной.
Чтобы изменения вступили в силу — не забудьде произвести рестарт nginx. Но для начала — проверьте, что ваша конфигурация в порядке. Для этого выполните команду:
Если выдаст «OK» — делаем смело перезагрузку:
или
Первый вариант — для устаревших систем Linux или FreeBSD. Второй — для новых систем Linux
Если же показывает ошибку — разбираемся с ней.
Проверяя редиректы в браузере, следует учесть, что настройки могут кэшироваться. Для обновления кэша используйте комбинацию Ctrl + F5. Если и это не помогает, закрывайте вкладку и открывайте новую.
Получение URL в PHP без GET-параметров
Иногда эти параметры, передаваемые в качестве части ссылки, нас не интересуют, то есть требуется получить адрес без них. Мы говорим о следующих параметрах: name=anna&city=Valencia.
В действительности их можно отсечь, используя функцию explode в PHP, разбивающую строку по разделителю. Не стоит объяснять, что ссылка представляет собой строку, а параметры GET начинают прописываться после «?». В результате вопросительный знак и станет разделителем, а функция explode сделает из строки массив с 2-мя элементами. Первый элемент станет содержать искомую ссылку без GET-параметров, так как эти самые параметры останутся во втором элементе.
Код на PHP с использованием переменной $_SERVER будет выглядеть так:
Ну и результат:
Настраиваем отображение сайта
Посмотрим, что можно сделать с отображением всего ресурса или его разделов в браузерах пользователей при помощи .htaccess.
10. Заменяем индексный файл
Индексный файл — тот, что открывается по умолчанию при обращении к определенному каталогу. Обычно они называются: index.html, index.htm, index.php, index.phtml, index.shtml, default.htm, default.html.
Вот как это выглядит в структуре каталога:
Чтобы заменить этот файл на любой другой, размещаете в каталоге .htaccess и добавляете эту команду:
Вместо «hello.html» вписывайте адрес желаемого файла.
Можно задать последовательность файлов, которые будут открываться в указанном порядке, если один из них будет недоступен:
11. Добавляем или убираем html в конце URL
Сохранять или убирать расширение файлов в URL — дело вкуса каждого оптимизатора. Достоверных исследований влияния расширений в адресах на ранжирование ресурса нет, но каждый вебмастер имеет свое мнение по этому поводу.
Чтобы убрать .html:
Этими же директивами можно добавить/убрать расширение php.
12. Настраиваем кодировку
Чтобы избежать ошибок в отображении ресурса браузером, нужно сообщить ему, в какой кодировке создан сайт. Самые популярные:
- UTF-8 — универсальная
- Windows-1251 — кириллица
- Windows-1250 — для Центральной Европы
- Windows-1252 — для Западной Европы
- KOI8-R — кириллица (КОИ8-Р)
Чаще всего используют UTF-8 и Windows-1251.
Если кодировка не указана в метатеге каждой страницы, можно задать ее через .htaccess.
Пример директивы, которая задает для файла кодировку UTF-8:
А такая команда означает, что все загружаемые на сервер файлы будут преобразованы в Windows-1251:
В примерах приведены разные кодировки, но в рамках одного сайта кодировки в этих директивах должны совпадать.
13. Создаем кастомные страницы ошибок
При помощи правил в .htaccess можно настроить отображение специально созданных страниц для самых популярных ошибок, например:
Перед тем, как прописывать директивы, создайте в корне сайта папку error и разместите туда соответствующие файлы для страниц ошибок.
Зачем это нужно? Например, чтобы не потерять пользователя на странице 404, а дать ему возможность перейти в другие разделы сайта:
Заголовки для кеширования
Когда веб-сервер отдаёт какой-нибудь файл: картинку, css, js или контент страницы, то он должен сказать сколько можно хранить эти данные в кеше.
Картинки можно хранить там вечно, они никогда не изменяются. Многие любят выдавать запрет на кеширование в виде заголовков:
Cache-Control: no-cache,no-store,max-age=0,must-revalidate Expires: -1 Expires: Thu, 19 Nov 1981 08:52:00 GMT Pragma: no-cache
На самом деле, смысла в этом никакого нет для большинства данных, только нагрузка на сервер. И не надо бояться сказать, что файл или страницу сайта можно закешировать.
Во-первых, потому что браузер при следующем обращении к этому контенту при условии, что время хранения кеша просрочено спросит: «а не изменился ли ресурс с момента последнего моего запроса».
И если не изменился, то веб-сервер должен вернуть заголовок 304 Not Modified и не отправлять запрашиваемый файл.
Во-вторых, пользователь всегда может нажать обновить страницу и принудительно послать запрос к серверу не уточняя изменился ресурс или нет.
Важно только правильно определить время хранения кеша. В решение этого вопроса можно исходить из того как часто обновляются данные и насколько это важные данные.
Что случится, если посетитель увидит обновление с опозданием
Какое это разумное опоздание? Подавляющее большинство страниц в интернете чаще умирает, чем обновляется.
Обновляются ленты новостей, а страница с конкретной новостью живёт вечно. Поэтому для подобных страниц можно смело выставить время жизни веша сутки или неделю, т.е. то
разумное время в которое посетитель может вернуться на эту страницу или ваш сайт.
Итак, давайте рассмотрим как браузер спросит не изменился ли запрашиваемый ресурс. Для этого есть два варианта.
Первый — отправить в запросе If-Modified-Since с датой предыдущего запроса.
Второй — отправить в запросе If-None-Match с меткой ETag, которую он получил при предыдущем обращении.
При ответе веб-серве посылает следующие заголовки:
ETag: "1722-59d1cd83fc41f" Cache-Control: max-age=31536000, public
ETag — является уникальной меткой, а Cache-Control сообщает можно ли хранить кеш на промежуточных прокси-сервера и сколько его можно хранить.
В .htaccess укажите:
Header set Cache-Control "max-age=31536000, public"
В заголовой php-скрипта добавьте следующий код если он не обращается к базе и не зависит от других сервисов.
Изменение кода статуса ответа и комментария статуса
В примерах выше статусом ответа был 200, и комментарий «OK».
Мы можем указать абсолютно любой статус ответа в диапазоне 100-599. Если указать статус 5xx, то веб-браузеры, поисковые системы и все остальные будут думать, что на сервере возникла ошибка — хотя на самом деле, никакой ошибки нет и наше сообщение успешно доставлено и успешно получен ответ.
Для демонстрации попробуем следующий код в нашем файле headers.php:
<?php header("HTTP/1.1 599 Damn, dude, you broke everything!"); $headers = apache_request_headers(); if (isset($headers)) { header ('HackWare: I got your message: ' . $headers); }
Откроем эту страницу в веб-браузере: http://localhost/headers.php
Как будто бы всё сломано и на сервере проблемы.
Но посмотрим в командной строке:
curl -v -H 'Hackware: Hello! How are you?' localhost/headers.php
Как можно увидеть, наше сообщение доставлено и процитировано в ответе.
Строка со статусом ответа включает три элемента:
- номер HTTP версии (например, HTTP/1.1)
- номер статуса ответа (любые цифры от 100 до 599 — если использовать другие цифры, то можно получить «настоящий» статус 5xx)
- комментарий (например, для кода 200 комментарием является «OK») — здесь может быть что угодно
Опять меняем наш небольшой скрипт — теперь мы хотим, чтобы доставленное через HTTP заголовок сообщение выводилось прямо в строку статуса ответа:
<?php $headers = apache_request_headers(); if (isset($headers)) { header('HTTP/1.1 599 ' . 'I got your message: ' . $headers); }
Отправляем в заголовке произвольную строку:
curl -v -H 'Hackware: Hello! How are you?' localhost/headers.php
И получаем её в строке статуса:
Я хотел ещё поменять строку с версией «HTTP/1.1», но средствами cURL/PHP это, видимо, сделать невозможно. В принципе, можно подключиться к Ncat и отправить какую угодно строку статуса ответа, чтобы посмотреть, как на это прореагирует HTTP клиент (но скорее всего, просто напишет, что-то в духе «получен неверный ответ»).
WAMP Server
As MAMP is for Mac OS, WAMP is for Windows. It is also an open-source PHP server for creating a localhost server.
Windows do not allow WordPress installation on its servers. WAMP makes the task of installing WordPress on local computer possible, that’s why it is popular among developers.
WAMP is a complete tool for beginner developers with easily accessible Apache configuration, PHP configuration, logs and directory files.
The functions it provides makes WAMP very user-friendly PHP server.
WAMP PHP server is a similar stack. The only difference is that Internet Information Services replaces Apache.
Получение ссылки текущей страницы в PHP
Для получения данных нужно обратиться к глобальной переменной в PHP, которая называется $_SERVER. Переменная $_SERVER представляет собой массив, содержащий много полезной информации. На практике $_SERVER может получать любые данные о текущем URL:
— доменное имя;
— название скрипта;
— параметры URL.
По сути, в глобальном массиве $_SERVER хранятся и заголовки, и пути, и местоположения скриптов. Если вас интересует сразу вся информация, хранимая в массиве $_SERVER, воспользуйтесь следующим кодом на PHP. Он выведет всё, что хранится, сделав это в читабельном виде:
<?php echo '<pre>'; var_dump($_SERVER); echo '</pre>'; ?>
Идём дальше. Представьте, что у вас есть web-страница, имеющая следующий вид: http://localhost/php-lessons/url/?name=anna&city=Valencia. Тестирование в данном примере осуществляется на локальном сервере. Если надо тестировать код на реальном веб-сайте, доступном в интернете, достаточно вместо localhost прописать имя сайта (домен) — тот же otus.ru.
Что же мы увидим в подопытном url? Нас могут интересовать следующие данные:
— адрес веб-страницы без GET-параметров;
— URL с GET-параметрами;
— непосредственно GET-параметры без текущей ссылки (адреса веб-страницы).
Лучше всего разобраться с каждым из случаев по отдельности — так будет гораздо понятнее.
С HTTP на HTTPS (другой порт)
Пример конфигурации для перенаправления запросов на другой порт — с 80 (http) на 443 (https):
server {
listen 80;
server_name domain.ru www.domain.ru;
return 301 https://$host$request_uri;
}
* в данном примере для всех обращений к сайту domain.ru по 80 порту (http) будет работать редирект на 443 порт (https) с кодом 301 (для склеивания доменов).
Также мы можем добавить условие, чтобы не перенаправлять на https для определенных ссылок, например:
server {
listen 80;
server_name domain.ru www.domain.ru;
if ($uri !~ /page.html){
return 301 https://$host$request_uri;
}
}
* в данном примере запрос на страницу /page.html будет открыт по http.
PHP $_SERVER
$_SERVER is a PHP super global variable which holds information about headers,
paths, and script locations.
The example below shows how to use some of the elements in $_SERVER:
Example
<?php echo $_SERVER;echo «<br>»;
echo $_SERVER;echo «<br>»;echo $_SERVER;
echo «<br>»;echo $_SERVER;echo «<br>»;echo $_SERVER;echo «<br>»;echo $_SERVER;?>
The following table lists the most important elements that can go inside $_SERVER:
Element/Code | Description |
---|---|
$_SERVER | Returns the filename of the currently executing script |
$_SERVER | Returns the version of the Common Gateway Interface (CGI) the server is using |
$_SERVER | Returns the IP address of the host server |
$_SERVER | Returns the name of the host server (such as www.w3schools.com) |
$_SERVER | Returns the server identification string (such as Apache/2.2.24) |
$_SERVER | Returns the name and revision of the information protocol (such as HTTP/1.1) |
$_SERVER | Returns the request method used to access the page (such as POST) |
$_SERVER | Returns the timestamp of the start of the request (such as 1377687496) |
$_SERVER | Returns the query string if the page is accessed via a query string |
$_SERVER | Returns the Accept header from the current request |
$_SERVER | Returns the Accept_Charset header from the current request (such as utf-8,ISO-8859-1) |
$_SERVER | Returns the Host header from the current request |
$_SERVER | Returns the complete URL of the current page (not reliable because not all user-agents support it) |
$_SERVER | Is the script queried through a secure HTTP protocol |
$_SERVER | Returns the IP address from where the user is viewing the current page |
$_SERVER | Returns the Host name from where the user is viewing the current page |
$_SERVER | Returns the port being used on the user’s machine to communicate with the web server |
$_SERVER | Returns the absolute pathname of the currently executing script |
$_SERVER | Returns the value given to the SERVER_ADMIN directive in the web server configuration file (if your script runs on a virtual host, it will be the value defined for that virtual host) (such as someone@w3schools.com) |
$_SERVER | Returns the port on the server machine being used by the web server for communication (such as 80) |
$_SERVER | Returns the server version and virtual host name which are added to server-generated pages |
$_SERVER | Returns the file system based path to the current script |
$_SERVER | Returns the path of the current script |
$_SERVER | Returns the URI of the current page |
❮ Previous
Next ❯
Структура URL адресов в админке
Обычно URL адреса в админке формируются по одной из следующих схем:
И сразу рассмотрим простой пример:
Итак, мы видим, что модулем здесь является products, а действием, к примеру, add. Что теперь с этим делать?
Если вы знакомы с ООП и MVC, тогда модулем для вас будет название класса, а действием — метод этого класса, который нужно запустить. Если действие не указано, то принято запускать метод под названием index.
Если вы ничего не поняли — воспринимайте модуль как название файла, который нужно подключить, а действие — как, собственно, действие, которое нужно выполнить.
Перепишем пример, написанный нами в единой точке входа, под новую схему URL:
Итак, мы берём 1-ый фрагмент URL и проверяем, существует ли в папке pages файл с таким названием.
Т.е. при переходе на страницу /test/test2 скрипт проверит существование файла /pages/test.php. Если файл есть — PHP выполнит этот файл, в противном случае выполнится файл /pages/404.php.
Как видите, при таком подходе нам больше не нужно прописывать соответствие URL-адресов и PHP-файлов. PHP сам будет искать нужный файл в папке pages по первому фрагменту URL.
Теперь осталось только создать файл pages/products.php. Сделаем небольшую заготовку:
Вот так выглядит обработка действий. Мы смотрим на второй фрагмент URL и ищем обработчик этого действия. Для каждого действия (add, update, delete) нужно прописать отдельный блок elseif.
Внутри обработчика add мы смотрим на то, каким методом пришёл запрос, GET или POST. Если GET — отображаем форму, если POST — добавляем товар.
Если вам не нравится вложенная проверка метода, можно сделать иначе. В файле index.php сохраним метод в отдельную переменную:
products.php
Готово. Да, если вам не нравится, что в коде 2 раза встречается одно и то же действие, только с разными методами, можете использовать немного упрощённую схему URL-адресов из фреймворка Laravel:
Добавление префикса /admin/ в URL
Немного изменим код index.php:
Теперь при запросе страницы /admin/products PHP будет искать файл с названием не products.php, а admin_products.php.
Переименуйте файл и не забудьте заменить в нём все $segments на $segments, поскольку в $segments теперь лежит модуль, а в $segments действие.
Пример двойного редиректа
Для того, чтобы было понятно, о чем идет речь, приведу пример. Допустим, у вас настроен и добавление к урлу в конце слеш. То есть вы хотите такое преобразование:
http://site.ru/catalog -> https://site.ru/catalog
Допустим, у вас сначала был настроен редирект на https подобным образом:
server { listen 80; root /var/www/site.ru/public; location / { return 301 https://site.ru$request_uri; } }
А потом вас попросили добавить редирект всех урлов без слеша на тот же урл только со слешем на конце. Вы идете в секцию c listen 443 и добавляете редирект.
server { listen 443 http2; ................... location / { rewrite ^(*)$ $1/ permanent; ................... }
# curl -I -L http://site.ru/catalog HTTP/1.1 301 Moved Permanently Server: nginx Content-Type: text/html Content-Length: 162 Connection: keep-alive Location: https://site.ru/catalog HTTP/2 301 server: nginx content-type: text/html content-length: 162 location: https://site.ru/catalog/ HTTP/2 200 server: nginx content-type: text/html; charset=utf-8 vary: Accept-Encoding
На выходе у вас 2 редиректа вместо одного, что плохо для СЕО. Надо по возможности все реализовать в одном. В данном случае напрашивается простое и очевидное решение:
server { listen 80; server_name site.ru www.site.ru; root /var/www/site.ru/public; location / { return 301 https://site.ru$request_uri/; } }
Вроде бы все нормально. Теперь редирект будет автоматически добавлять слеш в конец запроса. Но проблемы начнутся со ссылками на медиа файлы. Например, запрос http://site.ru/catalog/img.png будет превращаться в https://site.ru/catalog/img.png, что нам совершенно не нужно. Чтобы это исправить, надо сделать так.
server { listen 80; server_name site.ru www.site.ru; location ~* ^.+.(js|css|png|jpg|jpeg|gif|webp|ico|woff|txt)$ { return 301 https://site.ru$request_uri; } location / { return 301 https://site.ru$request_uri/; } }
Теперь все будет нормально, так как location со статикой указан в виде регулярного выражения. В случае попадания запроса в указанное правило, будет выполнен редирект без слеша. Все остальное попадет в следующий префиксный /. То же самое можно сделать с помощью if и одного location, но c if работать будет медленнее. Там где можно обходиться без if, лучше его не использовать.
Latest Magento Tips, Guides, & News
PHP
Установка PHP
Откроется страница с несколькими версиями пакета — там как мы ставим PHP как FastCGI, нам нужна версия «Non Thread Safe» (не потокобезопасная), так как она будет работать быстрее. И так, скачиваем zip-архив на сервер:
Для установка PHP на Windows достаточно просто распаковать содержимое архива в любой каталог, например, C:\Program Files\PHP:
Делаем копию файла php.ini-production и переименовываем его в php.ini:
Открываем на редактирование данный файл и правим следующее:
open_basedir = C:\inetpub\wwwroot
…
cgi.force_redirect = 0
…
short_open_tag = On
* где open_basedir — директория, в которой будут разрешены PHP-скрипты; cgi.force_redirect — указывает будет ли скрипты обрабатываться при прямом запросе или только при запросе от веб-сервера. В IIS запросы контролируются самим веб-сервером, поэтому опция может оказать обратный эффект; short_open_tag — позволяет использовать короткий вид открывающих тегов для PHP.
Проверяем, что PHP работает. Открываем командную строку Windows — переходим в каталог с установленным PHP:
cd «C:\Program Files\PHP»
Запускаем php с параметром -m:
php -m
Мы должны получить список подключенных модулей:
bcmath
calendar
Core
ctype
…
Но если мы получим ошибку, связанную с отсутствием файла VCRUNTIME140.dll:
… необходимо установить Microsoft Visual C++ Redistributable. Переходим на страницу https://www.microsoft.com/ru-RU/download/details.aspx?id=52685 и скачиваем компонент:
После загрузки, устанавливаем его на сервер, после чего, снова пробуем вывести на экран модули php:
php -m
Настройка сайта на IIS для работы с PHP
И так, веб-сервер поднят, PHP установлено, сайт работает. Настроим связку IIS + PHP. Открываем панель управления IIS — переходим к созданному сайту и кликаем по Сопоставления обработчиков:
В меню справа кликаем по Добавить сопоставление модуля:
Заполняем поля:
* где:
- Путь запроса — путь к файлам, при вызове которых действует сопоставление. В данном примере для всех файлов, заканчивающихся на php.
- Модуль — действующий модуль для обработки запроса.
- Исполняемый файл — файл, который будет выполнять обработку запроса. В данном примере мы выбрали файл из скачанного и распакованного нами архива PHP.
- Имя — произвольное имя для сопоставления.
Нажимаем OK и подтверждаем действие. Сопоставление создано.
Теперь заходим в Документ по умолчанию:
… и добавляем новый документ:
* в данном примете мы указываем, что по умолчанию сервер будет искать файл index.php, если таковой не указан явно в запросе.
Открываем в проводнике папку, в которой находятся файлы сайта (в нашем примере, C:\inetpub\wwwroot\php). Создаем файл index.php с содержимым:
<?php
phpinfo();
?>
PHP Manager в IIS
Скачиваем дополнение:
Выполняем установку на сервере, запустив загруженный файл. Открываем диспетчер управления IIS — мы должны увидеть PHP Manager:
Синтаксис .htaccess
Синтаксис файла простой: каждая директива (команда) начинается с новой строки, после знака # можно добавлять комментарии, которые не будут учитываться сервером. Изменения на сайте вступают в силу сразу, перезагрузка сервера не требуется.
Правила задаются в том числе при помощи регулярных выражений. Для того, чтобы их прочитать, нужно понимать значение спецсимволов и переменных. Расшифруем самые часто используемые.
Основные спецсимволы:
- ^ — начало строки;
- $ — конец строки;
- . — любой символ;
- * — любое количество любых символов;
- ? — один определенный символ;
- — последовательность символов, например, от 0 до 9;
- | — символ «или», выбирается или одна группа, или другая;
- () — иcпользуется для выбора групп символов.
Основные переменные:
- %{HTTP_USER_AGENT} — поле User-Agent, которое передает браузер пользователя;
- %{REMOTE_ADDR} — IP адрес пользователя;
- %{REQUEST_URI} — запрашиваемый URI;
- %{QUERY_STRING} — параметры запроса после знака ?.
Для тех, кто хочет основательно погрузиться в тему, — полная официальная документация по использованию .htaccess или хороший ресурс на русском. А мы пройдемся по основным возможностям файла для оптимизации вашего сайта.
Оптимизируем работу сайта
Скорость загрузки сайта — один из факторов ранжирования в поисковых системах. Увеличить ее можно в том числе с помощью директив в .htaccess.
14. Сжимаем компоненты сайта при помощи mod_gzip или mod_deflate
Сжатие файлов, с одной стороны, увеличивает скорость загрузки сайта, но с другой — больше нагружает сервер. В .htaccess можно включить сжатие при помощи двух модулей — mod_zip и mod_deflate. Они практически идентичны по качеству сжатия.
Синтаксис модуля Gzip более гибкий и он умеет работать с масками:
В mod_deflate вы перечисляете типы файлов, которые нужно сжать:
15. Усиливаем кэширование
Этот комплекс команд поможет быстрой загрузке сайта для тех посетителей, которые уже на нем были. Браузер не будет заново скачивать картинки и скрипты с сервера, а использует данные из кэша.
В примере срок жизни кэша ограничен одной неделей («1 week»), вы можете указать свой срок в месяцах (month), годах (year), часах (hours) и т.д.
Другой вариант кода:
Для кэширования доступны следующие типы файлов:
- image/x-icon;
- image/jpeg;
- image/png;
- image/gif;
- application/x-shockwave-flash;
- text/css;
- text/javascript;
- application/javascript;
- application/x-javascript;
- text/html;
- application/xhtml+xml.
Why using PHP Server Stacks?
If you are a budding developer, you don’t know how frustrating it is to install a Web Server.
It does not end at web servers, developers also have to install PHP, MariaDB, and sometimes Pearl, Ruby and other programming languages.
You can download them separately, and then install them to a same directory. And then you have to activate each of them before running the local host.
Else, you can easily download a PHP server, that is already stacked with the PHP, a database, OS, and a web server. They are a one-click installer of various useful programs that a developer needs to create an environment for web app deployment.
However, there are various type of PHP servers, depending on the requirements of the developer.
Let’s look at them in detail.
Установка MySQL
На следующей странице выбираем для скачивания mysql-installer-community:
В открывшемся окне кликаем по No thanks, just start my download:
Начнется загрузка файла для установки MySQL. Дожидаемся скачивания и запускаем установочный файл — в открывшемся окне выбираем Server only:
В следующем окне кликаем по Execute:
… и дожидаемся установки СУБД:
Откроется окно конфигурации MySQL — нажимаем Next:
Выбираем установку одиночного сервера MySQL:
Оставляем все значения по умолчанию для настроек сети:
Требуем сложные пароли:
Вводим дважды пароль для пользователя root:
* также, на данном этапе мы можем сразу добавить новых пользователей.
Устанавливаем СУБД как сервис и стартуем его:
Настройки готовы для применения — нажимаем Execute:
Дожидаемся применения настроек и кликаем по Next:
Настройка завершена:
Установка завершена — нажимаем Finish.
Сервер баз данных готов к использованию.
По умолчанию, PHP поддерживаем mysql — в этом можно убедиться на странице phpinfo, найдя раздел mysqlnd: