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
列。
这是我用于get
和send
将消息输入窗口的 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 jquery-ui - 不会在 Firefox 或 IE 上执行