Anda tidak menggunakan bind_param, sesuai dengan paradigma pernyataan yang disiapkan.
Dalam pilihan Anda:
$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();
Dan dalam pembaruan Anda:
$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();
Di atas memungkinkan pernyataan yang Anda siapkan untuk menerima parameter dalam format string berparameter (menggunakan "?" untuk mewakili param), dan untuk menerima param dengan informasi tipe, melalui metode bind_param().
Hal ini memungkinkan mesin DB untuk melakukan cast dan escape params dengan benar sebelum mengeksekusi kueri Anda.
Tidak ada gunanya menggunakan pernyataan yang sudah disiapkan jika Anda tidak mengikat params, itulah sebabnya Anda mendapatkan peringatan itu.
Di samping catatan, penggabungan kueri (seperti yang Anda lakukan di atas) adalah kebiasaan yang sangat buruk - ini membuka Anda untuk Injeksi SQL
Lihat dokumen untuk info lebih lanjut tentang pernyataan yang disiapkan:
http://php.net/manual/en/mysqli-stmt.prepare .php