• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • Closure::bind

    (PHP 5 >= 5.4.0, PHP 7)

    复制一个闭包,绑定指定的$this对象和类作用域。

    说明

    publicstaticClosure::bind(Closure$closure,object $newthis[,mixed $newscope= 'static']): Closure

    这个方法是Closure::bindTo()的静态版本。查看它的文档获取更多信息。

    参数

    $closure

    需要绑定的匿名函数。

    $newthis

    需要绑定到匿名函数的对象,或者NULL创建未绑定的闭包。

    $newscope

    想要绑定给闭包的类作用域,或者'static'表示不改变。如果传入一个对象,则使用这个对象的类型名。类作用域用来决定在闭包中$this 对象的私有、保护方法的可见性。 The class scope to which associate the closure is to be associated, or 'static' to keep the current one. If an object is given, the type of the object will be used instead. This determines the visibility of protected and private methods of the bound object.

    返回值

    返回一个新的Closure对象或者在失败时返回FALSE

    范例

    Example #1 Closure::bind()实例

    <?php
    class A {
        private static $sfoo = 1;
        private $ifoo = 2;
    }
    $cl1 = static function() {
        return A::$sfoo;
    };
    $cl2 = function() {
        return $this->ifoo;
    };
    $bcl1 = Closure::bind($cl1, null, 'A');
    $bcl2 = Closure::bind($cl2, new A(), 'A');
    echo $bcl1(), "\n";
    echo $bcl2(), "\n";
    ?>
    

    以上例程的输出类似于:

    1
    2
    

    参见

    • 匿名函数
    • Closure::bindTo() 复制当前闭包对象,绑定指定的$this对象和类作用域。
    With this class and method, it's possible to do nice things, like add methods on the fly to an object.
    MetaTrait.php
    <?php
    trait MetaTrait
    {
      
      private $methods = array();
     
      public function addMethod($methodName, $methodCallable)
      {
        if (!is_callable($methodCallable)) {
          throw new InvalidArgumentException('Second param must be callable');
        }
        $this->methods[$methodName] = Closure::bind($methodCallable, $this, get_class());
      }
     
      public function __call($methodName, array $args)
      {
        if (isset($this->methods[$methodName])) {
          return call_user_func_array($this->methods[$methodName], $args);
        }
     
        throw RunTimeException('There is no method with the given name to call');
      }
     
    }
    ?>
    test.php
    <?php
    require 'MetaTrait.php';
     
    class HackThursday {
      use MetaTrait;
     
      private $dayOfWeek = 'Thursday';
     
    }
     
    $test = new HackThursday();
    $test->addMethod('when', function () {
      return $this->dayOfWeek;
    });
     
    echo $test->when();
    ?>
    
    If you need to validate whether or not a closure can be bound to a PHP object, you will have to resort to using reflection.
    <?php
    /**
     * @param \Closure $callable
     *
     * @return bool
     */
    function isBindable(\Closure $callable)
    {
      $bindable = false;
      $reflectionFunction = new \ReflectionFunction($callable);
      if (
        $reflectionFunction->getClosureScopeClass() === null
        || $reflectionFunction->getClosureThis() !== null
      ) {
        $bindable = true;
      }
      return $bindable;
    }
    ?>