[wp-trac] [WordPress Trac] #46635: Improve identifying of non–trivial callbacks in hooks

WordPress Trac noreply at wordpress.org
Wed Apr 3 21:15:27 UTC 2019


#46635: Improve identifying of non–trivial callbacks in hooks
-------------------------+-------------------------------
 Reporter:  Rarst        |       Owner:  (none)
     Type:  enhancement  |      Status:  new
 Priority:  normal       |   Milestone:  Awaiting Review
Component:  General      |     Version:
 Severity:  normal       |  Resolution:
 Keywords:               |     Focuses:  coding-standards
-------------------------+-------------------------------

Comment (by schlessera):

 Here's another proposal on how this could be solved.

 First, I'd create an object that let's us wrap the closure in an object
 together with an ID.

 {{{#!php
 <?php
 final class RemovableClosure {

         private $id;
         private $callable;

         /**
          * Instantiate a RemovableClosure object.
          *
          * @param string   $id       Identifier of the closure.
          * @param callable $callable Callable logic for the closure.
          */
         public function __construct( $id, callable $callable ) {
                 $this->id       = $id;
                 $this->callable = $callable;
         }

         /**
          * Get the ID of the closure.
          *
          * @return mixed
          */
         public function get_id() {
                 return $this->id;
         }

         /**
          * Invoke the closure.
          *
          * @param mixed ...$arguments Arguments to pass to the closure.
          * @return mixed Result of invoking the closure.
          */
         public function __invoke( ...$arguments ) {
             $callable = $this->callable;

                 return $callable( ...$arguments );
         }
 }
 }}}

 This is valid PHP 5.6 code, so it could be committed together with the
 minimum version bump if WordPress does indeed enforce that minimum before
 updating. If not, the `__invokde()` would have to be adapted.

 Adding an action/filter and removing it again would be done as follows:
 {{{#!php
 <?php
 add_action(
         'some_action',
         new RemovableClosure( 'my_closure',function ( $some_arg ) {
                 echo "{$some_arg} was passed.";
         } )
 );

 remove_action( 'some_action', 'my_closure' );
 }}}

 Internally, the only thing that would need to be changed is to add a
 condition to `_wp_filter_build_unique_id()` function:
 {{{#!php
 <?php
 function _wp_filter_build_unique_id($tag, $function, $priority) {
     // [ ... ]

     if ( $function instanceof RemovableClosure ) {
         return $function->get_id();
     }

     // [ ... ]
 }
 }}}

 I haven't looked into the code in detail, so I have missed a few nuances,
 but I think the basic principle should work.

 And please, y'all, when building new functionality, please at least
 consider objects... PHP 7+ is built 100% around objects, there's only
 drawbacks and performance penalties to be had when still sticking to
 procedural code by default. This does not mean we should rewrite
 WordPress, but I rarely see anyone resorting to objects to solve new
 problems in here.

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


More information about the wp-trac mailing list