Данная статья располагается на двух страницах. Вторая часть Исходники
Видеоурок к ней
На этот раз мы делаем простую AJAX систему добавления комментариев. Этот позволит продемонстрировать, как добиться эффективного взаимодействия между JQuery и PHP / MySQL с помощью JSON. Система работает таким образом, что добавляемые комментарии помещаются на страницу без её полной перезагрузки, давая ощущение работы сайта только на компьютере пользователя, тем самым избегая необходимости ждать некоторое время, необходимое для повторной загрузки страницы с добавленным комментарием.
Вот примерная демонстрация того, что мы планируем реализовать:

Шаг 1 - XHTML
Во-первых, давайте взглянем на разметку комментариев.
Этот код генерируется PHP в комментарии, который мы собираемся посмотреть в одно мгновение.
demo.php
<div class="comment">
<div class="avatar">
<a href="**********">
<img src="**********">
</a>
</div>
<div class="name"><a href="***********">Имя</a></div>
<div title="title" class="date">30 июля 2010</div>
<p>Комментарий</p>
</div>
В Div-е класса avatar содержиться гиперссылка соответсвенно с аватаром
(если пользователь указал действительную ссылку на аватар при отправке комментария), допустим из gravatar.com.
Ну мы еще вернемся к этому когда будем работать с PHP. Наконец, у нас есть имя и время также в DIV-ах,
а также комментарий то есть сам текст в параграфе.
Другим важным элементом в части XHTML является сама форма отправки комментария
(все поля, кроме поля URL обязательны для заполнения).
demo.php
<div id="addCommentContainer">
<p>Добавить комментарий</p>
<form id="addCommentForm" method="post" action="">
<div>
<label for="name">Ваше имя?</label>
<input type="text" name="name" id="name" />
<label for="email">Вашь Email?</label>
<input type="text" name="email" id="email" />
<label for="url">Ваш аватар? (не обязательно)
</label>
<input type="text" name="url" id="url" />
<label for="body">Что вы хотели сказать?
</label>
<textarea name="body" id="body" cols="20" rows="5">
</textarea>
<input type="submit" id="submit" value="Отправить" />
</div>
</form>
</div>
Шаг 2 - PHP
PHP обрабатывает связи с базой данных MySQL и создает разметку комментарий.
Кроме того, на приёме в конце стоит AJAX и вставляет комментарий в таблицу комментариев.
Вы можете увидеть код, который выводит комментарии к странице, ниже.
demo.php
/*
/ Выбрать все коммнтарии и заполнить массив $comments
*/
$comments = array();
$result = mysql_query("SELECT * FROM comments ORDER BY id ASC");
while($row = mysql_fetch_assoc($result))
{
$comments[] = new Comment($row);
}
MySQL запрос выбирает все записи из базы данных и заполняет массив $comments с объектом класса комментарий,
который вы видите ниже. Этот массив выводится после выполнения скрипта.
demo.php
/*
/ Выводим комментарии один за другим
*/
foreach($comments as $c){
echo $c->markup();
}
Каждый комментарий имеет markup() метод, который генерирует HTML код для печати страницы.
Вы можете увидеть этотот метод и класс ниже.
Класс принимает строку из базы данных
(fetched with mysql_fetch_assoc() ) и сохраняет его в переменной $data.
Она доступна только для методов этого класса и не может быть доступна извне.
comment.class.php – Шаг 1
class Comment
{
private $data = array();
public function __construct($row)
{
/*
/ Конструктор
*/
$this->data = $row;
}
public function markup()
{
/*
/ Этот метод выводит разметки XHTML комментарий
*/
// Создание псевдонима, так что мы не должны писать
// $this->data данные каждый раз:
$d = &$this->data;
$link_open = '';
$link_close = '';
if($d['url']){
// Если человек заполнил URL при
//добавлении комментария
// Определяем гиперссылку
$link_open = '<a href="'.$d['url'].'">';
$link_close = '</a>';
}
// Преобразование времени
$d['dt'] = strtotime($d['dt']);
// Необходим для изображений Gravatar по умолчанию:
$url = 'http://'.dirname($_SERVER['SERVER_NAME'].
$_SERVER["REQUEST_URI"]).'/img/default_avatar.gif';
return '
<div class="comment">
<div class="avatar">
'.$link_open.'
<img src="http://www.gravatar.com/avatar/'.
md5($d['email']).'?size=50&default='.
urlencode($url).'" />
'.$link_close.'
</div>
<div class="name">'.$link_open.$d['name'].
$link_close.'</div>
<div class="date" title="Added at '.
date('H:i \o\n d M Y',$d['dt']).'"<'.
date('d M Y',$d['dt']).'</div>
<p>'.$d['body'].'</p>
</div>
';
}
Этот сценарий использует Gravatar чтобы показать аватары в комментариях.
Для тех, кто не использовали Gravatar, это очень полезная услуга, которая позволяет связывать аватар с вашим адресом электронной почты.
Аватар может быть легко взят передавая хеш по md5().
Уведомление на линии 39 над ней - скрипт пытается выяснить, URL, на которой он находится,
и определяет точный адрес default_avatar.gif изображения. Этот GIF передается Gravatar по md5 хеш,
поэтому если аватар был найден на данном электронном адресе, вместо него отображается запасное штатное изображение.
comment.class.php – Шаг 2
public static function validate(&$arr)
{
/*
/ Данный метод используется для проверки данных,
/ передаваемых через AJAX.
/
/ Это возвращение true/false (истина/лож) в зависимости
/ от данных является действительным, и заполняеться
/ Масив $arr передается в качестве paremter
/ (обратите внимание, амперсанд выше)
/ Либо действительно ввод данных, или сообщения об ошибках.
*/
$errors = array();
$data = array();
// Использование filter_input функция, введенная в PHP 5.2.0
if(!($data['email'] =
filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL)))
{
$errors['email'] = 'Please enter a valid Email.';
}
if(!($data['url'] =
filter_input(INPUT_POST,'url',FILTER_VALIDATE_URL)))
{
// Если поле URL не соответствует не правильный URL
$url = '';
}
// Использование фильтров с пользовательской
// функцией обратного вызова:
if(!($data['body'] =
filter_input(INPUT_POST,'body',FILTER_CALLBACK,
array('options'=>'Comment::validate_text'))))
{
$errors['body'] = 'Ошибака комментариев.';
}
if(!($data['name'] =
filter_input(INPUT_POST,'name',FILTER_CALLBACK,
array('options'=>'Comment::validate_text'))))
{
$errors['name'] = 'Ошибка имени.';
}
if(!empty($errors)){
//Если есть ошибки, записываем $errors в массив $arr:
$arr = $errors;
return false;
}
foreach($data as $k=>$v){
$arr[$k] = mysql_real_escape_string($v);
}
// Убедимся, что письма в нижнем регистре
// (для правильного хэш Gravatar):
$arr['email'] = strtolower(trim($arr['email']));
return true;
}
validate() описанным выше способом определяется как статический. Это означает, что он может быть вызван как
непосредственно Comment::validate(), без необходимости создания объекта этого класса.
Этот метод не является проверкой входных данных, который представлен через AJAX.
Этот метод использует новые функции фильтра, которые доступны в PHP 5.2.0.
Это позволяет нам легко проверить и фильтр любых вводных данных, которые передаются в сценарий.
Например filter_input (INPUT_POST, "URL", FILTER_VALIDATE_URL) означает, что мы проверяем $_POST['url']
является действительный адрес URL. Если это так, то функция возвращает значение переменной,
в противном случае возвращения являются ложными.
Это очень полезно, так как до сих пор, мы должны были использовать собственные регулярные выражения
для проверки данных. Кроме того, еще одним преимуществом является то, что эти данные взяли перед любой
конфигурации конкретных преобразований (например, волшебных кавычек).
У нас также есть возможность указать пользовательскую функцию, которая собирается применить некоторые более
продвинутые модификации данных, как видно из строк 31 и 37.
comment.class.php – Шаг 3
private static function validate_text($str)
{
/*
/ Этот метод используется внутри как FILTER_CALLBACK
*/
if(mb_strlen($str,'utf8')<1)
return false;
// Кодировать все специальные символы
// HTML (<,>, ", и т.д. ..) и преобразовать
// Символы новой строки в <br /> теги:
$str = nl2br(htmlspecialchars($str));
// Удалить символы новой строки, которые остались
$str = str_replace(array(chr(10),chr(13)),'',$str);
return $str;
}
Последний метод является validate_text, которые мы передаем в качестве функции обратного вызова.
Он экранирует все специальные символы HTML, фактически лишив их XSS атак. Он также заменяет строки символов с <br /> строк.
submit.php
/*
/ Этот массив будет заполнен либо
/ Данные, которые были отправлены в сценарий, или
/ Сообщения об ошибках:
/*/
$arr = array();
$validates = Comment::validate($arr);
if($validates)
{
/* Все хорошо, вставляем в базу данных: */
mysql_query("
INSERT INTO comments(name,url,email,body)
VALUES (
'".$arr['name']."',
'".$arr['url']."',
'".$arr['email']."',
'".$arr['body']."'
)");
$arr['dt'] = date('r',time());
$arr['id'] = mysql_insert_id();
/*
/ Данные в $arr вставляем query,
/ но неэкранированный текста,
/ так что мы используем, stripslashes
/ для всех элементов массива:
/*/
$arr = array_map('stripslashes',$arr);
$insertedComment = new Comment($arr);
/* Вывод разметку */
echo json_encode(array('status'=>1,
'html'=>$insertedComment->markup()));
}
else
{
/* Вывод сообщений об ошибках */
echo '{"status":0,"errors":'.
json_encode($arr).'}';
}
submit.php получает данные комментария в виде запроса AJAX.
Она проверяет его и выдает JSON объект либо разметки XHTML который успешно выведен,
или список сообщений об ошибках. JQuery использует статус собственности определить,
следует отображать сообщения об ошибках или добавить комментарий разметки страницы.
Вы можете увидеть два примера ниже.
Перейти ко второй части статьи