Opened 3 years ago

Closed 3 years ago

Last modified 20 months ago

#13480 closed defect (bug) (fixed)

update_option + PHP5 Object references not storing correctly in cache

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

Description

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 21 months ago.

Download all attachments as: .zip

Change History (13)

comment:1   dd323 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

comment:2   dd323 years ago

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

  • Keywords needs-unit-tests added

An excellent candidate for unit tests :-)

comment:4   dd323 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.

comment:5   dd323 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)

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.)

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.... )

Related: #16813

See [17613].

  • Cc jgadbois@… added
  • Keywords needs-unit-tests removed
  • 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.