Make WordPress Core


Ignore:
Timestamp:
09/18/2023 12:39:18 PM (3 years 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.