Post Top Ad

Your Ad Spot

jueves, 7 de mayo de 2020

Creación de un sistema de comentarios y respuestas PHP y MySQL

Un sistema que permita a los usuarios comentar en la publicación de su blog y obtener respuestas de otros usuarios puede aumentar la interactividad y la detención de los usuarios de su sitio web. Nuestro objetivo hoy es crear dicho sistema. En este proyecto, utilizamos la base de datos MySQL para almacenar todos los usuarios, publicaciones, comentarios y respuestas y la relación que existe entre ellos. Luego, nuestra aplicación consultará esta información de la base de datos y la mostrará en la página web. 
Solo los usuarios registrados pueden publicar un comentario en una publicación de blog. Si un usuario visita el sitio y aún no ha iniciado sesión, en lugar de un formulario de comentarios, mostramos un enlace y le pedimos que inicie sesión antes de publicar un comentario. Una vez que inician sesión, pueden publicar su comentario, que se enviará al servidor y se guardará en la base de datos en esa publicación en particular y actualizará la página sin volver a cargarla; utilizaremos JQuery y Ajax para asegurarnos de que se publique un comentario sin necesidad de actualizar toda la página. 
Creo que es una explicación suficiente. Ahora comencemos a codificar.
Cree una carpeta de proyecto llamada comment-reply-system . Haga clic derecho en la siguiente imagen, tome "guardar imagen como" en el menú que aparece; guarde la imagen en la carpeta recién creada como profile.png:
O puede buscar en Google "Imágenes de perfil de Avatar" y descargar cualquiera que elija. Solo asegúrate de cambiarle el nombre a profile.png.
Ahora en la misma carpeta coment-system-php, cree tres archivos, a saber functions.php ,  main.css, post_details.php . Abra post_details.php y agregue este código:
post_details.php:
<?php include('functions.php'); ?>
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Comment and reply system in PHP</title>
 <!-- Bootstrap CSS -->
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
 <link rel="stylesheet" href="main.css">
</head>
<body>
<div class="container">
 <div class="row">
  <div class="col-md-6 col-md-offset-3 post">
   <h2>Post title</h2>
   <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cum nam illum ipsum corporis voluptatibus, perspiciatis possimus vitae consequuntur. Voluptate quisquam reprehenderit sapiente cupiditate esse, consequuntur vel dicta culpa dolorem rerum.</p>
  </div>

  <!-- comments section -->
  <div class="col-md-6 col-md-offset-3 comments-section">
   <!-- comment form -->
   <form class="clearfix" action="index.php" method="post" id="comment_form">
    <h4>Post a comment:</h4>
    <textarea name="comment_text" id="comment_text" class="form-control" cols="30" rows="3"></textarea>
    <button class="btn btn-primary btn-sm pull-right" id="submit_comment">Submit comment</button>
   </form>

   <!-- Display total number of comments on this post  -->
   <h2><span id="comments_count">0</span> Comment(s)</h2>
   <hr>
   <!-- comments wrapper -->
   <div id="comments-wrapper">
    <div class="comment clearfix">
      <img src="profile.png" alt="" class="profile_pic">
      <div class="comment-details">
       <span class="comment-name">Melvine</span>
       <span class="comment-date">Apr 24, 2018</span>
       <p>This is the first reply to this post on this website.</p>
       <a class="reply-btn" href="#" >reply</a>
      </div>
      <div>
       <!-- reply -->
       <div class="comment reply clearfix">
        <img src="profile.png" alt="" class="profile_pic">
        <div class="comment-details">
         <span class="comment-name">Awa</span>
         <span class="comment-date">Apr 24, 2018</span>
         <p>Hey, why are you the first to comment on this post?</p>
         <a class="reply-btn" href="#">reply</a>
        </div>
       </div>
      </div>
     </div>
   </div>
   <!-- // comments wrapper -->
  </div>
  <!-- // comments section -->
 </div>
</div>
<!-- Javascripts -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Bootstrap Javascript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>
En la sección de cabecera, estamos incluyendo functions.php y main.css. Olvídate de functions.php por ahora, lo veremos más adelante. Abra main.css y agregue este código para fines de diseño:
main.css :
form button { margin: 5px 0px; }
textarea { display: block; margin-bottom: 10px; }
/*post*/
.post { border: 1px solid #ccc; margin-top: 10px; }
/*comments*/
.comments-section { margin-top: 10px; border: 1px solid #ccc; }
.comment { margin-bottom: 10px; }
.comment .comment-name { font-weight: bold; }
.comment .comment-date {
 font-style: italic;
 font-size: 0.8em;
}
.comment .reply-btn, .edit-btn { font-size: 0.8em; }
.comment-details { width: 91.5%; float: left; }
.comment-details p { margin-bottom: 0px; }
.comment .profile_pic {
 width: 35px;
 height: 35px;
 margin-right: 5px;
 float: left;
 border-radius: 50%;
}
/*replies*/
.reply { margin-left: 30px; }
.reply_form {
 margin-left: 40px;
 display: none;
}
#comment_form { margin-top: 10px; }
Ahora abra su navegador y vaya a http: //localhost/comment-reply-system/blog_post.php para verlo.http : // localhost comment reply system blog post PHP para verlo.
La información es estática por ahora. Creemos una base de datos para almacenarla.

Base de datos

Cree una base de datos llamada comment-reply-system . En esta base de datos, vamos a crear 4 tablas, a saber: usuarios , publicaciones , comentarios y respuestas .
usuarios:
+----+-----------+------------------------+------------+
|     field      |     type               | specs      |
+----+-----------+------------------------+------------+
|  id            | INT(11)                |            |
|  username      | VARCHAR(255)           | UNIQUE     |
|  email         | VARCHAR(255)           | UNIQUE     |
|  password      | VARCHAR(255)           |            |
|  created_at    | TIMESTAMP              |            |
+----------------+--------------+---------+------------+
publicaciones:
+----+-----------+--------------+------------+
|     field      |     type     | specs      |
+----+-----------+--------------+------------+
|  id            | INT(11)      |            |
|  title         | VARCHAR(255) |            |
|  slug          | VARCHAR(255) | UNIQUE     |
|  body          | TEXT         |            |
|  created_at    | TIMESTAMP    |            |
|  updated_at    | TIMESTAMP    |            |
+----------------+--------------+------------+
comentarios:
+----+-----------+--------------+------------+
|     field      |     type     | specs      |
+----+-----------+--------------+------------+
|  id            | INT(11)      |            |
|  user_id       | INT(11)      |            |
|  post_id       | INT(11)      |            |
|  body          | TEXT         |            |
|  created_at    | TIMESTAMP    |            |
|  updated_at    | TIMESTAMP    |            |
+----------------+--------------+------------+
respuestas:
+----+-----------+--------------+------------+
|     field      |     type     | specs      |
+----+-----------+--------------+------------+
|  id            | INT(11)      |            |
|  user_id       | INT(11)      |            |
|  comment_id    | INT(11)      |            |
|  body          | TEXT         |            |
|  created_at    | TIMESTAMP    |            |
|  updated_at    | TIMESTAMP    |            |
+----------------+--------------+------------+
Así es como se relacionan estas tablas: cada respuesta pertenece a un comentario que pertenece a una publicación que pertenece a un usuario.
¿Espero que no haya sonado demasiado complicado? En cualquier caso, no estamos muy preocupados por la relación entre usuario y publicación por ahora. Simplemente crearemos una sola publicación y demostraremos cómo se relaciona con los comentarios y las respuestas. Si desea obtener más información sobre los usuarios y su relación con las publicaciones, consulte mi tutorial sobre Cómo crear un blog con bases de datos PHP y MySQL.
Ahora vaya a http: //localhost/comment-reply-system/blog_post.php y copie toda la información que se muestra en la página en las tablas de base de datos apropiadas.http : // localhost comment reply system blog post php y copie toda la información que se muestra en la página en las tablas de base de datos apropiadas.
Por ejemplo, cree una publicación en la tabla de publicaciones con un título "Título de publicación" y un cuerpo "Lorem ipsum ..." Además, copie el comentario en esa página en la tabla de comentarios y, por ahora, establezca el campo user_id en valor 1 para el comentario y para la respuesta establezca user_id en el valor 2. 
Ahora reemplacemos el contenido estático en la página web con contenido que ahora consultaremos desde la base de datos. 
Abra el   archivo functions.php que creamos anteriormente y pegue este código en él.
<?php 
 // Set logged in user id: This is just a simulation of user login. We haven't implemented user log in
 // But we will assume that when a user logs in, 
 // they are assigned an id in the session variable to identify them across pages
 $user_id = 1;
 // connect to database
 $db = mysqli_connect("localhost", "root", "", "comment-reply-system");
 // get post with id 1 from database
 $post_query_result = mysqli_query($db, "SELECT * FROM posts WHERE id=1");
 $post = mysqli_fetch_assoc($post_query_result);

 // Get all comments from database
 $comments_query_result = mysqli_query($db, "SELECT * FROM comments WHERE post_id=" . $post['id'] . " ORDER BY created_at DESC");
 $comments = mysqli_fetch_all($comments_query_result, MYSQLI_ASSOC);

 // Receives a user id and returns the username
 function getUsernameById($id)
 {
  global $db;
  $result = mysqli_query($db, "SELECT username FROM users WHERE id=" . $id . " LIMIT 1");
  // return the username
  return mysqli_fetch_assoc($result)['username'];
 }
 // Receives a comment id and returns the username
 function getRepliesByCommentId($id)
 {
  global $db;
  $result = mysqli_query($db, "SELECT * FROM replies WHERE comment_id=$id");
  $replies = mysqli_fetch_all($result, MYSQLI_ASSOC);
  return $replies;
 }
 // Receives a post id and returns the total number of comments on that post
 function getCommentsCountByPostId($post_id)
 {
  global $db;
  $result = mysqli_query($db, "SELECT COUNT(*) AS total FROM comments");
  $data = mysqli_fetch_assoc($result);
  return $data['total'];
 }
Ahora abra post_details.php y actualícelo para que se vea así (reemplace todo el código con esto):
<?php include('functions.php'); ?>
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Comment and reply system in PHP</title>
 <!-- Bootstrap CSS -->
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
 <link rel="stylesheet" href="main.css">
</head>
<body>
<div class="container">
 <div class="row">
  <div class="col-md-6 col-md-offset-3 post">
   <h2><?php echo $post['title'] ?></h2>
   <p><?php echo $post['body']; ?></p>
  </div>
  <div class="col-md-6 col-md-offset-3 comments-section">
   <!-- if user is not signed in, tell them to sign in. If signed in, present them with comment form -->
   <?php if (isset($user_id)): ?>
    <form class="clearfix" action="post_details.php" method="post" id="comment_form">
     <textarea name="comment_text" id="comment_text" class="form-control" cols="30" rows="3"></textarea>
     <button class="btn btn-primary btn-sm pull-right" id="submit_comment">Submit comment</button>
    </form>
   <?php else: ?>
    <div class="well" style="margin-top: 20px;">
     <h4 class="text-center"><a href="#">Sign in</a> to post a comment</h4>
    </div>
   <?php endif ?>
   <!-- Display total number of comments on this post  -->
   <h2><span id="comments_count"><?php echo count($comments) ?></span> Comment(s)</h2>
   <hr>
   <!-- comments wrapper -->
   <div id="comments-wrapper">
   <?php if (isset($comments)): ?>
    <!-- Display comments -->
    <?php foreach ($comments as $comment): ?>
    <!-- comment -->
    <div class="comment clearfix">
     <img src="profile.png" alt="" class="profile_pic">
     <div class="comment-details">
      <span class="comment-name"><?php echo getUsernameById($comment['user_id']) ?></span>
      <span class="comment-date"><?php echo date("F j, Y ", strtotime($comment["created_at"])); ?></span>
      <p><?php echo $comment['body']; ?></p>
      <a class="reply-btn" href="#" data-id="<?php echo $comment['id']; ?>">reply</a>
     </div>
     <!-- reply form -->
     <form action="post_details.php" class="reply_form clearfix" id="comment_reply_form_<?php echo $comment['id'] ?>" data-id="<?php echo $comment['id']; ?>">
      <textarea class="form-control" name="reply_text" id="reply_text" cols="30" rows="2"></textarea>
      <button class="btn btn-primary btn-xs pull-right submit-reply">Submit reply</button>
     </form>

     <!-- GET ALL REPLIES -->
     <?php $replies = getRepliesByCommentId($comment['id']) ?>
     <div class="replies_wrapper_<?php echo $comment['id']; ?>">
      <?php if (isset($replies)): ?>
       <?php foreach ($replies as $reply): ?>
        <!-- reply -->
        <div class="comment reply clearfix">
         <img src="profile.png" alt="" class="profile_pic">
         <div class="comment-details">
          <span class="comment-name"><?php echo getUsernameById($reply['user_id']) ?></span>
          <span class="comment-date"><?php echo date("F j, Y ", strtotime($reply["created_at"])); ?></span>
          <p><?php echo $reply['body']; ?></p>
          <a class="reply-btn" href="#">reply</a>
         </div>
        </div>
       <?php endforeach ?>
      <?php endif ?>
     </div>
    </div>
     <!-- // comment -->
    <?php endforeach ?>
   <?php else: ?>
    <h2>Be the first to comment on this post</h2>
   <?php endif ?>
   </div><!-- comments wrapper -->
  </div><!-- // all comments -->
 </div>
</div>
<!-- Javascripts -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Bootstrap Javascript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>

<script src="scripts.js"></script>
</body>
</html>
Actualiza la página en el navegador. Si hizo todo correctamente, verá datos similares en su navegador como antes, pero esta vez provienen de la base de datos. 
Ahora escribamos código para agregar un comentario. Como dije antes, haremos eso con JQuery y Ajax; entonces el comentario enviado al servidor, almacenado en la base de datos y la página actualizada para mostrar el comentario recién creado sin volver a cargar la página.
Cree un archivo llamado scripts.js en la carpeta raíz del proyecto y agregue este código dentro de él:
scripts.js :
$(document).ready(function(){
 // When user clicks on submit comment to add comment under post
 $(document).on('click', '#submit_comment', function(e) {
  e.preventDefault();
  var comment_text = $('#comment_text').val();
  var url = $('#comment_form').attr('action');
  // Stop executing if not value is entered
  if (comment_text === "" ) return;
  $.ajax({
   url: url,
   type: "POST",
   data: {
    comment_text: comment_text,
    comment_posted: 1
   },
   success: function(data){
    var response = JSON.parse(data);
    if (data === "error") {
     alert('There was an error adding comment. Please try again');
    } else {
     $('#comments-wrapper').prepend(response.comment)
     $('#comments_count').text(response.comments_count); 
     $('#comment_text').val('');
    }
   }
  });
 });
 // When user clicks on submit reply to add reply under comment
 $(document).on('click', '.reply-btn', function(e){
  e.preventDefault();
  // Get the comment id from the reply button's data-id attribute
  var comment_id = $(this).data('id');
  // show/hide the appropriate reply form (from the reply-btn (this), go to the parent element (comment-details)
  // and then its siblings which is a form element with id comment_reply_form_ + comment_id)
  $(this).parent().siblings('form#comment_reply_form_' + comment_id).toggle(500);
  $(document).on('click', '.submit-reply', function(e){
   e.preventDefault();
   // elements
   var reply_textarea = $(this).siblings('textarea'); // reply textarea element
   var reply_text = $(this).siblings('textarea').val();
   var url = $(this).parent().attr('action');
   $.ajax({
    url: url,
    type: "POST",
    data: {
     comment_id: comment_id,
     reply_text: reply_text,
     reply_posted: 1
    },
    success: function(data){
     if (data === "error") {
      alert('There was an error adding reply. Please try again');
     } else {
      $('.replies_wrapper_' + comment_id).append(data);
      reply_textarea.val('');
     }
    }
   });
  });
 });
});
Este archivo contiene las llamadas ajax. Ahora abra functions.php y agregue este código al final del archivo para procesar las llamadas ajax.
funciones.php:
//...
// If the user clicked submit on comment form...
if (isset($_POST['comment_posted'])) {
 global $db;
 // grab the comment that was submitted through Ajax call
 $comment_text = $_POST['comment_text'];
 // insert comment into database
 $sql = "INSERT INTO comments (post_id, user_id, body, created_at, updated_at) VALUES (1, " . $user_id . ", '$comment_text', now(), null)";
 $result = mysqli_query($db, $sql);
 // Query same comment from database to send back to be displayed
 $inserted_id = $db->insert_id;
 $res = mysqli_query($db, "SELECT * FROM comments WHERE id=$inserted_id");
 $inserted_comment = mysqli_fetch_assoc($res);
 // if insert was successful, get that same comment from the database and return it
 if ($result) {
  $comment = "<div class='comment clearfix'>
     <img src='profile.png' alt='' class='profile_pic'>
     <div class='comment-details'>
      <span class='comment-name'>" . getUsernameById($inserted_comment['user_id']) . "</span>
      <span class='comment-date'>" . date('F j, Y ', strtotime($inserted_comment['created_at'])) . "</span>
      <p>" . $inserted_comment['body'] . "</p>
      <a class='reply-btn' href='#' data-id='" . $inserted_comment['id'] . "'>reply</a>
     </div>
     <!-- reply form -->
     <form action='post_details.php' class='reply_form clearfix' id='comment_reply_form_" . $inserted_comment['id'] . "' data-id='" . $inserted_comment['id'] . "'>
      <textarea class='form-control' name='reply_text' id='reply_text' cols='30' rows='2'></textarea>
      <button class='btn btn-primary btn-xs pull-right submit-reply'>Submit reply</button>
     </form>
    </div>";
  $comment_info = array(
   'comment' => $comment,
   'comments_count' => getCommentsCountByPostId(1)
  );
  echo json_encode($comment_info);
  exit();
 } else {
  echo "error";
  exit();
 }
}
// If the user clicked submit on reply form...
if (isset($_POST['reply_posted'])) {
 global $db;
 // grab the reply that was submitted through Ajax call
 $reply_text = $_POST['reply_text']; 
 $comment_id = $_POST['comment_id']; 
 // insert reply into database
 $sql = "INSERT INTO replies (user_id, comment_id, body, created_at, updated_at) VALUES (" . $user_id . ", $comment_id, '$reply_text', now(), null)";
 $result = mysqli_query($db, $sql);
 $inserted_id = $db->insert_id;
 $res = mysqli_query($db, "SELECT * FROM replies WHERE id=$inserted_id");
 $inserted_reply = mysqli_fetch_assoc($res);
 // if insert was successful, get that same reply from the database and return it
 if ($result) {
  $reply = "<div class='comment reply clearfix'>
     <img src='profile.png' alt='' class='profile_pic'>
     <div class='comment-details'>
      <span class='comment-name'>" . getUsernameById($inserted_reply['user_id']) . "</span>
      <span class='comment-date'>" . date('F j, Y ', strtotime($inserted_reply['created_at'])) . "</span>
      <p>" . $inserted_reply['body'] . "</p>
      <a class='reply-btn' href='#'>reply</a>
     </div>
    </div>";
  echo $reply;
  exit();
 } else {
  echo "error";
  exit();
 }
}

No hay comentarios.:

Publicar un comentario

Dejanos tu comentario para seguir mejorando!

outbrain

Páginas