PHP.mk документација

Closure::bindTo

Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.

closure.bindto.php PHP.net прокси Преводот се освежува
Оригинал на PHP.net
Патека closure.bindto.php Локална патека за оваа страница.
Извор php.net/manual/en Оригиналниот HTML се реупотребува и локално се стилизира.
Режим Прокси + превод во позадина Кодовите, табелите и белешките остануваат читливи во истиот тек.
Closure::bindTo

Референца за `closure.bindto.php` со подобрена типографија и навигација.

closure.bindto.php

Closure::bindTo

(PHP 5 >= 5.4.0, PHP 7, PHP 8)

Closure::bindTo (PHP 5 >= 5.4.0, PHP 7, PHP 8)

= NULL

public Closure::bindTo(?object $newThis, object|string|null $newScope (PHP 5 >= 5.3.0, PHP 7, PHP 8)): ?Затворање

Конвертира повикувач во затворање анонимна функција Ја дуплира затвореноста со нов поврзан објект и класен опсег

со истото тело и поврзани променливи како оваа, но со можност за различен поврзан објект и нов класен опсег. $this „Поврзаниот објект“ ја одредува вредноста newScope parameter.

ќе има во телото на функцијата и „класниот опсег“ претставува класа која одредува кои приватни и заштитени членови ќе може да ги пристапи анонимната функција. Имено, членовите што ќе бидат видливи се исти како да беше анонимната функција метод на класата дадена како вредност на newThis Статичните затворености не можат да имаат поврзан објект (вредноста на параметарот nullтреба да биде

), но овој метод сепак може да се користи за промена на нивниот класен опсег. null Овој метод ќе осигури дека за нестатична затвореност, имањето поврзан примерок ќе подразбира да биде со опсег и обратно. За таа цел, нестатичните затворености на кои им е даден опсег, но

Забелешка:

примерок се прават статични и нестатични затворености без опсег на кои им е даден примерок што не е null се со опсег до неопределена класа. cloning instead.

Параметри

newThis

Ако сакате само да ги дуплирате анонимните функции, можете да го користите null Објектот на кој треба да биде поврзана дадената анонимна функција, или

newScope

за затвореноста да биде неповрзана.

Вратени вредности

Повикувачот за конвертирање. Затворање објект или null при неуспех.

Примери

Пример #1 Класниот опсег на кој треба да биде поврзана затвореноста, или 'static' за да се задржи сегашниот. Ако е даден објект, наместо тоа ќе се користи типот на објектот. Ова ја одредува видливоста на заштитените и приватните методи на поврзаниот објект. Не е дозволено да се помине (објект од) внатрешна класа како овој параметар. example

<?php

class A
{
private
$val;

public function
__construct($val)
{
$this->val = $val;
}

public function
getClosure()
{
// Returns closure bound to this object and scope
return function() {
return
$this->val;
};
}
}

$ob1 = new A(1);
$ob2 = new A(2);

$cl = $ob1->getClosure();
echo
$cl(), "\n";

$cl = $cl->bindTo($ob2);
echo
$cl(), "\n";

?>

Горниот пример ќе прикаже нешто слично на:

1
2

Види Исто така

Белешки од корисници 8 белешки

- Дуплира анонимна функција со специфичен поврзан објект и класен опсег
пред 11 години
We can use the concept of bindTo to write a very small Template Engine:

#############
index.php
############

<?php

class Article{
    private $title = "This is an article";
}

class Post{
    private $title = "This is a post";
}

class Template{

    function render($context, $tpl){

        $closure = function($tpl){
            ob_start();
            include $tpl;
            return ob_end_flush();
        };

        $closure = $closure->bindTo($context, $context);
        $closure($tpl);

    }

}

$art = new Article();
$post = new Post();
$template = new Template();

$template->render($art, 'tpl.php');
$template->render($post, 'tpl.php');
?>

#############
tpl.php
############
<h1><?php echo $this->title;?></h1>
Nezar Fadle
пред 13 години
You can do pretty Javascript-like things with objects using closure binding:

<?php
trait DynamicDefinition {
    
    public function __call($name, $args) {
        if (is_callable($this->$name)) {
            return call_user_func($this->$name, $args);
        }
        else {
            throw new \RuntimeException("Method {$name} does not exist");
        }
    }
    
    public function __set($name, $value) {
        $this->$name = is_callable($value)? 
            $value->bindTo($this, $this): 
            $value;
    }
}

class Foo {
    use DynamicDefinition;
    private $privateValue = 'I am private';
}

$foo = new Foo;
$foo->bar = function() {
    return $this->privateValue;
};

// prints 'I am private'
print $foo->bar();

?>
tatarynowicz at gmail dot com
пред 14 години
Private/protected members are accessible if you set the "newscope" argument (as the manual says).

<?php
$fn = function(){
    return ++$this->foo; // increase the value
};

class Bar{
    private $foo = 1; // initial value
}

$bar = new Bar();

$fn1 = $fn->bindTo($bar, 'Bar'); // specify class name
$fn2 = $fn->bindTo($bar,  $bar); // or object

echo $fn1(); // 2
echo $fn2(); // 3
Анонимен
пред 7 години
If you want to unbind completely the closure and the scope you need to set both to null:

<?php
class MyClass
{
    public $foo = 'a';
    protected $bar = 'b';
    private $baz = 'c';

    /**
     * @return array
     */
    public function toArray()
    {
        // Only public variables
        return (function ($obj) {
            return get_object_vars($obj);
        })->bindTo(null, null)($this);
    }
}
?>

In this example, only the public variables of the class are exported (foo).

If you use the default scope (->bindTo(null)) also protected and private variables are exported (foo, bar and baz).

It was hard to figure it out because there is nowhere mentioned in the documentation that you can use null as a scope.
luc на s dot illi dot be
пред 9 години
Access private members of parent classes; playing with the scopes:
<?PHP
class Grandparents{ private $__status1 = 'married'; }
class Parents extends Grandparents{ private $__status2 = 'divorced'; }
class Me extends Parents{ private $__status3 = 'single'; }

$status1_3 = function()
{
    $this->__status1 = 'happy';
    $this->__status2 = 'happy';
    $this->__status3 = 'happy';
};

$status1_2 = function()
{
    $this->__status1 = 'happy';
    $this->__status2 = 'happy';
};

// test 1:
$c = $status1_3->bindTo($R = new Me, Parents::class);            
#$c();    // Fatal: Cannot access private property Me::$__status3

// test 2:
$d = $status1_2->bindTo($R = new Me, Parents::class);
$d();
var_dump($R);
/*
object(Me)#5 (4) {
  ["__status3":"Me":private]=>
  string(6) "single"
  ["__status2":"Parents":private]=>
  string(5) "happy"
  ["__status1":"Grandparents":private]=>
  string(7) "married"
  ["__status1"]=>
  string(5) "happy"
}
*/

// test 3:
$e = $status1_3->bindTo($R = new Me, Grandparents::class);    
#$e(); // Fatal: Cannot access private property Me::$__status3

// test 4:
$f = $status1_2->bindTo($R = new Me, Grandparents::class);    
$f();
var_dump($R);
/*
object(Me)#9 (4) {
  ["__status3":"Me":private]=>
  string(6) "single"
  ["__status2":"Parents":private]=>
  string(8) "divorced"
  ["__status1":"Grandparents":private]=>
  string(5) "happy"
  ["__status2"]=>
  string(5) "happy"
}
*/
?>

Clear the stack trace:
<?PHP
use Exception;
use ReflectionException;

$c = function()
{
    $this->trace = [];
};

$c = $c->bindTo($R = new ReflectionException, Exception::class);
$c();

try
{
    throw $R;
}
catch(ReflectionException $R)
{
    var_dump($R->getTrace());
}
/*
array(0) {
}
*/
?>
amica на php-resource dot de
пред 14 години
With rebindable $this at hand it's possible to do evil stuff:

<?php
    class A {
        private $a = 12;
        private function getA () {
            return $this->a;
        }
    }
    class B {
        private $b = 34;
        private function getB () {
            return $this->b;
        }
    }
    $a = new A();
    $b = new B();
    $c = function () {
        if (property_exists($this, "a") && method_exists($this, "getA")) {
            $this->a++;
            return $this->getA();
        }
        if (property_exists($this, "b") && method_exists($this, "getB")) {
            $this->b++;
            return $this->getB();
        }
    };
    $ca = $c->bindTo($a, $a);
    $cb = $c->bindTo($b, $b);
    echo $ca(), "\n"; // => 13
    echo $cb(), "\n"; // => 35
?>
malferov на gmail dot com
пред 2 години
If you, like me, did not immediately understand what exactly "(an object of) an internal class" in the documentation about the 'newScope' parameter:

By an internal class, the documentation means any internal PHP class such as 'stdClass', 'Closure', 'WeakMap', and etc:

<?php

class A {}
$a = new A();
$closure = fn() => null;

$binded = $closure->bindTo($a, 'stdClass',); // Cannot bind closure to scope of internal class stdClass
$binded = $closure->bindTo($a, $closure,); // Warning: Cannot bind closure to scope of internal class Closure etc.
Олександр Калаиџи
пред 4 години
Get all object vars without using Reflection:

<?php

declare(strict_types=1);

class A
{
    private $foo = 'foo';
    protected $bar = 'bar';
    public $buz = 'buz';
}

function get_object_vars_all($object): array
{
    if (!\is_object($object)) {
        throw new \InvalidArgumentException(sprintf('The argument should be an object, "%s" given.', get_debug_type($object)));
    }

    $closure = function () {
        return get_object_vars($this);
    };

    return $closure->bindTo($object, $object)();
}

$a = new A();

var_dump(get_object_vars($a));
var_dump(get_object_vars_all($a));

?>

The output: 

array(1) {
  ["buz"]=>
  string(3) "buz"
}
array(3) {
  ["foo"]=>
  string(3) "foo"
  ["bar"]=>
  string(3) "bar"
  ["buz"]=>
  string(3) "buz"
}
Навигација

Прелистувај сродни теми и функции.

На оваа страница

Автоматски outline од активната документација.

Насловите ќе се појават тука по вчитување.

Попрегледно читање

Примерите, changelog табелите и user notes се визуелно издвоени за да не се губат во долгата содржина.

Брз совет Користи го outline-от Скокни директно на главните секции од активната страница.
Извор Оригиналниот линк останува достапен Кога ти треба целосен upstream context, отвори го PHP.net во нов tab.