Make WordPress Core


Ignore:
Timestamp:
09/18/2023 12:39:18 PM (10 months ago)
Author:
spacedmonkey
Message:

Plugins: Store result of call to array_keys, to save repeated calls in WP_Hook class.

In the WP_Hook class the function array_keys was called every time an array of hook priorities was needed. For sites with lots of filters or actions, this would result in thousands of calls to the array_keys function, which uses server resources. Instead of recomputing this array every time it is needed, only compute it when filters are added and removed, then store the result as a class property. Improve unit tests to ensure this behaviour is tested.

Props spacedmonkey, bor0, flixos90, hellofromTonya, mukesh27.
Fixes #58458.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/hooks/addFilter.php

    r55081 r56609  
    3636
    3737        $hook->add_filter( $hook_name, $callback, $priority, $accepted_args );
     38        $this->check_priority_exists( $hook, $priority );
    3839
    3940        $function_index = _wp_filter_build_unique_id( $hook_name, $callback, $priority );
     
    5152
    5253        $hook->add_filter( $hook_name, $callback, $priority, $accepted_args );
     54        $this->check_priority_exists( $hook, $priority );
    5355
    5456        $function_index = _wp_filter_build_unique_id( $hook_name, $callback, $priority );
     
    6567
    6668        $hook->add_filter( $hook_name, $callback, $priority, $accepted_args );
     69        $this->check_priority_exists( $hook, $priority );
    6770
    6871        $function_index = _wp_filter_build_unique_id( $hook_name, $callback, $priority );
     
    8083
    8184        $hook->add_filter( $hook_name, $callback_one, $priority, $accepted_args );
     85        $this->check_priority_exists( $hook, $priority );
    8286        $this->assertCount( 1, $hook->callbacks[ $priority ] );
    8387
     
    9599
    96100        $hook->add_filter( $hook_name, $callback_one, $priority, $accepted_args );
     101        $this->check_priority_exists( $hook, $priority );
    97102        $this->assertCount( 1, $hook->callbacks[ $priority ] );
    98103
    99104        $hook->add_filter( $hook_name, $callback_two, $priority + 1, $accepted_args );
     105        $this->check_priority_exists( $hook, $priority + 1 );
    100106        $this->assertCount( 1, $hook->callbacks[ $priority ] );
    101107        $this->assertCount( 1, $hook->callbacks[ $priority + 1 ] );
     
    110116
    111117        $hook->add_filter( $hook_name, $callback, $priority, $accepted_args );
     118        $this->check_priority_exists( $hook, $priority );
    112119        $this->assertCount( 1, $hook->callbacks[ $priority ] );
    113120
     
    124131
    125132        $hook->add_filter( $hook_name, $callback, $priority, $accepted_args );
     133        $this->check_priority_exists( $hook, $priority );
    126134        $this->assertCount( 1, $hook->callbacks[ $priority ] );
    127135
    128136        $hook->add_filter( $hook_name, $callback, $priority + 1, $accepted_args );
     137        $this->check_priority_exists( $hook, $priority + 1 );
    129138        $this->assertCount( 1, $hook->callbacks[ $priority ] );
    130139        $this->assertCount( 1, $hook->callbacks[ $priority + 1 ] );
     
    142151        $hook->add_filter( $hook_name, array( $c, 'action' ), 8, 1 );
    143152
    144         $this->assertSame( array( 5, 8, 10 ), array_keys( $hook->callbacks ) );
     153        $this->assertSame( array( 5, 8, 10 ), $this->get_priorities( $hook ) );
    145154    }
    146155
     
    149158
    150159        $this->hook->add_filter( 'remove_and_add', '__return_empty_string', 10, 0 );
    151 
     160        $this->check_priority_exists( $this->hook, 10 );
    152161        $this->hook->add_filter( 'remove_and_add', array( $this, '_filter_remove_and_add2' ), 11, 1 );
    153 
     162        $this->check_priority_exists( $this->hook, 11 );
    154163        $this->hook->add_filter( 'remove_and_add', array( $this, '_filter_remove_and_add4' ), 12, 1 );
    155 
     164        $this->check_priority_exists( $this->hook, 12 );
    156165        $value = $this->hook->apply_filters( '', array() );
    157166
     167        $this->assertSameSets( array( 10, 11, 12 ), $this->get_priorities( $this->hook ), 'The priorities should match this array' );
     168
    158169        $this->assertSame( '24', $value );
    159170    }
     
    163174
    164175        $this->hook->add_filter( 'remove_and_add', '__return_empty_string', 10, 0 );
    165 
     176        $this->check_priority_exists( $this->hook, 10 );
    166177        $this->hook->add_filter( 'remove_and_add', array( $this, '_filter_remove_and_add1' ), 11, 1 );
    167 
     178        $this->check_priority_exists( $this->hook, 11 );
    168179        $this->hook->add_filter( 'remove_and_add', array( $this, '_filter_remove_and_add2' ), 12, 1 );
    169 
     180        $this->check_priority_exists( $this->hook, 12 );
    170181        $value = $this->hook->apply_filters( '', array() );
     182
     183        $this->assertSameSets( array( 10, 11, 12 ), $this->get_priorities( $this->hook ), 'The priorities should match this array' );
    171184
    172185        $this->assertSame( '12', $value );
     
    184197        $this->hook->add_filter( 'remove_and_add', array( $this, '_filter_remove_and_add4' ), 12, 1 );
    185198
     199        $this->assertSameSets( array( 10, 11, 12 ), $this->get_priorities( $this->hook ), 'The priorities should match this array' );
     200
    186201        $value = $this->hook->apply_filters( '', array() );
    187202
     
    196211        $this->hook->remove_filter( 'remove_and_add', array( $this, '_filter_remove_and_add2' ), 11 );
    197212        $this->hook->add_filter( 'remove_and_add', array( $this, '_filter_remove_and_add2' ), 11, 1 );
    198 
     213        $this->check_priority_exists( $this->hook, 11 );
    199214        return $value . '2';
    200215    }
     
    206221
    207222        $this->hook->add_filter( 'remove_and_add', array( $this, '_filter_remove_and_recurse_and_add2' ), 11, 1 );
    208 
     223        $this->check_priority_exists( $this->hook, 11 );
    209224        return $value . '2';
    210225    }
     
    292307        $this->action_output .= '4';
    293308    }
     309
     310    protected function check_priority_exists( $hook, $priority ) {
     311        $priorities = $this->get_priorities( $hook );
     312
     313        $this->assertContains( $priority, $priorities );
     314    }
     315
     316    protected function get_priorities( $hook ) {
     317        $reflection          = new ReflectionClass( $hook );
     318        $reflection_property = $reflection->getProperty( 'priorities' );
     319        $reflection_property->setAccessible( true );
     320
     321        return $reflection_property->getValue( $hook );
     322    }
    294323}
Note: See TracChangeset for help on using the changeset viewer.