Применение php: методы на стороне сервера, которые помогут вам в разработке интерфейсов
Содержание:
- Обеспечиваем безопасность сайта
- Как в PHP поменять заголовки и метод HTTP запроса
- Общие правила работы с .htaccess
- Использование вложенных if
- Простой роутинг
- PHP $_SERVER
- Единая точка входа
- Установка MySQL
- Получение полного URL в PHP
- Структура URL адресов в админке
- Настраиваем редиректы для SEO
- Итог
Обеспечиваем безопасность сайта
Файл .htaccess предоставляет большие возможности для защиты сайта от вредоносных скриптов, кражи контента, DOS-атак. Также можно защитить доступ к определенным файлам и разделам.
5. Запрещаем загрузку картинок с вашего сайта
Существуют технологии, при которых сторонние сайты используют контент, в том числе изображения, загружая его прямо с вашего хостинга путем хотлинков (прямых ссылок на файлы). Это не только обидно и нарушает авторские права, но и создает ненужную дополнительную нагрузку на ваш сервер.
Осадите воришек при помощи этого кода:
Заменяете «mysite.com» на адрес вашего сайта и создаете изображение с любым сообщением о том, что красть чужие картинки нехорошо, по адресу . Это изображение и будет показано на стороннем ресурсе.
6. Запрещаем доступ
Целым группам нежелательных гостей с определенных IP-адресов, подсетей, а также вредоносным ботам можно запретить доступ на ваш ресурс при помощи следующих директив в .htaccess.
Для нежелательных User Agents (ботов)
Список юзер-агентов можно дополнять, сокращать или создать свой. Перечень хороших и плохих ботов можно посмотреть здесь.
Частный случай такого запрета — запрет для поисковых роботов. Если вас почему-то не устраивает правило в robots.txt, можно запретить доступ, например, роботу Google при помощи таких директив:
Для подсети
Вписываем маску сети в строку после «deny from».
Спамные IP-адреса можно вычислить в логах сервера или с помощью сервисов статистики. В административной панели WordPress отображаются IP-адреса комментаторов:
К определенному файлу
Вписываем название файла вместо «myfile.html» в примере. Пользователю будет показана ошибка 403 — «доступ запрещен».
Не лишним будет ограничить доступ к самому файлу .htaccess из соображений безопасности, а также рекомендуем после настройки всех правил поставить на файл права доступа 444.
Для сайтов на WordPress важно ограничить доступ к файлу wp-config.php, т.к. в нем содержится информация о базе данных:
Для пользователей, пришедших с определенного сайта
Вы можете заблокировать посетителей с нежелательных ресурсов (например, со взрослым или шокирующим контентом).
7. Защищаем доступ к определенному файлу или папке
Для начала создайте файл .htpasswd, пропишите в нем логины и пароли в формате user:password и разместите в корне сайта. В целях безопасности пароли лучше зашифровать. Это можно сделать при помощи специальных сервисов генерации записей, например, такого. Следующим шагом добавьте директории или файлы в .htaccess:
Защита паролем папки
Вместо «/pub/home/.htpasswd» укажите путь до файла .htpasswd от корня сервера. Рекомендуем проверить доступ после установки кода.
8. Запрещаем выполнение вредоносных скриптов
Следующая группа директив защищает сайт от так называемых «скриптовых инъекций» — инструмента хакерских атак:
Все попытки причинить вред вашему ресурсу будут перенаправлены на страницу ошибки 403 «доступ запрещен».
9. Защищаем сайт от DOS-атак
Один из способов защиты — ограничить максимально допустимый размер запроса (ограничение отсутствует по умолчанию).
Для этого прописываем в .htaccess размер загружаемых файлов в байтах:
В примере указан размер 10 Мбайт. Если вы хотите запретить загрузку файлов, пропишите число меньше 1 Мбайт (1048576 байт).
Также можно изучить возможности директив LimitRequestFields, LimitRequestFieldSize и LimitRequestLine в официальной документации.
Как в PHP поменять заголовки и метод HTTP запроса
В этой статье мы использовали утилиту cURL. Рассмотрим вариант, когда вы работаете с cURL через PHP — типичный случай для веб-серверов.
Что касается использования методов, отличных от GET, то для метода POST есть специальный параметр CURLOPT_POST, для метода PUT есть CURLOPT_PUT.
Для DELETE, CONNECT, HEAD и других более редки либо просто произвольных методов запроса используйте CURLOPT_CUSTOMREQUEST следующим образом (замените «МЕТОД» на нужный вам):
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "МЕТОД");
Создадим теперь файл methods.php:
sudo gedit /var/www/html/methods.php
и скопируем в него:
<?php $target_url = "localhost/headers.php"; $agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36'; //$referer = 'REFERER HERE'; $cookies = ''; $ch = curl_init($target_url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "MIAL"); curl_setopt($ch, CURLOPT_USERAGENT, $agent); //curl_setopt($ch, CURLOPT_REFERER, $referer); curl_setopt($ch, CURLOPT_COOKIEJAR, $cookies); curl_setopt($ch, CURLOPT_COOKIEFILE, $cookies); //curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 'true'); $response_data = curl_exec($ch); if (curl_errno($ch) > 0) { die(PHP_EOL . PHP_EOL . 'Ошибка curl: ' . curl_error($ch) . PHP_EOL . PHP_EOL . print_r(curl_getinfo($ch)) . PHP_EOL . PHP_EOL); } elseif (empty($response_data)) { die(PHP_EOL . PHP_EOL . 'Returned empty result: ' . print_r(curl_getinfo($ch)) . PHP_EOL . PHP_EOL); } curl_close($ch); print_r (headers_list()) . PHP_EOL; echo $response_data . PHP_EOL;
Этот скрипт делает HTTP запрос указанным методом и показывает все полученные HTTP заголовки ответа.
Файл headers.php делаем таким:
<?php header('HTTP/1.1 599 ' . 'Just because we can!'); header ('HackWare: I am here!');
Запустим methods.php прямо в командной строке:
php /var/www/html/methods.php
В последнем примере мы добились:
- cURL в скрипте PHP использует пользовательский метод запроса MIAL — можно использовать для проверки, какие методы поддерживает сервер; ещё такие запросы не обнаруживаются фильтром «http» в Wireshark.
- ответ мы получили с произвольным комментарием в строке состояния и с заголовком с произвольным именем и содержанием.
Общие правила работы с .htaccess
- Всегда делайте резервную копию файла перед внесением изменений, чтобы оперативно «откатить» их.
- Вносите изменения пошагово, добавляйте по одному правилу и оценивайте, как оно сработало.
- Если размещаете несколько файлов .htaccess в разных каталогах, прописывайте в дочерних только новые директивы, которые актуальны для конкретного каталога, остальные унаследуются от родительского каталога или файла в корневой папке.
- Очищайте кэш браузера: Ctrl + F5, в Safari: Ctrl + R, в Mac OS: Cmd + R.
- Если возникает ошибка 500, проверьте синтаксис правила (нет ли опечатки). Можно воспользоваться сервисами проверки файла .htaccess онлайн, например таким. Если ошибок не найдено, значит в главном конфигурационном файле такой тип директивы запрещен, придется обратиться за консультацией к программисту и хостинг-провайдеру.
- В директивах .htaccess кириллические символы не допускаются. Если необходимо указать адрес кириллического домена (мойсайт.рф), воспользуйтесь любым whois-сервисом, чтобы узнать его написание по методу punycode. Например, адрес «сайт.рф» будет выглядеть как «xn--80aswg.xn--p1ai/$1».
- Слишком большое количество директив в .htaccess может снизить работоспособность сайта. Старайтесь использовать файл только в том случае, если другим путем задачу решить нельзя.
- Если нет времени подробно изучать особенности директив, воспользуйтесь генератором .htaccess.
Использование вложенных if
Вложенные if в конфигурации nginx запрещены, поскольку это вовсе не языковая конструкция nginx, а обычная директива из модуля rewrite, использование которой в ее же собственном контексте if не предусмотрено. Использование списка условий, разделенных логическими операторами «и» и «или» тоже не предусмотрено. Обычно для эмуляции вложенных условий с использованием директивы if предлагают использовать регулярные выражения. Например, проверить, что имя, указаное в HTTP хедере HOST, соответствует значению localhost, а в URI присутствует аргумент «a» (в этом случае переменная $arg_a будет не пустой), можно так:
К сожалению, условие в директиве if имеет ограничения. По крайней мере, это не выражение, и оно не может быть составлено в виде цепочки выражений, разделенных логическими операторами. Кроме того, в случае сравнения чего-то с регулярным выражением, это что-то может быть только именем переменной, именно поэтому пришлось ввести новую переменную $cond:
В данном примере мы соединили через произвольно выбранный нами разделитель :: три переменных $host, $goodhost и $arg_a и присвоили это значение переменной $cond. А регулярное выражение, с которым мы сопоставляем это значение, проверяет, что его первая часть (до разделителя ::) и вторая часть (до второго разделителя ::) равны, а последняя часть (после второго разделителя) не пуста.
В полном виде конструкция проверки примет вид:
Простой роутинг
Если единая точка входа настроена правильно, то при заходе по любому несуществующему URL-адресу, например /test должен запуститься файл index.php.
URL текущей страницы находится в переменной $_SERVER
Теперь мы можем написать очень простой роутер, который смотрит на текущий URL и подключает соответствующий скрипт:
Внесём ещё пару доработок. Во-первых, зачастую URL-адреса должны работать вне зависимости от наличия GET-параметров, поэтому вырежем их из URI:
Кроме этого, часто требуется получить доступ к определённой части URL. Для этого разобьём URL на части по слешу:
В переменной $segments для URL /products/15 будет лежать массив вида .
Теперь мы можем легко добавить маршруты для админки:
Это самый простой вариант роутинга. Не идеальный, конечно, но и не требующий знания регулярных выражений (хотя никто не мешает их использовать) и подключения сторонних библиотек.
При хранении URL адресов в базе данных роутинг будет выглядеть примерно так (реальный код зависит от библиотеки, которую вы используете для взаимодействия с БД):
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 ❯
Единая точка входа
Принцип работы единой точки входа очень прост.
Веб-сервер настраивается так, чтобы все HTTP-запросы, вне зависимости от их URL, обрабатывались одним и тем же скриптом index.php.
Перенаправление всех запросов на index.php
Текущий URL можно получить из переменной $_SERVER. Дальше останется только написать свои правила обработки URL-адресов. Упрощённый пример:
Однако в схеме выше есть одно упущение. Ведь если на сервер пришёл запрос к существующему файлу (style.css, script.js, logo.png и т.д) — сервер должен отдать этот файл, а не перенаправлять его.
Принцип работы единой точки входа
Вот и весь принцип единой точки входа. Именно так она работает в популярных CMS вроде WordPress и Opencart, в фреймворках Laravel, Symfony и т.д.
Единственный вопрос, который вам останется решить — что делать с запросами к существующим папкам.
Лично я предпочитаю также перенаправлять их на index.php.
На самом деле на сайтах часто используются 2 точки входа.
Первая — index.php, вторая — отдельный скрипт, предназначенный для работы с сайтом через консоль.
Плюсы единой точки входа
- Позволяет использовать ЧПУ
- Позволяет полностью управлять URL-адресами в PHP, в том числе хранить URL-адреса в базе данных
- Скрипты с конфигами, важными функциями и библиотеками подключаются только 1 раз и становятся доступны везде. Не нужно дублировать их подключение где-либо ещё.
Единая точка входа с Apache
Для настройки единой точки входа необходимо добавить несколько строк в конфиг веб-сервера. Проще всего это сделать с помощью файла .htaccess.
Этот файл позволяет переопределять настройки Apache для определённых сайтов и папок.
Добавляем следующие настройки в .htaccess:
Чтобы перенаправление срабатывало для существующих директорий, удаляем строку с !-d в конце, вот так:
Готово. Получить URL адрес текущей страницы можно из переменной $_SERVER.
Также в интернете часто можно встретить другой вариант конфига, отличается он только последней строкой:
Главное отличие в том, что URL-адрес текущей страницы будет храниться как в $_SERVER, так и в отдельном GET-параметре, в нашем случае $_GET, причём этот URL будет очищен от GET-параметров.
Флаг QSA нужен, поскольку без него GET-параметры не будут работать, т.е. массив $_GET будет содержать только url_param и больше ничего.
Какой из двух вариантов выбрать — решать вам, лично мне больше нравится первый.
Установка 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:
Получение полного URL в PHP
Для получения полного URL вместе с имеющимися GET-параметрами, пригодится следующий код:
$url = ((!empty($_SERVER'HTTPS'])) ? 'https' 'http') . '://' . $_SERVER'HTTP_HOST' . $_SERVER'REQUEST_URI']; echo $url;
Что здесь что? В первую очередь, осуществляется проверка, какой именно протокол передачи данных задействуется: https или http. В случае, если значение $_SERVER не является пустым, речь идёт о протоколе https, в обратном случае — http.
На втором этапе выполняется присоединение двоеточия и двух слэшев, имени домена и остальной части URL.
Итог выполнения кода будет следующим:
Если протокол получать не требуется, код на PHP можно немного сократить:
Смотрим на результат и видим, что протокол отсутствует:
Структура 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 действие.
Настраиваем редиректы для SEO
Как мы уже упоминали, это самый популярный способ использования .htaccess. Перед тем, как настраивать тот или иной вид переадресации, убедитесь, что это действительно необходимо. Например, редирект на страницы со слешем в некоторых CMS настроен по умолчанию. О настройках редиректа для SEO мы писали в блоге.
При настройке 301 редиректов помните о двух правилах:
- Избегайте нескольких последовательных перенаправлений — они увеличивают нагрузку на сервер и снижают скорость работы сайта.
- Располагайте редиректы от частных к глобальным. Например, сначала переадресация с одной страницы на другую, затем общий редирект на страницы со слешем. Это правило работает не в 100% случаев, поэтому с размещением директив нужно экспериментировать.
1. Настраиваем постраничные 301 редиректы
Это потребуется в следующих случаях:
- изменилась структура сайта и у страницы поменялся уровень вложенности;
- страница перестала существовать, но нужно сохранить ее входящий трафик (например, в случае отсутствия товара обычно делают переадресацию на товарную категорию);
- поменялся URL, что крайне нежелательно, но тоже встречается.
Просто удалить страницу — плохая идея, лучше не отдавать роботу ошибку 404, а перенаправить его на другой URL. В этом случае есть шанс не потерять позиции сайта в выдаче и целевой трафик. Настроить 301 редирект с одной страницы на другую можно при помощи директивы простого перенаправления:
- — адрес страницы от корня, без протокола и домена. Например, .
- — полный адрес страницы перенаправления, включая протокол и домен. Например, .
2. Избавляемся от дублей
Каждая страница сайта должна быть доступна только по одному адресу. Для этого должны быть настроены:
- редирект на страницы со слешем в конце URL или наоборот;
- главное зеркало — основной адрес сайта в поиске.
Сделать это можно при помощи модуля . В его составе используются специальные команды — директивы сложного перенаправления. Первой командой всегда идет включение преобразования URL:
Переадресация на слеш или наоборот
Настроить ли переадресацию на страницы со слешем или без, в каждом случае нужно решать индивидуально. Если у сайта уже накоплена история в поиске, анализируйте, каких страниц в индексе больше. Для новых сайтов обычно настраивают редирект на слеш. Проверить, не настроена ли переадресация по умолчанию, просто: удалите/добавьте слеш в конце URL. Если страница перезагрузится с новым адресом — мы имеем дубли, требуется настройка. Если URL подменяется — все в порядке. Проверять лучше несколько уровней вложенности.
Код 301 редиректа на страницы без слеша:
3. Настраиваем главное зеркало
Для начала нужно определиться, какой адрес будет являться основным для поиска. SSL-сертификат давно уже мастхэв. Просто установите его и добавьте правило в .htaccess. Не забудьте также прописать его в robots.txt.
Редирект на HTTPS
Определять, с «www» или без будет главное зеркало, можно несколькими способами:
- добавить сайт в Яндекс.Вебмастер в двух вариантах, в консоли отобразится информация, какой URL поисковик считает главным зеркалом;
- проанализировать выдачу и посмотреть, каких страниц сайта больше в индексе;
- для нового ресурса не имеет значения, с «www» или без будет адрес, выбор за вами.
После того как выбор сделан, воспользуйтесь одним из двух вариантов кода.
Редирект с без www на www
4. Перенаправляем с одного домена на другой
Самая очевидная причина настройки этого редиректа — переадресовать роботов и пользователей на другой адрес при переезде сайта на новый домен. Также им пользуются оптимизаторы для манипуляций ссылочной массой, но дроп-домены и PBN — серые технологии продвижения, которые в рамках этого материала мы затрагивать не будем.
Воспользуйтесь одним из вариантов кода:
или
Не забудьте поменять в коде «mysite1» и «mysite2» на старый и новый домен соответственно.
Итог
# curl -I https://itsoft.ru HTTP/1.1 200 OK Server: nginx/1.16.0 Date: Tue, 05 May 2020 05:57:34 GMT Content-Type: text/html; charset=utf-8 Connection: keep-alive Keep-Alive: timeout=200 Cache-Control: max-age=604800, public Last-Modified: Wed, 01 Apr 2020 18:49:15 GMT Etag: a49f2da878be351c6c73a1ec0524d8ea Set-Cookie: a=1961012078; expires=Wed, 06-May-2020 05:57:34 GMT; path=/; secure; HttpOnly X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block; report=/feedback/http-csp-report.php Strict-Transport-Security: max-age=63072000; includeSubDomains; preload Referrer-Policy: same-origin Feature-Policy: autoplay 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; payment 'none'; usb 'none'; vibrate 'none'; Content-Security-Policy-Report-Only: default-src 'self' data: *.googletagmanager.com *.google.com *.google-analytics.com *.googleapis.com *.gstatic.com *.doubleclick.net mc.yandex.ru api-maps.yandex.ru yastatic.net webvisor.com *.calltouch.ru *.usedesk.ru *.youtube.com *.ytimg.com 'nonce-counters' 'report-sample'; img-src https: data: blob: ; report-uri /feedback/http-csp-report.php X-Frame-Options: SAMEORIGIN