Opened 8 years ago
Last modified 12 months ago
#40007 reopened defect (bug)
update_option function does not work if the $value argument is false on a nonexistent option
Reported by: | alexvorn2 | Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | |
Component: | General | Keywords: | has-patch |
Focuses: | Cc: |
Description
If we specify a false argument in update_option function and if the database option does not exist then the option will not be saved.
I expect the option to be saved with false value if it does not exist.
If we look into the code of this function we can see that it will return false if the old value is false too, so if the option does not exists then it will return false.
It's a bug.
How to replicate? give a try:
<?php update_option( 'aaa2345454', false );
Attachments (2)
Change History (12)
#2
follow-up:
↓ 3
@
8 years ago
- Keywords close added
- Resolution set to invalid
- Status changed from new to closed
According to the structure as of now the datatype the option_name
column in wp_options
is of string type (varchar(191)
).
The reason it does not add a record with update_option('aaa2345454', false)
is you are passing a Boolean value.
To add / update a record with value true
or false
you either need to pass it directly as string like
update_option('aaa2345454', 'false');
or in case you are grabbing this value from somewhere else which is a Boolean then you need to create a string alternative for your value before you actually send it:
$value = true; //hard coding the $value here. You may be grabbing it from somewhere else. $converted_value = ($value) ? 'true' : 'false'; update_option('aaa2345454', $converted_value)
The above would add / update the value in wp_options
table with a value either true
or false
in option_value
column. However, the value would not insert as a real Boolean type.
#3
in reply to:
↑ 2
@
8 years ago
- Resolution invalid deleted
- Status changed from closed to reopened
Replying to subrataemfluence:
According to the structure as of now the datatype the
option_name
column inwp_options
is of string type (varchar(191)
).
The reason it does not add a record with
update_option('aaa2345454', false)
is you are passing a Boolean value.
To add / update a record with value
true
orfalse
you either need to pass it directly as string like
update_option('aaa2345454', 'false');or in case you are grabbing this value from somewhere else which is a Boolean then you need to create a string alternative for your value before you actually send it:
$value = true; //hard coding the $value here. You may be grabbing it from somewhere else. $converted_value = ($value) ? 'true' : 'false'; update_option('aaa2345454', $converted_value)The above would add / update the value in
wp_options
table with a value eithertrue
orfalse
inoption_value
column. However, the value would not insert as a real Boolean type.
I want to add a Boolean false value, not STRING 'false' value, these are 2 different things.
Why update_option( 'aaa2345', true )
works and update_option( 'aaa2346', false )
does not?
I think you did not understand the issue here. I will reopen this, why close so fast? Just a close keyword is enough, maybe someone has a different opinion.
Even if update_option( 'aaa2346', false )
does not work it should at least insert a new row into the database.
#4
@
8 years ago
- Keywords close removed
My apology for closing the ticket. That was not intended. I will try once again.
#5
@
8 years ago
Although false
is not being recognized a value 0 is actually adding / updating record in the table. So it is only Boolean false
which is not working! I am under an impression that this value has a conflict somewhere in the function!
true
- works. Value added is 1
1
- works. Value added is 1
false
- does not work - No record added
0
- works - Value added is 0
'true'
- works. Value added is 'true'
'false'
- works. Value added is 'false'
#6
@
8 years ago
Further inspecting the core function update_action
reveals something strange!
The value false
is actually being treated as an empty string, but true
is not! So when I am passing false
for a key which I know does not exist there yet, get_option
returns an empty string ($old_value = get_option( $option );
), which when being compared in the following snippet:
if ( $value === $old_value ) return false;
always returning false as both $value
and $old_value
are nothing but empty strings!
This is the reason update_option('_option_key_index', false)
, never adds a record in the database. But if I pass update_option('_option_key_index', 0)
it does.
#8
@
8 years ago
Converting to 0(int)
instead of "0"(string)
will result in a database write on every call, as all options are recorded as strings. The old and new value comparison becomes 0 === "0"
and evaluates to false. (related #38903).
A more robust solution would be to correctly cast the value before comparing old an new values.
It's worth noting add_option()
will fail to store the value false
too. ref.
#10
@
12 months ago
I rediscovered this while working on another ticket.
In 40007.diff, rather than checking the return value of get_option()
to determine if update_option()
is called with a new option, it checks if the option name appears in the notoptions
cache.
If the option key is in notoptions
then the option can be added to the database via the add_option
function.
The attached diff is only lightly tested, a call to update_option( 'non-exisistent-option', false )
does result in the option being added to the database.
I can't believe such a old function and very used one have a bug.