And yet, the post meta is stored in the database as a serialized array!
This is because all meta values are strings, that’s what the database table schema says.
So if you try to pass structured data into it, WordPress tries to be helpful and uses serialize
to turn it into a string, then deserialises it when it’s retrieved back. Note that this also has security consequences!. This happens for options, transients, user meta, post meta, term meta, etc etc. Anywhere that accepts arbitrary PHP data structures will serialise them down into a string so that it can still be stored. This also goes for JS data structures etc that are sent to the REST API, as well as any structured data you try to pass in via block APIs, it can’t be stored as a JS array or a PHP object, it has to be serialised into a string before it can be stored.
There are major performance and practical consequences to this too, querying for values is much harder and sometimes not possible as you can’t reliably query sub-parts of a meta value, and MySQL is unaware of any internal structure to the value. It also means if you wanted to do comparisons against your lat/long values that would not be possible.
and any way to override the way the value is saved?
You could declare it as a string and do the serialisation yourself, JSON would be a superior method, and you’d be explicit about how the data is stored.
But fundamentally it will always be a string. For this though, it could be argued that using an object in the first place is a mistake!
For example if you instead store your latitude and longitude in separate values, you can simplify your code, avoid serialising, and you gain the ability to use comparison operators in meta_query
.
Generally it’s best to avoid storing structured data in post meta unless you intend to serialize it yourself and retrieve it in its entirety, e.g. a JSON or XML fragment, or content.