[wp-trac] [WordPress Trac] #55942: Add a "value type" parameter to get_option() and get_metadata()

WordPress Trac noreply at wordpress.org
Tue May 9 18:06:04 UTC 2023


#55942: Add a "value type" parameter to get_option() and get_metadata()
-------------------------------------------------+-------------------------
 Reporter:  azaozz                               |       Owner:  (none)
     Type:  enhancement                          |      Status:  new
 Priority:  normal                               |   Milestone:  6.3
Component:  Options, Meta APIs                   |     Version:
 Severity:  normal                               |  Resolution:
 Keywords:  has-patch has-unit-tests needs-      |     Focuses:
  testing                                        |  performance
-------------------------------------------------+-------------------------

Comment (by flixos90):

 @azaozz
 > Unfortunately the "expansion/refactoring" in 4.7 made this a "try to do
 everything" type of function which is pretty bad design from software
 architecture point of view. So now it has some flaws and mixes up settings
 for HTML form elements with settings for the REST API and with settings
 for the retrieval of data from the database. Thinking it is a bad idea to
 continue to expand its scope.

 I see your point about mixing up concerns in that function not being
 optimal. Looking back, I would have preferred a separate function (e.g.
 `register_option()`?) to keep low-level option registration logic separate
 from UI registration logic in `register_setting()`. That said, the
 underlying functionality itself is crucial to have, and we cannot just
 stop working on it because we disagree with a decision made years ago.
 Either we have to do something about it (move to another new function and
 deprecate the changes introduced in 4.7?) or we have to accept where we
 are and move on. Simply not relying on the underlying functionality
 anymore because where it was implemented mixes option concerns with UI
 concerns is going to result in even more clunky APIs in the future.

 > Because it is mostly useless to try to "handle" it outside of the
 database. The initial idea of this ticket was to store the type of the
 option/meta value in the database. I.e. it would have been impossible to
 change (unless hacking directly in the DB). The type would have been set
 by the data type of the last `update_option()`. This would have fixed some
 of the "weirdness" with the options and meta APIs.
 Unfortunately it became clear that this is pretty much impossible to
 implement without breaking back-compat, and would introduce edge cases
 with caching. Trying to use external "register" comes with pretty much the
 same strings attached, and in addition there is a chance for it to become
 out of sync with the values in the DB. That would be a disaster :)

 The backward compatibility implication you mention makes sense, thanks for
 clarifying. Having a function return e.g. a (type-cast) `int` where it
 would have previously returned a raw string from the database is indeed a
 backward compatibility break, even though it would be nice to have. That
 makes me question the whole point of the current discussion, which is
 about database types. Originally, the focus was on avoiding
 `maybe_unserialize()`, and FWIW that is also the only thing here that has
 to do with performance.

 I think we need to take a step back here. The approach you outlined in
 [comment:1] makes a lot more sense conceptually than coming up with a full
 "type casting system" - that is tricky because of backward compatibility
 implications, and the approach of having to pass that in a parameter on
 every `get_option()` call is just as clunky of an API as plugins having to
 manually handle it. For example, `get_option( $option, $default, 'int' )`
 is not really better or worse than `(int) get_option( $option, $default
 )`.

 For purely serialization though, I think the backward compatibility
 implications don't apply. Data is typically serialized when it's an array
 or an object. Centrally registering for an option whether it uses
 serialization or not should not be the same concern regarding backward
 compatibility. For example, if a plugin today uses an option that
 conceptually is always a number, today the return value from
 `get_option()` may be an integer (if the default is returned or somehow
 filtered) or a string (if coming directly from the database). Telling
 WordPress explicitly that this option is ''not'' serialized will avoid the
 call to `maybe_unserialize()`, which addresses the original problem, and
 the return value will be maintained just like before.

 I'm basically proposing that options can centrally ''opt out'' of being
 attempted to be unserialized when it's clear they'll never use serialized
 data in the first place.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/55942#comment:76>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list