我有用 PHP 编写的 Web 应用程序,我想为我的 Web 应用程序构建一个实时聊天模块,我想使用 firebase,但我无法弄清楚如何使用 fir-base 构建聊天和PHP 让我的所有用户都可以一对一聊天,我知道我必须将所有用户同步到 firebase 数据库才能在他们之间进行聊天,但它如何与 PHP 一起工作。如果有人以前这样做过,请帮助我。 这是我在 Codelab 上找到的,但它仅适用于 node.js 有人可以建议我如何使用 php 做到这一点吗?
https://codelabs.developers.google.com/codelabs/firebase-web/#0
您可以使用 Firebase PHP 客户端,它基于 Firebase REST API。
对于
websocket
,请使用 棘轮。 Ratchet 是一个松散耦合的 PHP 库,为开发人员提供了通过 WebSocket 在客户端和服务器之间创建实时、双向应用程序的工具。
我想您正在谈论 Firebase,因为您需要保留一些数据。 Firebase 是其中的一个解决方案。
所以我认为您需要数据持久性来保存聊天历史记录。如果不是,那么这是一个 XY 问题:您应该解释您的首要需求是什么,而不谈论任何解决方案。
仅使用 websocket 服务器,您应该能够安装聊天服务器,而不需要数据库。您可以在网络上看到多个聊天服务器示例,但 RatchetPHP (http://socketo.me/docs/hello-world) 是一个很好的解决方案。另请参阅 reddit 主题以获取其他一些解决方案:https://www.reddit.com/r/PHP/comments/5unai8/ratchet_php_websockets/
但是如果您需要历史记录,您可以将其保存在数据库中或仅保存在简单的日志文件中,具体取决于您是否需要执行一些获取、排序、聚合操作。
或者,如果您的网站只需要一个聊天模块,更简单的解决方案是嵌入 IRC 小部件:https://kiwiirc.com/embedding
jQuery(document).ready(function ($) {
var senderId = $("#senderId").val();
var receiverId = $("#receiverId").val();
const { database, ref, onValue } = window.firebaseData;
console.log(window.firebaseData);
console.log(onValue);
const chatRef1 = ref(
database,
"chats/" + senderId + "/" + senderId + "_to_" + receiverId
);
const chatRef2 = ref(
database,
"chats/" + receiverId + "/" + receiverId + "_to_" + senderId
);
console.log(chatRef1.toString());
console.log(chatRef2.toString());
onValue(
chatRef1,
(snapshot) => {
console.log("Value Changed 1");
console.log("ChatRef1 snapshot received");
const messages = snapshot.val();
console.log(messages);
},
(error) => {
console.error("Error in ChatRef1:", error);
}
);
onValue(chatRef2, (snapshot) => {
console.log("Value Changed 2");
const messages = snapshot.val();
console.log("Messages from receiver to sender:", messages);
updateChatUI(messages);
});
function updateChatUI(messages) {
const chatMessagesContainer = $("#chatMessages");
chatMessagesContainer.empty();
$.each(messages, function (key, message) {
var messageHtml = "";
var timeToDisplay = message.strTime || "Invalid time";
if (message.senderId == senderId) {
if (message.message && message.message.trim() !== "") {
messageHtml += `
<div class="chat-message d-flex justify-content-end mb-3">
<div>
<div class="bg-primary text-white rounded p-2">
<p class="mb-0">${message.message}</p>
</div>
<small class="text-muted text-end d-block">${timeToDisplay}</small>
</div>
</div>
`;
}
if (message.attachments && message.attachments.length > 0) {
messageHtml +=
'<div class="chat-attachments d-flex justify-content-end mb-3">';
message.attachments.forEach(function (attachment) {
messageHtml +=
'<img src="' +
attachment +
'" class="chat-image" style="height:100px;width:100px;"/>';
});
messageHtml += `</div><small class="text-muted text-end d-block">${timeToDisplay}</small>`;
}
} else {
if (message.message && message.message.trim() !== "") {
messageHtml += `
<div class="chat-message d-flex mb-3">
<div class="me-auto">
<div class="bg-light rounded p-2">
<p class="mb-0">${message.message}</p>
</div>
<small class="text-muted">${timeToDisplay}</small>
</div>
</div>
`;
}
if (
message.attachments &&
Array.isArray(message.attachments) &&
message.attachments.length > 0
) {
messageHtml += '<div class="chat-attachments d-flex mb-3">';
message.attachments.forEach(function (attachment) {
messageHtml +=
'<img src="' +
attachment +
'" class="chat-image" style="height:100px;width:100px;"/>';
});
messageHtml += `</div><small class="text-muted">${timeToDisplay}</small>`;
}
}
chatMessagesContainer.append(messageHtml);
});
$(".card-body").scrollTop($(".card-body")[0].scrollHeight);
}
loadMessages();
function loadMessages() {
$.ajax({
url: ajaxObject.ajaxUrl,
type: "POST",
data: {
action: "load_messages",
senderId: senderId,
receiverId: receiverId,
},
success: function (response) {
if (response.success) {
var messages = response.data;
updateChatUI(messages);
} else {
console.log("Error: No messages");
}
},
error: function () {
console.error("Error occurred while fetching messages.");
},
});
}
$("#form_data").on("submit", function (e) {
e.preventDefault();
var formData = new FormData(this);
formData.append("action", "send_chat_message");
var message = $("#chatInput").val().trim();
var files = $("#gallery-photo-add")[0].files;
if (message === "" && files.length === 0) {
$(".alert")
.removeClass("alert-success")
.addClass("alert-danger")
.empty()
.text("Please type a message before sending.");
$("html, body").animate(
{
scrollTop: 0,
},
"fast"
);
return;
}
$.ajax({
url: ajaxObject.ajaxUrl,
type: "POST",
data: formData,
processData: false,
contentType: false,
success: function (response) {
$("#chatInput").val("");
$("#gallery-photo-add").val("");
$("#gallery").empty();
},
error: function () {
$(".alert")
.removeClass("alert-success")
.addClass("alert-danger")
.empty()
.text("Error occurred while sending the message.");
},
});
});
$(".btn-attachment").on("click", function (e) {
e.preventDefault();
$("#gallery-photo-add").click();
});
$(function () {
let filesArray = [];
function updateInputField(input, files) {
input.value = "";
const dataTransfer = new DataTransfer();
files.forEach((file) => dataTransfer.items.add(file));
input.files = dataTransfer.files;
}
function displayImages(input, placeToInsertImagePreview) {
const gallery = $(placeToInsertImagePreview);
gallery.empty();
filesArray.forEach((file, index) => {
const reader = new FileReader();
const currentIndex = index;
reader.onload = function (event) {
console.log("index=" + currentIndex);
const wrapper = $("<div>")
.addClass("image-wrapper")
.attr("data-flag", currentIndex);
$("<img>")
.attr("src", event.target.result)
.attr("height", "100px")
.attr("width", "100px")
.appendTo(wrapper);
$("<button>")
.addClass("btn-close")
.css("background-color", "red")
.on("click", function (e) {
e.preventDefault();
filesArray.splice(currentIndex, 1);
updateInputField(input, filesArray);
displayImages(input, placeToInsertImagePreview);
})
.appendTo(wrapper);
wrapper.appendTo(gallery);
};
reader.readAsDataURL(file);
});
}
$("#gallery-photo-add").on("change", function (e) {
e.preventDefault();
filesArray = Array.from(this.files);
console.log(filesArray);
if (filesArray.length > 5) {
Swal.fire({
text: "Please Select only 5 images",
title: "Error",
icon: "error",
});
filesArray = [];
this.value = "";
return;
}
displayImages(this, "#gallery");
});
});
$(document).on("click", ".image-wrapper", function () {
$(".image-wrapper").removeClass("addBorder");
$(this).addClass("addBorder");
var flag = $(this).data("flag");
$(".featured_image_key").val("").val(flag);
});
});
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<?php
if ($_SERVER['REQUEST_METHOD'] == "GET") {
$senderId = isset($_GET['senderId']) ? absint($_GET['senderId']) : 0;
$receiverId = isset($_GET['receiverId']) ? absint($_GET['receiverId']) : 0;
$receiver = get_userdata($receiverId);
$receiver_photo = wp_get_attachment_url(get_user_meta($receiverId, 'profile_image', true), 'thumbnail');
$receiverPhoto = !empty($receiver_photo) ? $receiver_photo : get_avatar_url($receiverId);
}
?>
<div class="container my-2">
<div class="alert"></div>
<div class="card shadow-lg">
<div class="card-header d-flex align-items-center">
<img src="#" alt="Receiver Image"
class="rounded-circle me-3" style="width: 50px; height: 50px;">
<div>
<h5 class="mb-0">Receiver Name</h5>
<small class="text-muted">Chat with {Name}</small>
</div>
</div>
<div class="card-body" id="chatMessages">
</div>
<div class="card-footer mb-3">
<form id="form_data">
<input type="hidden" name="senderId" id="senderId" value="<?php echo $senderId ?>" />
<input type="hidden" name="receiverId" id="receiverId" value="<?php echo $receiverId ?>" />
<div id="gallery"></div>
<input type="file" id="gallery-photo-add" name="images[]" multiple><br>
<div class="d-flex">
<input type="text" class="form-control me-2" name="message" placeholder="Type a message..." id="chatInput">
<button class="btn btn-attachment btn-outline-secondary mx-2"><i class=" bi bi-paperclip"></i></button>
<button type="submit" class="btn btn-primary" id="sendMessageButton">Send</button>
</div>
</form>
</div>
</div>
</div>
<script type="module">
import {
initializeApp
} from "https://www.gstatic.com/firebasejs/9.17.1/firebase-app.js";
import {
getDatabase,
ref,
onValue
} from "https://www.gstatic.com/firebasejs/9.17.1/firebase-database.js";
const firebaseConfig = {
apiKey: "AIzaSyDUciGPOL9Mg5R9aoelFMvgigNYIB3xj2M",
authDomain: "my-chatbot-project-48653.firebaseapp.com",
databaseURL: "https://my-chatbot-project-48653-default-rtdb.asia-southeast1.firebasedatabase.app",
projectId: "my-chatbot-project-48653",
storageBucket: "my-chatbot-project-48653.firebasestorage.app",
messagingSenderId: "1059953390534",
appId: "1:1059953390534:web:9a516a6a400129ae7df8c7",
measurementId: "G-FPVQDFGZSG"
};
const app = initializeApp(firebaseConfig);
const database = getDatabase(app);
window.firebaseData = {
app,
database,
ref,
onValue
};
const dbRef = ref(database, 'path/to/data');
onValue(dbRef, (snapshot) => {
console.log(snapshot.val());
});
</script>