See the discussion in T301915#7821799: although ParserOutput will properly store any JSON-serializable value, the deferred LinksUpdate task will stringify everything before storing it in the database. Further, the sort key will be null unless the value is int|float|bool.
This is a dangerous pattern, as many implicit conversions in PHP will convert between numeric strings (strings which "look like" numbers) and int|float. For example, storing a numeric string as an array_key will convert it to a number. It is too easy to either (a) add bogus sort keys to things like title strings that just sometimes happen to be numbers (and which were stored as array keys and thus numeric-ified), or (b) store a numeric string instead of an actual number and thus get the sort key dropped (see T350224).
It would be best to split this into two methods:
- ::setIndexedPageProperty() which only takes int|float and coerces its values to numbers --- at least until PHP 8 when we can use the union type as a type hint
- This can also allow specification of sort key independent from value, as hinted by a note in PagePropsTable (Txxxx)
- ::setUnindexedPageProperty() which only takes string and ensures the values won't be inadvertently indexed