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

Dion Hulse (dd32) wordpress at dd32.id.au
Fri May 21 13:58:11 UTC 2010


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