[wp-testers] update_option() not always working in WP 3.0 beta 2

Dion Hulse (dd32) wordpress at dd32.id.au
Fri May 21 14:16:47 UTC 2010


Fixed, See http://core.trac.wordpress.org/ticket/13480

Turns out there was a recent change in caching, The Object cache was  
previously doing the cloning of the object, 3.0 changed the cache layout  
of options, and as such, the object cloning code wasnt kicking in.

On Fri, 21 May 2010 23:58:11 +1000, Dion Hulse (dd32)  
<wordpress at dd32.id.au> wrote:

> Hi Andrea,
> I've managed to reproduce it.. Using a similar set of code to what  
> you've posted the 2nd time around.
>
> And I think i know why its happening, But not what has changed.
>
> In short, $value (the object) is being stored by reference in the  
> WordPress per-page object cache.
>
> If you run:
>
> $value = new stdClass;
> $value->var1 = $k;
> update_option ($option_name, $value);
> $value->var2 = $k + 1;
>
> var_dump(get_option($option_name));
>
> You'll find that get_option() will return var1, AND var2, even though  
> the database was never updated, or update_option was never called.
>
> This is due to PHP5 passing objects by reference, rather than by value.
>
> So when it comes to the line:
> if ( $newvalue === $oldvalue )
> in update_option(), $oldvalue IS the $newvalue, as they're the same  
> object in memory.
>
> This is the code that was introduced to fix that 18months ago:  
> http://core.trac.wordpress.org/changeset/9740/trunk/wp-includes/cache.php
>
> wp_clone() appears to be working correcting in my testing, So i'm not  
> sure what is causing the error at this point in time..
>
>
> On Thu, 20 May 2010 23:58:08 +1000, andrea <andrea at blogsweek.com> wrote:
>
>> Hello Dion,
>>
>> I tried to run your code, and it works for me too, but that doesn't  
>> mean the
>> option is saved in the database. Running this modified version
>>
>> $option_name = 'test2';
>>
>> $value = get_option ($option_name);
>> if ($value == false)
>> 	$value = new stdClass;
>>
>> echo "<br/><br/>";
>> print_r (get_option ($option_name));
>>
>> $k = time ();
>> $value->var1 = $k;
>> update_option ($option_name, $value);
>> $value->var2 = $k + 1;
>> update_option ($option_name, $value);
>> $value->var3 = $k + 2;
>> update_option ($option_name, $value);
>>
>> echo "<br/><br/>";
>> print_r (get_option ($option_name));
>>
>> and reloading the page once or more times, I can see that the option is  
>> not
>> being saved in the database. The first print_r output should match the  
>> second
>> print_r output from the previous run, but it doesn't.
>>
>> Can you replicate this in your environment?
>>
>> Thank you
>> Andrea
>>
>>
>> Quoting "Dion Hulse (dd32)" <wordpress at dd32.id.au>:
>>
>>> No I didnt test with any plugins, You can try deactivating the plugin  
>>> to
>>> see if it makes a difference.
>>> My point was, I cant see it being caused by WordPress, The comparisons
>>> made using either == or === in this case should show the objects as
>>> different, and due to it working for me, I dont personally think its a
>>> change that has been made.
>>>
>>> If you can provide a SVN revision range where it did work, and where it
>>> doesnt work (narrowed down as much as possible) it'd obviously help to  
>>> see
>>> what may've changed.
>>>
>>>
>>> On Thu, 20 May 2010 20:49:38 +1000, andrea <andrea at blogsweek.com>  
>>> wrote:
>>>
>>> > Hello Dion,
>>> >
>>> > thank you for your feedback. I'm running an out-of-the-box WP  
>>> install,
>>> > without
>>> > additional caching, on PHP 5.2.0. The only difference between the  
>>> working
>>> > environment and the non-working one is:
>>> >
>>> > working: WP 2.9.2
>>> > non-working: WP 3.0 beta 2
>>> >
>>> > so I was suspecting a change in WP 3.0 options caching, made before  
>>> or
>>> > with
>>> > svn13807 - 2010.03.23 @ 20.03.
>>> >
>>> > Were you able to run Menubar 4.7? To replicate the problem, you only
>>> > need to
>>> > install it, create a menu, add a menu item, and reload the admin  
>>> page.
>>> > With WP
>>> > 2.9.2 the menu item is still there, with WP 3.0 beta 2 the new menu  
>>> item
>>> > goes
>>> > away, because the underlying option is not updated in the DB.
>>> >
>>> > Thank you
>>> > Andrea
>>> >
>>> >
>>> > Quoting "Dion Hulse (dd32)" <wordpress at dd32.id.au>:
>>> >
>>> >> Sounds like you've run into either:
>>> >>   a. a Bug with PHP
>>> >>   b. a Bug in a Caching layer you've got enabled
>>> >>
>>> >> This exact code works for me:
>>> >>
>>> >>
>>> >> $option_name = 'test';
>>> >>
>>> >> $value = (object) array('test' => true);
>>> >> $value->var1 = 1;
>>> >> update_option ($option_name, $value);
>>> >> $value->var2 = 2;
>>> >> update_option ($option_name, $value);
>>> >> $value->var3 = 3;
>>> >> update_option ($option_name, $value);
>>> >>
>>> >> var_dump(get_option($option_name));
>>> >> delete_option($option_name);
>>> >>
>>> >> Resulting in:
>>> >> object(stdClass)#278 (4) { ["test"]=> bool(true) ["var1"]=> int(1)
>>> >> ["var2"]=> int(2) ["var3"]=> int(3) }
>>> >>
>>> >> Thats running the latest SVN edition, and PHP 5.3.1
>>> >>
>>> >> Checking
>>> >> http://www.php.net/manual/en/language.oop5.object-comparison.php
>>> >> confirms that the existing code should work as expected.
>>> >>
>>> >>
>>> >> On Thu, 20 May 2010 05:43:42 +1000, andrea <andrea at blogsweek.com>  
>>> wrote:
>>> >>
>>> >> > Hi all,
>>> >> >
>>> >> > In a plugin I store an object in an option, and the typical flow  
>>> is as
>>> >> > follows:
>>> >> >
>>> >> > $value = get_option ($option_name);
>>> >> > $value->var1 = $new_var1;
>>> >> > update_option ($option_name, $value);
>>> >> > $value->var2 = $new_var2;
>>> >> > update_option ($option_name, $value);
>>> >> > $value->var3 = $new_var3;
>>> >> > update_option ($option_name, $value);
>>> >> >
>>> >> > and so on. That used to work fine with WP 2.9.2, both with PHP4  
>>> and
>>> >> PHP5.
>>> >> >
>>> >> > With WP 3.0 beta 2 and PHP4, no problem.
>>> >> >
>>> >> > With WP 3.0 beta 2 and PHP5, apparently only the first  
>>> update_option()
>>> >> > call is
>>> >> > honored, and following calls are not honored because  
>>> update_option()
>>> >> > finds that
>>> >> >
>>> >> > $newvalue === $oldvalue (lines 503-504 in  
>>> wp-includes/functions.php)
>>> >> >
>>> >> > and does not update the database. If I remove those two lines, the
>>> >> > plugin works
>>> >> > again. If in my code I replace
>>> >> >
>>> >> > update_option ($option_name, $value);
>>> >> >
>>> >> > with
>>> >> >
>>> >> > update_option ($option_name, 0);
>>> >> > update_option ($option_name, $value);
>>> >> >
>>> >> > the plugin works as well.
>>> >> >
>>> >> > According to a user report I received, the problem was first  
>>> noted in
>>> >> > WordPress 3.0 alpha (svn13807 – 2010.03.23 @ 20.03).
>>> >> >
>>> >> > Is this issue already known? Or am I missing something? If  
>>> interested,
>>> >> > the
>>> >> > plugin that stopped working in WP 3.0 is Menubar 4.7.
>>> >> >
>>> >> > Thank you all
>>> >> > Andrea
>>> >> >
>>> >> > Andrea Tarantini
>>> >> > www.blogsweek.com
>>> >> > www.dontdream.it
>>> >> >
>>> >> >
>>> >> > _______________________________________________
>>> >> > wp-testers mailing list
>>> >> > wp-testers at lists.automattic.com
>>> >> > http://lists.automattic.com/mailman/listinfo/wp-testers
>>> >> >
>>> >>
>>> >>
>>> >> --
>>> >> Dion Hulse / dd32
>>> >> Contact:
>>> >>   e: contact at dd32.id.au
>>> >>   Web: http://dd32.id.au/
>>> >> _______________________________________________
>>> >> wp-testers mailing list
>>> >> wp-testers at lists.automattic.com
>>> >> http://lists.automattic.com/mailman/listinfo/wp-testers
>>> >>
>>> >
>>> >
>>> >
>>> >
>>> > _______________________________________________
>>> > wp-testers mailing list
>>> > wp-testers at lists.automattic.com
>>> > http://lists.automattic.com/mailman/listinfo/wp-testers
>>> >
>>>
>>>
>>> --
>>> Dion Hulse / dd32
>>> Contact:
>>>   e: contact at dd32.id.au
>>>   Web: http://dd32.id.au/
>>> _______________________________________________
>>> wp-testers mailing list
>>> wp-testers at lists.automattic.com
>>> http://lists.automattic.com/mailman/listinfo/wp-testers
>>>
>>
>>
>>
>>
>> _______________________________________________
>> wp-testers mailing list
>> wp-testers at lists.automattic.com
>> http://lists.automattic.com/mailman/listinfo/wp-testers
>>
>
>


-- 
Dion Hulse / dd32
Contact:
  e: contact at dd32.id.au
  Web: http://dd32.id.au/


More information about the wp-testers mailing list