Make WordPress Core

Opened 8 years ago

Closed 8 years ago

Last modified 7 years ago

#13480 closed defect (bug) (fixed)

update_option + PHP5 Object references not storing correctly in cache

Reported by: dd32 Owned by: ryan
Milestone: 3.0 Priority: normal
Severity: normal Version: 3.0
Component: Cache API Keywords: needs-unit-tests
Focuses: Cc:


This is related to the changes to caching of the options API.

At present, When objects are saved using the option API, the PHP5 object references are being stored in an array in the "object cache", The result is that if you attempt to update an object variable multiple times in 1 page load, you'll end up with only the first update_option succeeding.

This is because on subsequent calls, the object cache references the NEW value as existing within the database..

Whilst this ticket description might be hard to follow, This is the same as [9740].

The solution is to clone the variables if they're objects in the Options API.

Attachments (1)

13480-test.diff (832 bytes) - added by jgadbois 7 years ago.

Download all attachments as: .zip

Change History (13)

#1 @dd32
8 years ago

  • Resolution set to fixed
  • Status changed from new to closed

(In [14777]) Clone Objects in add_option()/update_option() to prevent storing PHP5 object references in memory cache. See [9740]. Fixes #13480

#2 @dd32
8 years ago

See also this wp-testers thread which prompted this ticket: http://lists.automattic.com/pipermail/wp-testers/2010-May/013020.html

#3 @westi
8 years ago

  • Keywords needs-unit-tests added

An excellent candidate for unit tests :-)

#4 @dd32
8 years ago

An excellent candidate for unit tests :-)

Quite agree, I'll write some when i've got a free moment if someone else doesnt get to it first.

To reproduce:

  • Create an object, store its value in an option, update a field in that object, update the option with it again.
  • All going well, the database should now contain the updated object.
  • Under PHP5 previously, This would not be the case, The database would only contain the FIRST version of the object
    • Will need to use a query or similar(disable cache temporarily?) to bypass cache and retrieve directly from the database.

#5 @dd32
8 years ago

Another way to reproduce:

  • Create an object, store its value in an option, update a field in that object WITHOUT SAVING
  • Retrieve option, It should contain the first copy of the object, Under PHP5 previously, it will return the updated object (directly from the cache which references the original object)

#6 @hakre
7 years ago

Another way to comment:

If you want a NEW value you should offer the clone as such:

$value = clone get_option($option_name);
$value->var1 = $new_var1;
update_option($option_name, $value);

my 2 cents. don't fix what isn't broken (so I'll remove the cause.../ [chuckles] but not the symptom.)

#7 @hakre
7 years ago

And if $alloptions was the cache, then add_option was not to be fixed as $alloptions[$option] is set to the serialized value (which is never subject to cloning.... )

#8 @hakre
7 years ago

Related: #16813

7 years ago

#10 @jgadbois
7 years ago

  • Cc jgadbois@… added

#11 @SergeyBiryukov
7 years ago

  • Keywords needs-unit-tests removed

#12 @SergeyBiryukov
7 years ago

  • Keywords needs-unit-tests added

Didn't notice that the tests from 13480-test.diff weren't commited yet. Adding the keyword back.

Note: See TracTickets for help on using tickets.