define a closure as method from class

后端 未结 4 410
Happy的楠姐
Happy的楠姐 2020-12-18 21:34

i\'m trying to play with php5.3 and closure.

I see here (Listing 7. Closure inside an object : http://www.ibm.com/developerworks/opensource/library/os-php-5.3new2/in

4条回答
  •  南笙
    南笙 (楼主)
    2020-12-18 22:01

    Well, the whole reason that you can't use $this, is because the closure is an object in the background (the Closure class).

    There are two ways around this. First, is add the __invoke method (What's called if you call $obj())..

    class Dog {
    
        public function __invoke($method) {
            $args = func_get_args();
            array_shift($args); //get rid of the method name
            if (is_callable(array($this, $method))) {
                return call_user_func_array(array($this, $method), $args);
            } else {
                throw new BadMethodCallException('Unknown method: '.$method);
            }
        }
    
        public function greet($greeting) {
            $self = $this;
            return function() use ($greeting, $self) {
                $self('do_greet', $greeting);
            };
        }
    
        protected function do_greet($greeting) {
            echo "$greeting, I am a {$this->_color} dog named {$this->_name}.";
        }
    }
    

    If you want the closure to not change if you modify the host object, you can just change the return function to something like:

    public function greet($greeting) {
        $self = (clone) $this;
        return function() use ($greeting, $self) {
            $self('do_greet', $greeting);
        };
    }
    

    The other option, is to provide a generic getter:

    class Dog {
    
        public function __get($name) {
            return isset($this->$name) ? $this->$name : null;
        }
    
    }
    

    For more information, see: http://www.php.net/manual/en/language.oop5.magic.php

提交回复
热议问题