Opened 4 years ago
Last modified 9 months ago
#51699 reopened enhancement
The only correct method to check for existence of option
Reported by: | ttodua | Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | |
Component: | Options, Meta APIs | Keywords: | |
Focuses: | Cc: |
Description
There are many valid cases to check if particular option exists in WP (checking for leftovers of other plugins, or existence of some theme options, or some other cases).
The current advertised method to check that is:
if ( ! get_option('optionName') )
However, that is no way the correct approach as it is not able to check for option existence (because if the option is set with value: null/false/0/empty-string
, then the check for existence will be meaningless with that approach).
So, I suggest to add a correct function named option_exists
to get the correct answer:
function option_exists( $option_name, $site_wide = false ) {
global $wpdb;
return $wpdb->query( $wpdb->prepare( "SELECT * FROM ". ($site_wide ? $wpdb->base_prefix : $wpdb->prefix). "options WHERE option_name ='%s' LIMIT 1", $option_name ) );
}
Attachments (1)
Change History (12)
#2
follow-up:
↓ 7
@
4 years ago
- Component changed from General to Options, Meta APIs
Thanks for the ticket!
Just noting that get_option() has an optional $default
argument, which serves exactly this purpose, it's a default value to return if the option does not exist.
So the existence could be checked with a snippet like this:
if ( 'not-exists' === get_option( 'my_option', 'not-exists' ) ) { echo 'The option does not exist.'; }
#3
follow-up:
↓ 4
@
4 years ago
@apedog well, select 1 might be good also, i am not SQL master, you might adopt that. Just found in internet, that the method i posted is fastest among others, however, you can tell your thoughts.
@SergeyBiryukov thanks, but the $default option is not even related to this ticket. the ticket is about "existence" of option (nevertheless it's value, let it be string, boolean, or whatever, even no-one knows what value specific option might have, string, bool, or whatever). So, your offered one is not related to the problem directly, and doesn't solve it.
#4
in reply to:
↑ 3
@
4 years ago
- Resolution set to invalid
- Status changed from new to closed
Replying to ttodua:
@apedog well, select 1 might be good also, i am not SQL master, you might adopt that. Just found in internet, that the method i posted is fastest among others, however, you can tell your thoughts.
@SergeyBiryukov thanks, but the $default option is not even related to this ticket. the ticket is about "existence" of option (nevertheless it's value, let it be string, boolean, or whatever, even no-one knows what value specific option might have, string, bool, or whatever). So, your offered one is not related to the problem directly, and doesn't solve it.
@SergeyBiryukov is correct and the default option actually does the work that you're willing to achieve with your custom function. The $default option is just like your return value for the existence i-e: you're returning 'boolean' while $default in get_options is allowing us to set 'string' something to return if option doesn't exists.
#5
@
4 years ago
- Resolution invalid deleted
- Status changed from closed to reopened
I don't think this is an invalid ticket. I'd say an option_exists()
function would be a valuable addition to the API. I know I searched for such a function quite often when I started with WordPress.
@SergeyBiryukov's solution does work. But it's a workaround. It makes creative use of get_option
's optional parameter and results in non-human-readable code (it is not immidiately obvious what the code does). And it relies on the test string not being used as the value of the option (either intentionally or accidentally). ie. it's not foolproof 100% of the time.
This is ok for most purposes, but it does not, strictly speaking, test the database if the option exists.
#7
in reply to:
↑ 2
@
4 years ago
Replying to SergeyBiryukov:
So the existence could be checked with a snippet like this:
if ( 'not-exists' === get_option( 'my_option', 'not-exists' ) ) { echo 'The option does not exist.'; } else { echo 'The option exists.'; }
Sergey's solution above (I've edited it slightly), in fact, does not work.
If a plugin makes use of the "pre_option_{$option}"
filter (which shortcircuits get_option
to return a custom value), this solution will show that the option exists - even when no such option exists in the options table.
An option_exists
API function would actually solve for such a situtation.
This ticket was mentioned in Slack in #core by apedog. View the logs.
4 years ago
#10
@
3 years ago
In addition to pre_option_{$option} you should use the alloptions and notoptions caches to save database queries
- if the key exists in alloptions return true
- if the key exists in notoptions return false
- only then make the database query
- if the value exists save it in alloptions (after running the usual filters); if not add the key to notoptions
so that if we all option_exists() and get_option() it will make at most one database query, and ditto if you call option_exists() twice for the same key it will make at most one database query. (However this is starting to duplicate a lot of the get_option logic, so maybe this should use that or be built into that somehow instead.)
Testing with
if ( get_option('some_option') !== false )
will not return false negatives fornull
,0
,''
.But will still miss boolean
false
... :/This seems to me like a useful method.
I think
SELECT 1
in the query would be more appropriate. You don't want to return the option. You want to return a boolean.