[wp-trac] [WordPress Trac] #47678: Modernize/simplify current_user_can()

WordPress Trac noreply at wordpress.org
Sun Oct 20 09:33:07 UTC 2019


#47678: Modernize/simplify current_user_can()
-------------------------------------+-------------------------------------
 Reporter:  jrf                      |       Owner:  pento
     Type:  task (blessed)           |      Status:  closed
 Priority:  normal                   |   Milestone:  5.3
Component:  Role/Capability          |     Version:  trunk
 Severity:  normal                   |  Resolution:  fixed
 Keywords:  has-patch has-unit-      |     Focuses:  performance, coding-
  tests has-dev-note                 |  standards
PR Number:                           |
-------------------------------------+-------------------------------------

Comment (by sinkluxe):

 Replying to [ticket:47678 jrf]:
 > As support for PHP < 5.6.20 has been dropped, certain modernizations can
 now be applied to WP.
 >
 > The
 [https://developer.wordpress.org/reference/functions/current_user_can/
 `current_user_can()`] function is used pretty often during a regular WP
 page-load and is a good candidate for modernization.
 >
 > The patch I'm attaching contains this modernization.
 >
 > To understand what I'm doing here, let's step through it.
 >
 > **Step 1: simplify the function.**
 >
 > The function contains the following redundant code:
 > {{{#!php
 > <?php
 >       $args = array_slice( func_get_args(), 1 );
 >       $args = array_merge( array( $capability ), $args );
 > }}}
 >
 > What is happening here is that:
 > 1. All arguments passed to the function are retrieved.
 > 2. The first argument - the named parameter `$capability` - is sliced
 off, so `$args` is now only the arguments after `$capability`.
 > 3. The arguments are merged back together in the same order as they were
 originally.
 >
 > I've not done the code archeology to see how this code ever made into
 the code base as I'm not here to name and shame, but let's get rid of it.
 >
 > Replacing this part of the code with the below has the exact same effect
 and removes two (badly performing) function calls:
 > {{{#!php
 > <?php
 >       $args = func_get_args();
 > }}}
 >
 > To prove the point, see: https://3v4l.org/BqYY0
 >
 >
 > **Step 2: modernize the function declaration.**
 >
 > The function currently declares one named, required parameter
 `$capability` and via the above mentioned `func_get_args()` allows for
 additional arguments to be passed.
 > This is also documented as such in the function documentation.
 > {{{#!php
 > <?php
 > /**
 >  * ...
 >  * @param string $capability Capability name.
 >  * @param mixed  ...$args    Optional further parameters, typically
 starting with an object ID.
 >  * @return bool Whether the current user has the given capability. If
 `$capability` is a meta cap and `$object_id` is
 >  *              passed, whether the current user has the given meta
 capability for the given object.
 >  */
 > function current_user_can( $capability ) {
 > }}}
 >
 > PHP 5.6 introduced [https://www.php.net/manual/en/migration56.new-
 features.php#migration56.new-features.variadics variadic functions using
 the spread operator].
 >
 > Now, we could make `$capability` variadic and remove the call to
 `func_get_args()`, but that would make the `$capability` parameter
 optional.
 > {{{#!php
 > <?php
 > function current_user_can( ...$capability ) {
 > }}}
 >
 > Making the `$capability` parameter optional is not the intention as it:
 > * Changes the function signature.
 > * Could break the subsequent function call to `WP_User::has_cap()` to
 which `$capability` is passed, where `$capability` is not optional.
 >
 > So, instead, we add a new variadic (and therefore by nature optional)
 parameter `$args`.
 > {{{#!php
 > <?php
 > function current_user_can( $capability, ...$args ) {
 > }}}
 >
 > This is completely in line with the existing function documentation, so
 no changes are needed to the docs.
 >
 > As things stand at this moment, we would still be overwritting `$args`
 in the function via the call to `func_get_args()`, but that's ok for now,
 we'll get to that in step 3.
 >
 >
 >
 > **Step 3: modernize the return.**
 >
 > Now, let's look at the part of the function which is returning the
 result:
 > {{{#!php
 > <?php
 >       $args = func_get_args();
 >
 >       return call_user_func_array( array( $current_user, 'has_cap' ),
 $args );
 > }}}
 >
 > `call_user_func_array()` is used here as `$args` would contain a
 variable number of arguments and prior to PHP 5.6, there was no other way
 to pass those on to another function which expected multiple arguments.
 >
 > However, PHP 5.6 also introduced
 [https://www.php.net/manual/en/migration56.new-features.php#migration56
 .new-features.splat argument unpacking using the spread operator].
 >
 > Now suddenly, the call to the badly performing `call_user_func_array()`
 is no longer necessary and we can call `$current_user->has_cap()`
 directly, unpacking the variadic `$args` in the function call:
 >
 > {{{#!php
 > <?php
 >       return $current_user->has_cap( $capability, ...$args );
 > }}}
 >
 >
 > So, that's how we get to the actual patch.
 >
 > All together, this patch gets rid of four redundant function calls,
 three of which were calls to functions with a bad reputation for
 performance.
 >
 > So, even though small, this patch should give WP a very tiny performance
 boost.
 >
 >
 > **Unit tests**
 >
 > There are numerous tests in the
 [https://core.trac.wordpress.org/browser/trunk/tests/phpunit/tests/user/capabilities.php
 `Tests_User_Capabilities`] class covering this change already.
 >
 > All of these tests still pass after this change.
 >
 > And once I've uploaded this patch, I will start a Travis run just to
 make sure and quieten any nerves anyone may have about this patch.
 >
 > /cc @pento

 لیست قیمت فر توکار استیل البرز
 لیست قیمت بروز فر توکار استیل البرز  به همراه راهنمای خرید فر توکار -خرید
 فر استیل البرز از فروشگاه لوکس
 Price list of stainless steel Alborz oven
 Price List of Built-in Steel Alborz Oven with Shopping Guide Built-in Oven
 - Buy Luxury Alborz Oven from Luxury Store
 https://reluxe.ir/category/steel-alborz-built-in-oven

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/47678#comment:84>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list