PHP/Ajax 简单聊天 - 将管理员用户名颜色设置为红色

PHP/Ajax simple chat - set admin username color to red

我有一个简单的 PHP/Ajax 聊天应用程序,允许用户在统一聊天 window 中相互交谈。我希望具有角色 'admin' 的用户在聊天 window 中将其用户名显示为红色,无论谁登录。

这是用户 table 列:

这里是 table 列的消息:

我在一个会话中有用户 table 的用户名和角色 - $_SESSION['name']$_SESSION['role'] - $_SESSION['name'] 写入 user消息中的列 table.

这是我用来 getsend 消息到 window:

的 PHP switch 语句
switch( $_REQUEST['action'] ) {
        case "sendMessage":
            $stmt = $pdo->prepare("INSERT INTO messages SET user = ?, message = ?");
            $run = $stmt->execute([$_SESSION['name'], $_REQUEST['message']]);

            if ( $run ) {
                echo 1;
                exit;
            }
        break;
        case "getMessages":
            $stmt = $pdo->prepare("SELECT * FROM messages");
            $run = $stmt->execute();
            $results = $stmt->fetchAll(PDO::FETCH_OBJ);

            $chat = '';
            foreach($results as $message){
                $chat .= '<div class="single-message border">
                            <strong class="text-uppercase">'.$message->user.': </strong>
                            <p> '.$message->message.'</p>
                            <span class="float-right">'.date('h:i a', strtotime($message->date)).'</span>
                          </div>';
            }
            echo $chat;
        break;

作为参考,这里是 ajax:

LoadChat();

setInterval(function(){
    LoadChat();
}, 1000);

function LoadChat() {
    $.post('handlers/messages.php?action=getMessages', function(response){

        var scrollpos = $('#chat').scrollTop();
        var scrollpos = parseInt(scrollpos) + 520;
        var scrollHeight = $('#chat').prop('scrollHeight');

        $('#chat').html(response);
        if( scrollpos < scrollHeight ){

        } else {
            $('#chat').scrollTop( $('#chat').prop('scrollHeight') );
        }
    });
}

$('.textarea').keyup(function(e){
    if( e.which == 13 ) {
        $('form').submit();
    }
});

$('form').submit(function(){
    var message = $('.textarea').val();
    $.post('handlers/messages.php?action=sendMessage&message='+message, function(response){
        if( response == 1) {
            LoadChat();
            document.getElementById("messageFrm").value = "";
        }
    });
    return false;
});

我的想法是我需要将消息 table 中的用户与用户 table 的用户名进行匹配,检查角色,然后在聊天中突出显示用户名 window,但我不知道从哪里开始。我将继续尝试在 sql 语句中使用内部联接,但我对如何表达它感到困惑。

这是不正确的(也是我感到困惑的地方),但这是我的起点:

$sql = 'SELECT * FROM message m INNER JOIN users u ON m.user = u.username WHERE role = :role AND u.username = :username';
$stmt = $pdo->prepare($sql);
$stmt->execute([ 'role' => "$_SESSION['role']", 'username' => $_SESSION['name']]);

在对 sql 语句进行了更多思考之后,并在此处发帖的人们的帮助下,这就是我解决问题的方法。如果有更优雅(正确)的方法,请告诉我。我将 getMessages switch 语句更改为:

case "getMessages":

            $stmt = $pdo->prepare('SELECT m.*, u.role FROM messages m INNER JOIN users u ON m.user = u.username');
            $stmt->execute();
            $results = $stmt->fetchAll(PDO::FETCH_OBJ);

            $chat = '';
            foreach($results as $message) {
                if ($message->role == 'Admin') {
                    $chat .= '<div class="single-message border">
                        <strong class="text-uppercase">' . $message->user . ': </strong>[admin]
                        <p> ' . $message->message . '</p>
                        <span class="float-right">' . date('h:i a', strtotime($message->date)) . '</span>
                      </div>';
                } else {
                    $chat .= '<div class="single-message border">
                        <strong class="text-uppercase">' . $message->user . ': </strong>
                        <p> ' . $message->message . '</p>
                        <span class="float-right">' . date('h:i a', strtotime($message->date)) . '</span>
                      </div>';
                }
            }
            echo $chat;
        break;

如果有更简单的方法,请告诉我。请注意,我选择用 [admin] 附加用户名而不是更改文本颜色 - 看起来更用户友好。

首先尝试使用 fetchObject 并迭代直到它 returns false。
这种方法更少 memory-intensive 并且更快,因为您创建一个数组而不是数组和字符串。

这样加“[admin]”是可以的,但是你重复了代码。 如果你想在未来更改此代码中的某些内容,那将会很痛苦。 例如。当您想更改“single-message”class 名称时,您必须在两个地方进行。 第二个错误是在获取的数组中使用 fetchAll 和迭代。

这段代码应该更好:

case "getMessages":

            $stmt = $pdo->prepare('SELECT m.*, u.role FROM messages m INNER JOIN users u ON m.user = u.username');
            $stmt->execute();

            $chat = '';
            while( $message = $stmt->fetchObject() ) {
                $admin = "";
                if ($message->role == 'Admin') {
                    $admin = "[admin]";
                }
                    $chat .= '<div class="single-message border">
                        <strong class="text-uppercase">' . $message->user . '</strong>'
                       . $admin . '<p> ' . $message->message . '</p>
                        <span class="float-right">' . date('h:i a', strtotime($message->date)) . '</span>
                      </div>';

            }
            echo $chat;
        break;

另一方面,你可以做得更好。
考虑在客户端呈现您的 GUI。
而是从 getMessages 返回 html 代码,构建消息对象数组并将其作为 JSON.
发送 这是更好的方法,因为在这种情况下 PHP 仅负责生成数据,而不负责布局。
当你想改变布局时,在客户端改变它。
代码将更清晰和分离。应用程序的每个部分都有自己的责任。

$stmt = $pdo->prepare('SELECT m.*, u.role FROM messages m INNER JOIN users u ON m.user = u.username');
$stmt->execute();

$messages = [];
while ($message = $stmt->fetchObject()) {
    $message->date_formatted = date('h:i a', strtotime($message->date));
    $messages[] = $message;
}

我想你会知道如何从 JSON 中提取数据并将其显示在 javascript 的客户端:)