Du bruger ikke bind_param i henhold til det forberedte sætningsparadigme.
I dit valg:
$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();
Og i din opdatering:
$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();
Ovenstående tillader din forberedte sætning at acceptere parametre i det parametriserede strengformat (ved at bruge "?" til at repræsentere en param), og at acceptere params med typeinformation via bind_param() metoden.
Dette gør det muligt for DB-motoren at caste og escape-parameter korrekt, før du udfører din forespørgsel.
Det nytter ikke noget at bruge forberedte erklæringer, hvis du ikke binder parametre, hvilket sandsynligvis er grunden til, at du får den advarsel.
Som en sidebemærkning er sammenkædning af forespørgsler (som du gør ovenfor) en meget dårlig vane - det åbner dig for SQL-injektion
Se dokumenterne for mere information om udarbejdede erklæringer:
http://php.net/manual/en/mysqli-stmt.prepare .php