Vous n'utilisez pas bind_param, conformément au paradigme de l'instruction préparée.
Dans votre sélection :
$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();
Et dans votre mise à jour :
$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();
Ce qui précède permet à votre instruction préparée d'accepter des paramètres dans le format de chaîne paramétrée (en utilisant "?" pour représenter un paramètre), et d'accepter des paramètres avec des informations de type, via la méthode bind_param().
Cela permet au moteur de base de données de convertir et d'échapper correctement les paramètres avant d'exécuter votre requête.
Il ne sert à rien d'utiliser des instructions préparées si vous ne liez pas de paramètres, ce qui explique probablement pourquoi vous recevez cet avertissement.
En passant, la concaténation des requêtes (comme vous le faites ci-dessus) est une très mauvaise habitude - elle vous ouvre à Injection SQL
Consultez la documentation pour plus d'informations sur les instructions préparées :
http://php.net/manual/en/mysqli-stmt.prepare .php