Ich fürchte, das ist nicht ganz leicht zu erklären. Unabhängig davon ist ein Gegenargument, dass du mit htmlentities gezwungen bist, allen Text mit HTML-Entities ("<" statt "<" usw.) in der Datenbank stehen zu haben, was sicher in manchen Fällen problematisch ist. In der Datenbank sollten nach Möglichkeit die Originaldaten stehen, da nur so Flexibilität hinsichtlich des Ausgabeformats gewährleistet ist.
Ansonsten lies mal diesen Blogeintrag:
Chris Shiflett: addslashes() Versus mysql_real_escape_string()
Was hier über verschiedene Charsets für addslashes gezeigt wird, könnte auch für htmlentities gelten. (Ich weiß es ehrlich nicht.) Für mysql_real_escape_string gilt es nicht, da diese Funktion eine Datenbankverbindung voraussetzt und deshalb auch das korrekte Charset kennt und umsetzen kann.
Zudem heißt es im Handbuch:
mysql_real_escape_string() calls MySQL's library function mysql_real_escape_string, which prepends backslashes to the following characters: \x00, \n, \r, \, ', " and \x1a.
Ich weiß auch hier nicht, ob htmlentities etwas Vergleichbares mit den entsprechenden Zeichen anstellt bzw. ob sich mögliche Angriffspunkte ergeben, wenn htmlentities das nicht tut.
Es könnte sein, dass all das (zufällig oder nicht) niemals zu Problemen führen wird, aber es könnte auch nicht sein.
Was ich aber definitiv sagen kann: htmlentities ist nicht dafür gedacht, Werte für Datenbankabfragen zu escapen. Die Funktion ist dafür gedacht, Werte für die Ausgabe als HTML aufzubereiten.
Das mag keine besonders tolle Begründung sein, aber du benutzt schließlich auch nicht... sagen wir... base64encode, um Werte für SQL-Queries aufzubereiten. Das wäre prinzipiell dasselbe wie htmlentities.
Edit: Noch einmal anders gesagt: Wenn htmlentities ausreicht, um den Job von mysql_real_escape_string zu erfüllen, ist das nicht mehr als Zufall. Diese Funktion ist definitiv nicht dazu vorgesehen.