Bạn không sử dụng bind_param, theo mô hình câu lệnh đã chuẩn bị.
Theo lựa chọn của bạn:
$sql = "SELECT id,msg,time,msg.from,msg.to
FROM msg
WHERE msg.from IN (?, ?)
AND msg.to IN (?, ?)
ORDER BY time";
$ex = $conn->prepare($sql);
$ex->bind_param("s", $_SESSION["username"]);
$ex->bind_param("s", $_SESSION["tousermessage"]);
$ex->bind_param("s", $_SESSION["username"]);
$ex->bind_param("s", $_SESSION["tousermessage"]);
$ex->execute();
Và trong bản cập nhật của bạn:
$sql = "UPDATE msg
SET readmsg=1
WHERE id = ?
AND msg = ?";
$ex1 = $conn->prepare($sql);
$ex1->bind_param("i", $result['id']);
$ex1->bind_param("s", $result["msg"]);
$ex1->execute();
Ở trên cho phép câu lệnh đã chuẩn bị của bạn chấp nhận các tham số ở định dạng chuỗi được tham số hóa (sử dụng "?" Để đại diện cho một tham số) và chấp nhận các tham số với thông tin kiểu, thông qua phương thức bind_param ().
Điều này cho phép công cụ DB truyền và thoát các tham số một cách chính xác trước khi thực hiện truy vấn của bạn.
Sẽ không có ích gì khi bạn sử dụng các câu lệnh đã chuẩn bị sẵn nếu bạn không ràng buộc các tham số, đó có thể là lý do tại sao bạn nhận được cảnh báo đó.
Lưu ý nhỏ, việc nối các truy vấn (như bạn đang làm ở trên) là một thói quen rất xấu - nó mở ra cho bạn SQL Injection
Xem tài liệu để biết thêm thông tin về các báo cáo đã chuẩn bị:
http://php.net/manual/en/mysqli-stmt.prepare .php