Use static Closures or Closures in PHP?

5

As of PHP 5.4, Closures , when declared within the context of a method of the class (other than static methods), automatically inherits the funções anônimas as a reference of the class that contains it.

Example:

class StackOverflow
{
    protected $array = ['stack', 'overflow', 'portugues'];

    public function testClosure($string)
    {      
        $callback = function()
        {
            print_r($this);

            /*
                StackOverflow Object
                (
                    [array:protected] => Array
                        (
                            [0] => stack
                            [1] => overflow
                            [2] => portugues
                        )
                )
            */

            return 'stack';
        };

        return preg_replace_callback('/stick/', $callback, $string);
    }
}

(new StackOverflow)->testClosure('stick overflow');

As seen in the example, when we do $this , it will return the current instance of class print_r($this) .

However, if we made a small change and added the keyword StackOverflow before the declaration of the anonymous function, the variable static does not "import" the instance of class $this there in:

public function testClosure($string)
{
      // Closure static não importa o $this para o Escopo
      $callback = static function()
      {
          print_r($this); // Undefined variable: this
          return 'stack';
      };

      return preg_replace_callback('/stick/', $callback, $string);
}

As seen in the example, I'm using the StackOverflow function to be able to make a string change through a regex . That is, I do not need to have preg_replace_callback properly within the class, but I just want to use $this as a Closure .

My question is:

  • Since I will not use anything in the context of the current instance of the class, could we say that it is more performative to use callback ?

  • Or the question of static Closure being "imported" into the scope does not mean loss of performasse (since $this of $this does not receive a copy, but will only create the reference of the same instance of the class currently invoked)?

  • asked by anonymous 27.01.2015 / 13:07

    2 answers

    2

    I'm surprised that in one of these situations it is possible to access $this . A static function should never be able to do this. But again, we know how language developers do not think at all. They knew that this should not be accepted but they did not realize that it was possible to get around by putting the static function inside a non-static function.

    If it is not something documented I would be afraid to use it. Just because it works does not mean it's right. Nothing guarantees that it will work in the future if it is not documented. Someone will surely say that anyone who uses something undocumented deserves what happens to him in the future if that fails.

    So my official response is do not use .

    To tell you the truth, I do not know if this is making sense. Perhaps for lack of context is not easy to understand. Maybe it's me.

    Performance is certainly not relevant if you chose PHP. It is not a language that has that quality. The difference of doing something static or per instance will be at most tiny. Maybe none.

    I would question if you need to put this into a class. I just do not do it because I did not fully understand the problem.

    Under normal conditions I would say that a (normal) function that does not access anything from the instance should be declared static, to make it clear that this is the intention. Showing in the code what you want is more important than performance. Performance should only be considered if you measured and saw that it is not meeting the needs. Note that I am not talking about closure here, since closure is not documented according to the AP comment in question.

    If the documentation says that you can use a static closure , then the deadlock is whether or not you should use it. Unfortunately these questions could only be asked by those who have authority, the language developers. Even then I would only use it if they put it in the documentation.

        
    27.01.2015 / 13:30
    0

    According to PHP documentation , the purposes that could be applied using static in a Closure would be:

    • Prevent it from being bound to the context (Class) in which it is called.

    Example:

    class Foo
    {
        function __construct()
        {
            $func = static function() {
                var_dump($this);
            };
            $func();
        }
    };
    new Foo();
    

    The output would be:

      

    Notice: Undefined variable: this in% s on line% d

    • Prevent binding of $this of Closure to an object by calling method bindTo (and probably Closure::bind and Closure::call ).

      $func = static function() {
          // function body
      };
      
      $func = $func->bindTo(new StdClass);
      
      $func();
      

    A E_WARNING would be generated:

      Warning: Can not bind an instance to a static closure in / in / sLLS9 on line 5

    Apart from this, there is nothing more than detailed documentation, such as whether this implies performance gain or not.

        
    07.05.2018 / 19:10