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

Posted

技术标签:

【中文标题】PHP/Ajax 简单聊天 - 将管理员用户名颜色设置为红色【英文标题】:PHP/Ajax simple chat - set admin username color to red 【发布时间】:2020-12-18 13:44:33 【问题描述】:

我有一个简单的 php/Ajax 聊天应用程序,它允许用户在统一的聊天窗口中相互交谈。我希望角色为“管理员”的用户在聊天窗口中的用户名显示为红色,无论谁登录。

这是用户表的列:

这是消息表列:

我拥有会话中用户表中的用户名和角色 - $_SESSION['name']$_SESSION['role'] - 并且 $_SESSION['name'] 写入消息表中的 user 列。

这是我用于getsend 将消息输入窗口的 PHP 切换语句:

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

我的想法是我需要将消息表中的用户与用户表中的用户名匹配,检查角色,然后在聊天窗口中突出显示用户名,但我不知道从哪里开始。我将继续尝试在 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']]);

【问题讨论】:

我认为在获取数据后,您可以检查role="Admin" 是否存在,那么您就不需要在查询中添加role = :role 条件。 与消息一起,像这样从数据库中获取用户角色 - $sql = 'SELECT m.*, u.role FROM message m INNER JOIN users u ON m.user = u.username WHERE u.role = :role AND u.username = :username';。我假设您将用户角色存储在“用户”表中。然后在您的 switch case 语句中 - case "getMessages": - 您可以检查用户角色是否为管理员,将其设为红色 - 可能正在使用 css .. 请勿发文字图片 @Strawberry - 我在数据库中发布了列的图片 - 以前有人问过我 - 有什么问题? @Swati - 好点 - 谢谢。 【参考方案1】:

首先尝试改用 fetchObject 并迭代直到它返回 false。 这种方法占用的内存更少且速度更快,因为您创建了一个数组而不是数组和字符串。

这样加“[admin]”是可以的,但是你有重复的代码。 如果您将来想在此代码中更改某些内容,那将会很痛苦。 例如。当您想更改“单消息”类名时,您必须在两个地方进行。 第二个错误是使用 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 中显示在客户端 :)

【讨论】:

我知道有更好的方法 - 应该考虑使用 while 循环 - 谢谢。至于另一种方式——我喜欢你所说的——但是——我不太明白你的意思——我对 PHP 的理解很好,并且刚刚开始学习 javascript。你能扩展你的评论吗? @SteveShead 抱歉在我的代码中我丢失了声明:) 在循环之后,请添加: header("Content-Type: application/json");回声 json_encode($messages);死();现在在您的 javascript 中,您将获得 json 数组而不是 html 代码。接下来遍历这个数组并在你的 html 代码中创建 DOM 节点,方法是将消息作为子项插入到#chat 容器中。【参考方案2】:

在对 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] 而不是更改文本颜色 - 似乎对用户更加友好。

【讨论】:

以上是关于PHP/Ajax 简单聊天 - 将管理员用户名颜色设置为红色的主要内容,如果未能解决你的问题,请参考以下文章

php+ajax长轮询实现web即时聊天

php+ajax长轮询实现web即时聊天

node.js + socket.io 聊天群聊系统

表单提交 - php ajax jquery-ui - 不会在 Firefox 或 IE 上执行

Android - Firebase - 将用户发送到聊天室

如何开发一个简单的聊天APP?