Options: Avoid unnecessary DB calls when updating network options.

Adds a `maybe_serialize()` comparison for the old and new values in `update_network_option()` to avoid unnecessary database writes when options contain identical objects.

Props bor0.
Fixes #44956.



git-svn-id: https://develop.svn.wordpress.org/trunk@44662 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Peter Wilson 2019-01-21 04:26:33 +00:00
parent 02422aab1d
commit 7d8ce1e287
2 changed files with 46 additions and 1 deletions

View File

@ -1583,7 +1583,16 @@ function update_network_option( $network_id, $option, $value ) {
*/
$value = apply_filters( "pre_update_site_option_{$option}", $value, $old_value, $option, $network_id );
if ( $value === $old_value ) {
/*
* If the new and old values are the same, no need to update.
*
* Unserialized values will be adequate in most cases. If the unserialized
* data differs, the (maybe) serialized data is checked to avoid
* unnecessary database calls for otherwise identical object instances.
*
* See https://core.trac.wordpress.org/ticket/44956
*/
if ( $value === $old_value || maybe_serialize( $value ) === maybe_serialize( $old_value ) ) {
return false;
}

View File

@ -169,4 +169,40 @@ class Tests_Option_NetworkOption extends WP_UnitTestCase {
$this->assertSame( array( 'this_does_not_exist' => true ), $cache );
}
/**
* Ensure updating network options containing an object do not result in unneeded database calls.
*
* @ticket 44956
*/
public function test_update_network_option_array_with_object() {
$array_w_object = array(
'url' => 'http://src.wordpress-develop.dev/wp-content/uploads/2016/10/cropped-Blurry-Lights.jpg',
'meta_data' => (object) array(
'attachment_id' => 292,
'height' => 708,
'width' => 1260,
),
);
$array_w_object_2 = array(
'url' => 'http://src.wordpress-develop.dev/wp-content/uploads/2016/10/cropped-Blurry-Lights.jpg',
'meta_data' => (object) array(
'attachment_id' => 292,
'height' => 708,
'width' => 1260,
),
);
// Add the option, it did not exist before this.
add_network_option( null, 'array_w_object', $array_w_object );
$num_queries_pre_update = get_num_queries();
// Update the option using the same array with an object for the value.
$this->assertFalse( update_network_option( null, 'array_w_object', $array_w_object_2 ) );
// Check that no new database queries were performed.
$this->assertEquals( $num_queries_pre_update, get_num_queries() );
}
}