Make WordPress Core

Changeset 56681

Timestamp:
09/25/2023 04:23:52 PM (11 months ago)
Author:
flixos90
Message:

Options, Meta APIs: Improve logic to avoid unnecessary database writes in update_option().

Prior to this change, a strict comparison between the old and new database value could lead to a false negative, since database values are generally stored as strings. For example, passing an integer to update_option() would almost always result in an update given any existing database value for that option would be that number cast to a string.

This changeset adjusts the logic to perform an intentional "loose-y" comparison by casting the values to strings. Extensive coverage previously added in [56648] provides additional confidence that this does not introduce any backward compatibility issues.

Props mukesh27, costdev, spacedmonkey, joemcgill, flixos90, nacin, atimmer, duck_, boonebgorges.
Fixes #22192.

Location:
trunk
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/option.php

    r56595 r56681  
    777777    $value = apply_filters( 'pre_update_option', $value, $option, $old_value );
    778778
     779
     780
     781
    779782    /*
    780783     * If the new and old values are the same, no need to update.
    781784     *
    782      * Unserialized values will be adequate in most cases. If the unserialized
    783      * data differs, the (maybe) serialized data is checked to avoid
    784      * unnecessary database calls for otherwise identical object instances.
    785      *
    786      * See https://core.trac.wordpress.org/ticket/38903
    787      */
    788     if ( $value === $old_value || maybe_serialize( $value ) === maybe_serialize( $old_value ) ) {
     785     * An exception applies when no value is set in the database, i.e. the old value is the default.
     786     * In that case, the new value should always be added as it may be intentional to store it rather than relying on the default.
     787     *
     788     * See https://core.trac.wordpress.org/ticket/38903 and https://core.trac.wordpress.org/ticket/22192.
     789     */
     790    if ( $old_value !== $default_value && _is_equal_database_value( $old_value, $value ) ) {
    789791        return false;
    790792    }
    791793
    792     /** This filter is documented in wp-includes/option.php */
    793     if ( apply_filters( "default_option_{$option}", false, $option, false ) === $old_value ) {
     794   
     795
    794796        // Default setting for new options is 'yes'.
    795797        if ( null === $autoload ) {
     
    28882890    return $registered[ $option ]['default'];
    28892891}
     2892
     2893
     2894
     2895
     2896
     2897
     2898
     2899
     2900
     2901
     2902
     2903
     2904
     2905
     2906
     2907
     2908
     2909
     2910
     2911
     2912
     2913
     2914
     2915
     2916
     2917
     2918
     2919
     2920
     2921
     2922
     2923
     2924
     2925
     2926
     2927
     2928
  • trunk/tests/phpunit/tests/option/option.php

    r56648 r56681  
    525525        );
    526526    }
     527
     528
     529
     530
     531
     532
     533
     534
     535
     536
     537
     538
     539
     540
     541
     542
     543
     544
     545
     546
     547
     548
     549
     550
     551
     552
     553
     554
     555
     556
     557
     558
     559
     560
     561
     562
     563
     564
     565
     566
     567
     568
     569
     570
     571
     572
     573
     574
     575
     576
     577
     578
     579
     580
     581
     582
     583
    527584}
Note: See TracChangeset for help on using the changeset viewer.