Closures

Closures

Có một lớp đại diện cho các hàm không tên (anonymous functions) tên là Closures. Trong class này có các hàm để thay đổi context (ngữ cảnh) của hàm được gọi. Thay đổi context cũng có nghĩa rằng thay đổi nội dung con trỏ $this.

Closure::bindTo()

Khi gọi $closure->bindTo($object) thì sẽ trả về một closure mới với với con trỏ $this lúc này được trỏ vào đối tượng $object.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<?php
class A {
  function __construct($val) {
    $this->val = $val;
  }
}

$closure = function($prefix) {
  echo $prefix . $this->val . "\n";
};

$object1 = new A(1);
$object2 = new A(2);

$aClosure1 = $closure->bindTo($object1);
$aClosure2 = $closure->bindTo($object2);

$aClosure1('Number is '); // Number is 1
$aClosure2('Number is '); // Number is 2

Hàm bindTo tương đương với class A nhúng hàm closure trong thân hàm class. Object sẽ mượn hàm này để thực thi với context của nó.

Hàm static Closure::bind()

Hàm Closure::bind() tương tự hàm Closure::bindTo() nhưng hàm này là hàm static. Hàm này nhận vào tham số là $closure$object mà con trỏ $this trỏ tới và trả về một closure mới.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<?php
class A {
  function __construct($val) {
    $this->val = $val;
  }
}

$closure = function($prefix) {
  echo $prefix . $this->val . "\n";
};

$object1 = new A(1);
$object2 = new A(2);

$aClosure1 = Closure::bind($closure, $object1);
$aClosure2 = Closure::bind($closure, $object2);

$aClosure1('Number is '); // Number is 1
$aClosure2('Number is '); // Number is 2

Tham số thứ ba scrope của hàm, mặc định là static. Hàm này được sử dụng với static closure.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<?php
class A {
  private static $foo = 1;
}

class B {
  private static $foo = 2;
}

// static closure
$closure = static function($prefix) {
  echo $prefix . static::$foo . "\n";
};

$aClosure1 = Closure::bind($closure, null, A::class);
$aClosure2 = Closure::bind($closure, null, B::class);

$aClosure1('Number is '); // Number is 1
$aClosure2('Number is '); // Number is 2

Hàm Closure::call

Hàm này bind xong sẽ thực thi hàm luôn, không như hai hàm bindbindTo chỉ bind thôi. Thực thi hàm này cần context của closure (mà con trỏ $this trỏ tới), cùng với các tham số khi thực thi closure.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?php
class A {
  function __construct($val) {
    $this->val = $val;
  }
}

$closure = function($prefix) {
  echo $prefix . $this->val . "\n";
};

$object = new A(1);
$closure->call($object, 'Number is '); // Number is 1