Make WordPress Core

Opened 2 years ago

Last modified 2 years ago

#56944 new defect (bug)

get_option does not return expected value

Reported by: planvova's profile planvova Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 6.0.2
Component: Options, Meta APIs Keywords:
Focuses: Cc:

Description (last modified by sabernhardt)

Hello,

I ran into the issue when get_option does not return any value:
get_option( "_wp_session_{$this->session_id}", array() );

It returns an empty value, but the value exists in DB and in cache.

I tested with 3 different methods one-by-one for option _wp_session_5c1f3b8058ca4b6cf9e637c31300bc23:

1) get_option

get_option( "_wp_session_5c1f3b8058ca4b6cf9e637c31300bc23", array() );

It returns an empty value (but sometimes it works fine)

2) wp_cache_get

wp_cache_get( "_wp_session_5c1f3b8058ca4b6cf9e637c31300bc23", 'options' );

It returns correct value

a:6:{s:8:"edd_cart";s:40:"[{"id":79377,"options":[],"quantity":1}]";s:13:"edd_cart_fees";s:0:"";s:18:"edd_resume_payment";s:0:"";s:14:"cart_discounts";s:0:"";s:10:"edd_errors";s:0:"";s:12:"edd_purchase";s:1072:"{"downloads":[{"id":147706,"options":[],"quantity":1}],"fees":[],"subtotal":0,"discount":0,"tax":"0.00","tax_rate":0,"price":0,"purchase_key":"f7f8403a9d9edb93f9be9376d117c1f0","user_email":"","date":"2022-10-31 13:59:43","user_info":{"id":37847,"email":"","first_name":"","last_name":"","discount":"none","address":[]},"post_data":{"edd_email":"","edd_first":"","edd_last":"","edd_agree_to_terms":"1","edd-user-id":"","edd_action":"purchase","edd-gateway":"manual","edd-process-checkout-nonce":"911cf02037"},"cart_details":[{"name":"","id":,"item_number":{"id":147706,"options":[],"quantity":1},"item_price":0,"quantity":1,"discount":0,"subtotal":0,"tax":0,"fees":[],"price":0}],"gateway":"manual","card_info":{"card_name":"","card_cvc":"","card_exp_month":"","card_exp_year":"","card_address":"","card_address_2":"","card_city":"","card_state":"","card_country":"","card_zip":""}}";}

I removed some private information here.

3) direct DB request

$wpdb->get_results('SELECT * FROM wp_options WHERE option_name = "_wp_session_5c1f3b8058ca4b6cf9e637c31300bc23"')

It returns correct value

Array
(
    [edd_cart] => [{"id":79377,"options":[],"quantity":1}]
    [edd_cart_fees] =>
    [edd_resume_payment] =>
    [cart_discounts] =>
    [edd_errors] =>
    [edd_purchase] => {"downloads":[{"id":147706,"options":[],"quantity":1}],"fees":[],"subtotal":0,"discount":0,"tax":"0.00","tax_rate":0,"price":0,"purchase_key":"f7f8403a9d9edb93f9be9376d117c1f0","user_email":"","date":"2022-10-31 13:59:43","user_info":{"id":37847,"email":"","first_name":"","last_name":"","discount":"none","address":[]},"post_data":{"edd_email":"","edd_first":"","edd_last":"","edd_agree_to_terms":"1","edd-user-id":"37847","edd_action":"purchase","edd-gateway":"manual","edd-process-checkout-nonce":"911cf02037"},"cart_details":[{"name":"","id":147706,"item_number":{"id":147706,"options":[],"quantity":1},"item_price":0,"quantity":1,"discount":0,"subtotal":0,"tax":0,"fees":[],"price":0}],"gateway":"manual","card_info":{"card_name":"","card_cvc":"","card_exp_month":"","card_exp_year":"","card_address":"","card_address_2":"","card_city":"","card_state":"","card_country":"","card_zip":""}}
)

I removed some private information here.


So the problem only with function get_option. I checked this function as well. It selects values for notoptions:
$notoptions = wp_cache_get( 'notoptions', 'options' );

And if current option exists in this array – it do return

if ( isset( $notoptions[ $option ] ) ) {
			/**
			 * Filters the default value for an option.
			 *
			 * The dynamic portion of the hook name, `$option`, refers to the option name.
			 *
			 * @since 3.4.0
			 * @since 4.4.0 The `$option` parameter was added.
			 * @since 4.7.0 The `$passed_default` parameter was added to distinguish between a `false` value and the default parameter value.
			 *
			 * @param mixed  $default The default value to return if the option does not exist
			 *                        in the database.
			 * @param string $option  Option name.
			 * @param bool   $passed_default Was `get_option()` passed a default value?
			 */
			return apply_filters( "default_option_{$option}", $default, $option, $passed_default );
		}

Current option exists in this array, so it applies filter "default_option_{$option}", function filter_default_option. But this function check get_registered_settings, and there is no information about this option, so it returns empty result.

That’s all information I have so far.

This problem exists at least for 1 year, for this time we always update WordPress core and Plugins for latest version, and it does not any effect.

Change History (3)

#1 @sabernhardt
2 years ago

  • Component changed from General to Options, Meta APIs
  • Description modified (diff)

Hi and thanks for the report!

I updated the ticket description's formatting, which includes replacing the “smart quotes” that came from the support topic.

#2 @planvova
2 years ago

@sabernhardt Thank you. Can you please also change values _wp_session_f5f8546504975ed39fb121b6b1b7c829 to _wp_session_5c1f3b8058ca4b6cf9e637c31300bc23 in original comment? I can't edit it and I wrote a wrong session_id.

So for all requests I used option _wp_session_5c1f3b8058ca4b6cf9e637c31300bc23,
this one _wp_session_f5f8546504975ed39fb121b6b1b7c829 is wrong(typo).


Also I noticed that at the same time we have value for
$notoptions = wp_cache_get( 'notoptions', 'options' );
$notoptions['_wp_session_5c1f3b8058ca4b6cf9e637c31300bc23'] = 1;

And for
wp_cache_get( "_wp_session_5c1f3b8058ca4b6cf9e637c31300bc23", 'options' );
it has correct data.

But if I checked code in options.php file - when it sets cache for _wp_session_5c1f3b8058ca4b6cf9e637c31300bc23 then it removes $notoptions['_wp_session_5c1f3b8058ca4b6cf9e637c31300bc23'] and updates notoptions

So I guess this situation must not happen.

#3 @sabernhardt
2 years ago

  • Description modified (diff)
Note: See TracTickets for help on using tickets.