htmlspecialchars() is sufficient to escape text for browsers. This will protect other site users from XSS attacks.
However, I would only run this function when displaying data. Storing escaped content in a database seems like poor design to me. The database should store actual content, not munged content. Escape things as necessary at each layer, and no sooner.
To illustrate why this is a bad idea, consider a web site that is working on implementing a JSON-driven API. If they are storing HTML-encoded data in their database, they have two choices: (a) have HTML-encoded data in their JSON responses (which makes no sense), or (b) decode the HTML back to its original form before JSON-encoding it. Both choices are sub-optimal.
Data goes in the database, JSON strings go in JSON documents, and HTML-encoded data goes in HTML documents. Don't mix them!