Новые уроки
Получай новые уроки по RSS

Подписка на рассылку


Голосование
Чего выкладывать больше?
Программ
Уроков
Скриптов
Шаблонов
Макетов
CMS
Видеоуроков
Облако тегов

PHP → Простая AJAX система комментариев

Простая AJAX система комментариев


Демо: смотреть
Скачать: demo.zip [7,98 Kb] (cкачиваний: 837)


На этот раз, мы делаем простE. AJAX систему комментариев. Она будет включать Gravatar интеграцию и вывод комментариев, мы добьемся эффективного взаимодействия между JQuery и PHP / MySQL с помощью JSON.

Шаг 1 - XHTML

Во-первых, давайте посмотрим на разметку комментариев. Этот код генерируется PHP комментарий с классом, к которому мы добавим стиль. Наш комментарий будет иметь такой вид.

demo.php
<div class="comment">
    <div class="avatar">
        <a href="/">
        <img src="http://www.gravatar.com/avatar/112fdf7a8fe3609e7af2cd3873b5c6bd?size=50&default=http%3A%2F%2Fdemo.tutorialzine.com%2F2010%2F06%2Fsimple-ajax-commenting-system%2Fimg%2Fdefault_avatar.gif">
        </a>
    </div>

    <div class="name"><a href="/">Person's Name</a></div>
    <div title="Added at 06:40 on 30 Jun 2010" class="date">30 Jun 2010</div>
    <p>Comment Body</p>
</div>


Форма добавления будет иметь следующий код:

demo.php
<div id="addCommentContainer">
    <p>Add a Comment</p>
    <form id="addCommentForm" method="post" action="">
        <div>
            <label for="name">Your Name</label>
            <input type="text" name="name" id="name" />

            <label for="email">Your Email</label>
            <input type="text" name="email" id="email" />

            <label for="url">Website (not required)</label>
            <input type="text" name="url" id="url" />

            <label for="body">Comment Body</label>
            <textarea name="body" id="body" cols="20" rows="5"></textarea>

            <input type="submit" id="submit" value="Submit" />
        </div>
    </form>
</div>


Вот примерно как будут выглядеть наши комментарии:
Простая AJAX система комментариев


Шаг 2 - РНР
PHP будет осуществлять взаимодействие с базой данных MySQL и генерирует разметку комментариев. Кроме того, на приемном конце запросов AJAX и вставляет комментарий в таблицу комментариев. Код:

demo.php
/*
/    Select all the comments and populate the $comments array with objects
*/

$comments = array();
$result = mysql_query("SELECT * FROM comments ORDER BY id ASC");

while($row = mysql_fetch_assoc($result))
{
    $comments[] = new Comment($row);
}


Массив вывода комментариев:
/*
/    Output the comments one by one:
*/

foreach($comments as $c){
    echo $c->markup();
}


comment.class.php – Part 1
Вывод комментариев и генерация html кода комментария. Так же этот код генерирует аватрку с помощью сервиса gravatar.
class Comment
{
    private $data = array();

    public function __construct($row)
    {
        /*
        /    The constructor
        */

        $this->data = $row;
    }

    public function markup()
    {
        /*
        /    This method outputs the XHTML markup of the comment
        */

        // Setting up an alias, so we don't have to write $this->data every time:
        $d = &$this->data;

        $link_open = '';
        $link_close = '';

        if($d['url']){

            // If the person has entered a URL when adding a comment,
            // define opening and closing hyperlink tags

            $link_open = '<a href="'.$d['url'].'">';
            $link_close =  '</a>';
        }

        // Converting the time to a UNIX timestamp:
        $d['dt'] = strtotime($d['dt']);

        // Needed for the default gravatar image:
        $url = 'http://'.dirname($_SERVER['SERVER_NAME'].$_SERVER["REQUEST_URI"]).
                'http://cdn.tutorialzine.com/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>
        ';
    }


comment.class.php – Part 2
Проверка формы на заполнение всех полей, а так же правильности заполнения email и обновление комментариев на странице.

public static function validate(&$arr)
{
    /*
    /    This method is used to validate the data sent via AJAX.
    /
    /    It return true/false depending on whether the data is valid, and populates
    /    the $arr array passed as a paremter (notice the ampersand above) with
    /    either the valid input data, or the error messages.
    */

    $errors = array();
    $data    = array();

    // Using the filter_input function introduced in 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)))
    {
        // If the URL field was not populated with a valid URL,
        // act as if no URL was entered at all:

        $url = '';
    }

    // Using the filter with a custom callback function:

    if(!($data['body'] = filter_input(INPUT_POST,'body',FILTER_CALLBACK,
                    array('options'=>'Comment::validate_text'))))
    {
        $errors['body'] = 'Please enter a comment body.';
    }

    if(!($data['name'] = filter_input(INPUT_POST,'name',FILTER_CALLBACK,
                    array('options'=>'Comment::validate_text'))))
    {
        $errors['name'] = 'Please enter a name.';
    }

    if(!empty($errors)){

        // If there are errors, copy the $errors array to $arr:

        $arr = $errors;
        return false;
    }

    // If the data is valid, sanitize all the data and copy it to $arr:

    foreach($data as $k=>$v){
        $arr[$k] = mysql_real_escape_string($v);
    }

    // Ensure that the email is in lower case (for a correct gravatar hash):
    $arr['email'] = strtolower(trim($arr['email']));

    return true;

}
    private static function validate_text($str)
    {
        /*
        /    This method is used internally as a FILTER_CALLBACK
        */

        if(mb_strlen($str,'utf8')<1)
            return false;

        // Encode all html special characters (<, >, ", & .. etc) and convert
        // the new line characters to <br> tags:

        $str = nl2br(htmlspecialchars($str));

        // Remove the new line characters that are left
        $str = str_replace(array(chr(10),chr(13)),'',$str);

        return $str;
    }

}


submit.php
Обработка формы. Берем информацию из полей и заносим в базу.
/*
/    This array is going to be populated with either
/    the data that was sent to the script, or the
/    error messages:
/*/

$arr = array();

$validates = Comment::validate($arr);

if($validates)
{
    /* Everything is OK, insert to database: */

    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();

    /*
    /    The data in $arr is escaped for the mysql insert query,
    /    but we need the unescaped text, so we apply,
    /    stripslashes to all the elements in the array:
    /*/

    $arr = array_map('stripslashes',$arr);

    $insertedComment = new Comment($arr);

    /* Outputting the markup of the just-inserted comment: */

    echo json_encode(array('status'=>1,'html'=>$insertedComment->markup()));

}
else
{
    /* Outputting the error messages */
    echo '{"status":0,"errors":'.json_encode($arr).'}';
}


Простая AJAX система комментариев


CSS
Далее чтоб наша страница не смотрелась пустой и не красивой, мы украсим её с помощью css стилей.
*{
    margin:0;
    padding:0;
}

body{
    font-size:14px;
    color:#666;
    background:url('img/bg.jpg') #f2f2f2;
    font-family:Arial, Helvetica, sans-serif;
}

.comment,
#addCommentContainer{
    
    /* Syling the comments and the comment form container */
    
    padding:12px;
    width:400px;
    position:relative;
    background-color:#fcfcfc;
    border:1px solid white;
    color:#888;
    margin-bottom:25px;
    
    /* CSS3 rounded corners and drop shadows */
    
    -moz-border-radius:10px;
    -webkit-border-radius:10px;
    border-radius:10px;

    -moz-box-shadow:2px 2px 0 #c2c2c2;
    -webkit-box-shadow:2px 2px 0 #c2c2c2;
    box-shadow:2px 2px 0 #c2c2c2;
}

.comment .avatar{

    /*
    /    The avatar is positioned absolutely,
    /    and offset outside the comment div
    /*/

    height:50px;
    left:-70px;
    position:absolute;
    width:50px;
    background:url('img/default_avatar.gif') no-repeat #fcfcfc;
    
    /* Centering it vertically: */
    
    margin-top:-25px;
    top:50%;

    -moz-box-shadow:1px 1px 0 #c2c2c2;
    -webkit-box-shadow:1px 1px 0 #c2c2c2;
    box-shadow:1px 1px 0 #c2c2c2;
}

.comment .avatar img{
    display:block;
}

.comment .name{
    font-size:20px;
    padding-bottom:10px;
    color:#ccc;
}

.comment .date{
    font-size:10px;
    padding:6px 0;
    position:absolute;
    right:15px;
    top:10px;
    color:#bbb;
}

.comment p,
#addCommentContainer p{
    font-size:18px;
    line-height:1.5;
    overflow-x:hidden;
}

#addCommentContainer input[type=text],
#addCommentContainer textarea{

    /* Styling the inputs */

    display:block;
    border:1px solid #ccc;
    margin:5px 0 5px;
    padding:3px;
    font-size:12px;
    color:#555;
    font-family:Arial, Helvetica, sans-serif;
}

#addCommentContainer textarea{
    width:300px;
}

label{
    font-size:10px;
}

label span.error{
    color:red;
    position:relative;
    right:-10px;
}

#submit{
    
    /* The submit button */
    
    background-color:#58B9EB;
    border:1px solid #40A2D4;
    color:#FFFFFF;
    cursor:pointer;
    font-family:'Myriad Pro',Arial,Helvetica,sans-serif;
    font-size:14px;
    font-weight:bold;
    padding:4px;
    margin-top:5px;

    -moz-border-radius:4px;
    -webkit-border-radius:4px;
    border-radius:4px;
}

#submit:hover{
    background-color:#80cdf5;
    border-color:#52b1e2;
}

/* The styles below are only necessary for the styling of the demo page: */

#main{
    position:relative;
    margin:0 auto;
    width:427px;
}

h1{
    color:#7E94A2;
    font-size:30px;
    margin:50px 0 20px;
}

h2{
    font-size:18px;
    margin-bottom:50px;
}

h1,h2{
    font-family:"Myriad Pro",Arial,Helvetica,sans-serif;
    text-align:center;
    font-weight:normal;
    text-shadow:0 1px 1px #FFFFFF;
}

a, a:visited {
    color:#0196e3;
    text-decoration:none;
    outline:none;
}

a:hover{
    text-decoration:underline;
}

a img{
    border:none;
}


Шаг 4 - JQuery
Теперь давайте продолжать работу с JQuery, который является последним этапом этого урока. После включения библиотеки в нижней части страницы (для лучшей производительности) мы можем начать кодирования файла сценария.
$(document).ready(function(){
    /* The following code is executed once the DOM is loaded */

    /* This flag will prevent multiple comment submits: */
    var working = false;

    /* Listening for the submit event of the form: */
    $('#addCommentForm').submit(function(e){

        e.preventDefault();
        if(working) return false;

        working = true;
        $('#submit').val('Working..');
        $('span.error').remove();

        /* Sending the form fileds to submit.php: */
        $.post('submit.php',$(this).serialize(),function(msg){

            working = false;
            $('#submit').val('Submit');

            if(msg.status){

                /*
                /    If the insert was successful, add the comment
                /    below the last one on the page with a slideDown effect
                /*/

                $(msg.html).hide().insertBefore('#addCommentContainer').slideDown();
                $('#body').val('');
            }
            else {

                /*
                /    If there were errors, loop through the
                /    msg.errors object and display them on the page
                /*/

                $.each(msg.errors,function(k,v){
                    $('label[for='+k+']').append('<span class="error">'+
                        v+'</span>');
                });
            }
        },'json');

    });

});

Скрипт плавно обновляет информацию на странице. И комментарии плавно добавляются.
Опубликовал dimas_ua, 6-04-2011, 00:00 Комментариев: 14
 (голосов: 32)
Пишет Мария, 9 апреля 2011 23:49
  • Сообщений: 0
  • Новостей: 0
Огромное спасибо!
Пишет Вад, 21 апреля 2011 17:34
  • Сообщений: 0
  • Новостей: 0
Не сохроняет комменты, вверху выводит Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource in Z:\home\New\www\Coment\demo.php on line 17 юзаю денвер, в пхп ниче не смыслю :) Однако оч нужна система комментов :)

Вад, ой, в имя забыл дописать букву Л :)
Пишет кран балка, 19 июля 2011 19:29
  • Сообщений: 0
  • Новостей: 0
Восхищена как всегда
Пишет супер марио онлайн, 21 июля 2011 01:27
  • Сообщений: 0
  • Новостей: 0
Хорошая статья. Краткость явно Ваша сестра

Даже и не придирешься!
Пишет ipad 2 купить, 22 июля 2011 00:45
  • Сообщений: 0
  • Новостей: 0
прочитав несколько статей на эту тему понял

Спасибо! Супер статья! Блог в ридер однозначно

Спасибо! Супер статья! Блог в ридер однозначно
  • Сообщений: 0
  • Новостей: 0
Как там у вас с погодой? Давно не писали

Огромное спасибо за инфу. Автору респект и уважуха.
Пишет продвижение сайтов, 24 июля 2011 03:23
  • Сообщений: 0
  • Новостей: 0
Очень интересно. Но чего-то не хватает
Пишет Михаил, 26 июля 2011 14:31
  • Сообщений: 0
  • Новостей: 0
Не могу перевести, выходят карякозабры а при смене кодировки приходится обновлять страницу чтобы что то появилось. Как такое решить?
  • Сообщений: 0
  • Новостей: 0
Данный пост реально помог мне принять очень важное для себя решение. За что автору отдельное спасибо. Жду от Вас новых постов!

Чёрт возьми! Круто!
Пишет эвакуатор Жуковский, 28 июля 2011 09:21
  • Сообщений: 0
  • Новостей: 0
Да, такой блог однозначно надо раскручивать сильнее - что б как можно больше людей о нем узнали

Действительно удивили и порадовали Никогда не поверил бы, что даже такое бывает
Пишет эротик костюмы, 29 июля 2011 10:27
  • Сообщений: 0
  • Новостей: 0
Давно искала эту информацию, спасибо.

+1. Подписался.
Пишет aforex, 1 августа 2011 11:51
  • Сообщений: 0
  • Новостей: 0
Где-то я что то подобное уже видел
Пишет Самосвал КАМАЗ, 2 августа 2011 20:43
  • Сообщений: 0
  • Новостей: 0
Согласен, что пост получился удачным. Хорошая работа!
Пишет продвижение неизбежно, 3 августа 2011 02:03
  • Сообщений: 0
  • Новостей: 0
Блин ну почему, почему когда продавщица в магазине нахамит, смешной ответ придумывается только на полпути домой!

Хорошо пишете. Надеюсь, когда-нибудь увижу нечто подобное и на своем блоге…