Tutorial:Hacer un Shoutbox con PHP y jQuery

En este tutorial, vamos a crear un cuadro de mensajes con PHP y jQuery, que permite a los visitantes de su sitio web dejarse comentarios breves entre ellos. Los gritos se almacenarán en el servidor como archivos, no se requerirá una base de datos como MySQL. Vamos a utilizar dos bibliotecas de PHP para facilitar las cosas:Flywheel para almacenar los gritos como archivos json y RelativeTime para crear marcas de tiempo relativas legibles por humanos. Usaremos Composer para instalar estas bibliotecas.

En el lado del cliente, usamos código jQuery sin formato y la biblioteca Emoji One, que es un proyecto gratuito y una biblioteca para agregar lindos emojis a las aplicaciones web. ¡Comencemos!

Ejecutar el shoutbox

Puede obtener el código fuente desde el botón de descarga de arriba. Tiene muchos comentarios y es fácil de seguir. Para ejecutarlo, simplemente cárguelo en su espacio de alojamiento web o agréguelo a la carpeta apache htdocs si ejecuta algo como XAMPP o MAMP. Luego, abra http://localhost en su navegador (o su sitio web, si lo cargó en su espacio de alojamiento). Aquí hay algunas cosas que debe buscar:

  • Los archivos zip ya contienen las dependencias, por lo que no necesita instalar Composer. Esto hace que sea fácil comenzar con el código:¡simplemente cárguelo y utilícelo!
  • Asegúrese de que el directorio data/shouts exista y se pueda escribir. De lo contrario, verá errores en su archivo de registro y no se almacenarán gritos. Es posible que deba cambiarlo a 777 si sigue viendo errores.

El HTML

Comencemos con index.html . Es un documento HTML5 regular, que incluye nuestras bibliotecas JavaScript, scripts y hojas de estilo. Estas son las partes relevantes para el shoutbox:

index.html

<div class="shoutbox">

    <h1>Shout box <img src='./assets/img/refresh.png'/></h1>

    <ul class="shoutbox-content"></ul>

    <div class="shoutbox-form">
        <h2>Write a message <span>×</span></h2>

        <form action="./publish.php" method="post">
            <label for="shoutbox-name">nickname </label> <input type="text" id="shoutbox-name" name="name"/>
            <label class="shoutbox-comment-label" for="shoutbox-comment">message </label> <textarea id="shoutbox-comment" name="comment" maxlength='240'></textarea>
            <input type="submit" value="Shout!"/>
        </form>
    </div>

</div>

Con JavaScript insertaremos los gritos publicados en el elemento

    . El formulario está oculto de forma predeterminada y solo se revela cuando se hace clic en el encabezado "Escribir un mensaje".

    El Código JavaScript

    Y aquí está nuestro script.js , lo que hace que el HTML anterior funcione:

    activos/js/script.js

    $(function(){
    
        // Storing some elements in variables for a cleaner code base
    
        var refreshButton = $('h1 img'),
            shoutboxForm = $('.shoutbox-form'),
            form = shoutboxForm.find('form'),
            closeForm = shoutboxForm.find('h2 span'),
            nameElement = form.find('#shoutbox-name'),
            commentElement = form.find('#shoutbox-comment'),
            ul = $('ul.shoutbox-content');
    
        // Replace :) with emoji icons:
        emojione.ascii = true;
    
        // Load the comments.
        load();
    
        // On form submit, if everything is filled in, publish the shout to the database
    
        var canPostComment = true;
    
        form.submit(function(e){
            e.preventDefault();
    
            if(!canPostComment) return;
    
            var name = nameElement.val().trim();
            var comment = commentElement.val().trim();
    
            if(name.length && comment.length && comment.length < 240) {
    
                publish(name, comment);
    
                // Prevent new shouts from being published
    
                canPostComment = false;
    
                // Allow a new comment to be posted after 5 seconds
    
                setTimeout(function(){
                    canPostComment = true;
                }, 5000);
    
            }
    
        });
    
        // Toggle the visibility of the form.
    
        shoutboxForm.on('click', 'h2', function(e){
    
            if(form.is(':visible')) {
                formClose();
            }
            else {
                formOpen();
            }
    
        });
    
        // Clicking on the REPLY button writes the name of the person you want to reply to into the textbox.
    
        ul.on('click', '.shoutbox-comment-reply', function(e){
    
            var replyName = $(this).data('name');
    
            formOpen();
            commentElement.val('@'+replyName+' ').focus();
    
        });
    
        // Clicking the refresh button will force the load function
    
        var canReload = true;
    
        refreshButton.click(function(){
    
            if(!canReload) return false;
    
            load();
            canReload = false;
    
            // Allow additional reloads after 2 seconds
            setTimeout(function(){
                canReload = true;
            }, 2000);
        });
    
        // Automatically refresh the shouts every 20 seconds
        setInterval(load,20000);
    
        function formOpen(){
    
            if(form.is(':visible')) return;
    
            form.slideDown();
            closeForm.fadeIn();
        }
    
        function formClose(){
    
            if(!form.is(':visible')) return;
    
            form.slideUp();
            closeForm.fadeOut();
        }
    
        // Store the shout in the database
    
        function publish(name,comment){
    
            $.post('publish.php', {name: name, comment: comment}, function(){
                nameElement.val("");
                commentElement.val("");
                load();
            });
    
        }
    
        // Fetch the latest shouts
    
        function load(){
            $.getJSON('./load.php', function(data) {
                appendComments(data);
            });
        }
    
        // Render an array of shouts as HTML
    
        function appendComments(data) {
    
            ul.empty();
    
            data.forEach(function(d){
                ul.append('<li>'+
                    '<span class="shoutbox-username">' + d.name + '</span>'+
                    '<p class="shoutbox-comment">' + emojione.toImage(d.text) + '</p>'+
                    '<div class="shoutbox-comment-details"><span class="shoutbox-comment-reply" data-name="' + d.name + '">REPLY</span>'+
                    '<span class="shoutbox-comment-ago">' + d.timeAgo + '</span></div>'+
                '</li>');
            });
    
        }
    
    });

    La biblioteca Emoji One tiene una versión para JavaScript y PHP. En el método appendComments, usamos la función emojione.toImage() para convertir todos los emoticonos escritos en emoji. Vea todas las funciones compatibles y consulte este práctico sitio web de códigos emoji. Ahora que el frontend está listo, pasemos al backend.

    El código PHP

    Tenemos dos archivos:publicar.php y cargar.php. El primero acepta una solicitud POST para almacenar gritos en el almacén de datos y el segundo devuelve los 20 últimos gritos. Los visitantes no abren estos archivos directamente, solo manejan solicitudes AJAX.

    publicar.php

    <?php
    
    // Include our composer libraries
    require 'vendor/autoload.php';
    
    // Configure the data store
    
    $dir = __DIR__.'/data';
    
    $config = new \JamesMoss\Flywheel\Config($dir, array(
        'formatter' => new \JamesMoss\Flywheel\Formatter\JSON,
    ));
    
    $repo = new \JamesMoss\Flywheel\Repository('shouts', $config);
    
    // Store the posted shout data to the data store
    
    if(isset($_POST["name"]) && isset($_POST["comment"])) {
    
        $name = htmlspecialchars($_POST["name"]);
        $name = str_replace(array("\n", "\r"), '', $name);
    
        $comment = htmlspecialchars($_POST["comment"]);
        $comment = str_replace(array("\n", "\r"), '', $comment);
    
        // Storing a new shout
    
        $shout = new \JamesMoss\Flywheel\Document(array(
            'text' => $comment,
            'name' => $name,
            'createdAt' => time()
        ));
    
        $repo->store($shout);
    
    }

    Aquí usamos directamente la biblioteca Flywheel que mencionamos al principio. Una vez configurado, puede almacenar cualquier tipo de datos, que se escribirán como un archivo JSON en la carpeta de datos/gritos. La lectura de estos gritos se realiza en load.php:

    cargar.php

    <?php
    
    require 'vendor/autoload.php';
    
    // If you want to delete old comments, make this true. We use it to clean up the demo.
    $deleteOldComments = false;
    
    // Setting up the data store
    
    $dir = __DIR__.'/data';
    
    $config = new \JamesMoss\Flywheel\Config($dir, array(
        'formatter' => new \JamesMoss\Flywheel\Formatter\JSON,
    ));
    
    $repo = new \JamesMoss\Flywheel\Repository('shouts', $config);
    
    // Delete comments which are more than 1 hour old if the variable is set to be true.
    
    if($deleteOldComments) {
    
        $oldShouts = $repo->query()
                    ->where('createdAt', '<', strtotime('-1 hour'))
                    ->execute();
    
        foreach($oldShouts as $old) {
            $repo->delete($old->id);
        }
    
    }
    
    // Send the 20 latest shouts as json
    
    $shouts = $repo->query()
            ->orderBy('createdAt ASC')
            ->limit(20,0)
            ->execute();
    
    $results = array();
    
    $config = array(
        'language' => '\RelativeTime\Languages\English',
        'separator' => ', ',
        'suffix' => true,
        'truncate' => 1,
    );
    
    $relativeTime = new \RelativeTime\RelativeTime($config);
    
    foreach($shouts as $shout) {
        $shout->timeAgo = $relativeTime->timeAgo($shout->createdAt);
        $results[] = $shout;
    }
    
    header('Content-type: application/json');
    echo json_encode($results);

    Hemos incluido un código que elimina los gritos de más de una hora. Usamos esta función para mantener limpia la demostración. Puede habilitarlo si lo desea. Después de seleccionar los gritos, también estamos calculando la marca de tiempo relativa legible por humanos con la biblioteca RelativeTime.

    ¡Con esto nuestro shoutbox está listo! Puede incrustarlo en su sitio web, personalizarlo y cambiar el código de la forma que desee. ¡Esperamos que te guste!