Must I serialize/sanitize/escape array data before using set_transient?

tl;dr

  • Should I serialize the data? No, it will be done for you as long as everything is serializable.
  • Should I sanitize/escape the data? Partially. The data will be escaped automatically for you to prevent SQL injection attacks, but you should sanitize and validate it to assure data consistency.

Explanation

If there’s no object cache in place, transients stores the data in the database with $wpdb->update(), which secures the input from SQL Injection attacks by using PDO prepared statements.

If object cache is in place, it just persists it in the object cache class with WP_Object_Cache::set(), which performs no sanitization whatsoever. I don’t think this is a problem since object cache doesn’t suffer any kind of injection like SQL does.

It can only be a security issue if you then fetch this data and output it without properly escaping it, so it’s something that you might want to be careful about.

You don’t need to serialize the value, you just have to make sure that if it’s an object, it is serializable (by implementing the Serializable interface), and if it’s an array, that the values are also serializable. All scalar types are serializable out of the box, such as string, int, float, etc.

This is exactly what @param mixed $value Transient value. Must be serializable if non-scalar. that you quoted in your question means.

It’s worth mentioning that, for transients being stored in object cache, it’s the duty of the object cache to serialize the value, but I wouldn’t worry about that, since this is a basic feature of any object cache storage. Memcached serializes it by default, while Redis relies on the drop-in to do so, but either way, you can consider object cache to serialize your value for you.