WordPress.org

Make WordPress Core

Opened 3 months ago

Last modified 6 days ago

#51699 reopened defect (bug)

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)

51699-1.patch (1.2 KB) - added by ttodua 3 months ago.

Download all attachments as: .zip

Change History (7)

@ttodua
3 months ago

#1 @apedog
2 months ago

Testing with if ( get_option('some_option') !== false ) will not return false negatives for null, 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.

#2 @SergeyBiryukov
2 months 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: @ttodua
2 months 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 @digitalsetups
6 days 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 @apedog
6 days 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.

#6 @ttodua
6 days ago

@apedog You told every word exactly I was preparing to say. :thumb_up:

Note: See TracTickets for help on using tickets.