Объект не уничтожается до конца скрипта, если он регистрирует spl_autoload_register ();

Объект не уничтожается до завершения сценария, может кто-то объяснить, почему с помощью spl_autoload_register() предотвращает разрушение объекта при unset(),

Метод деструктора будет вызываться, как только не будет никаких других ссылок на конкретный объект или в каком-либо порядке во время последовательности выключения.

Есть ли spl_autoload_register() есть ссылка на объект, который его зарегистрировал или что происходит?

class MyAutoLoader {

public function registerAutoLoader() {

spl_autoload_register(function ($class) {

});

}

public function __destruct() {
echo 'Destroying: ' . get_class($this) . "<br/>";
}

}

$MyAutoLoader = new MyAutoLoader();

$MyAutoLoader->registerAutoLoader();

unset($MyAutoLoader);

echo 'End of script<br/>';

//End of script
//Destroying: MyAutoLoader

1

Решение

Есть ли у spl_autoload_register () ссылка на объект, который его зарегистрировал, или что происходит?

Да, это так. Но не потому, что spl_autoload_register был вызван внутри класса. Это происходит из-за вашей Closure,

Как вы можете читать в ручную:

Начиная с PHP 5.4.0, когда он объявлен в контексте класса, текущий класс автоматически связывается с ним, делая $ this доступным внутри области действия функции. Если это автоматическое связывание текущего класса нежелательно, то вместо него могут использоваться статические анонимные функции.

Когда closure был создан внутри класса, он будет автоматически связывать псевдо-переменную $this, Тогда ваш экземпляр будет иметь две ссылки:

  • $MyAutoLoader переменная;
  • Closure перешел к spl_autoload_register,

Я переписал ваш пример с несколькими отличиями, которые вы можете увидеть поведение:

class MyAutoLoader {

private $instance = "Outside";

public function registerAutoLoader(Closure $closure = null) {

//If a closure ins't passed as parameter, a new one will be created
if (!$closure instanceof Closure)
{
$this->instance = "Inside";
//A closure created inside a class will bound the pseudo-variable $this
$closure = function ($class) {};
}

spl_autoload_register($closure);

}

public function __destruct() {
printf('Destroying: %s - %s instance<br/>' , get_class($this) , $this->instance);
}

}

$MyAutoLoader = new MyAutoLoader();
$MyAutoLoader->registerAutoLoader();

$MyAutoLoader2 = new MyAutoLoader();

//A closure created outside of a class doesn't have the class scope
$MyAutoLoader2->registerAutoLoader(function($class){});

unset($MyAutoLoader , $MyAutoLoader2);

echo 'End of script<br/>';

И результат будет:

Destroying: MyAutoLoader - Outside the instance
End of script
Destroying: MyAutoLoader - Inside the instance

В последнем примере Closure был создан из области видимости класса. Так что только переменная $MyAutoLoader2 имеет экземпляр класса.

Другой возможный пример может быть:

class MyAutoLoader {

public function registerAutoLoader(Closure $closure) {

//Binding the class scope to the closure
$closure = $closure->bindTo($this);

spl_autoload_register($closure);

}

public function __destruct() {
printf('Destroying: %s <br/>' , get_class($this));
}

}

$MyAutoLoader = new MyAutoLoader();
$MyAutoLoader->registerAutoLoader(function($class){});
unset($MyAutoLoader);

echo 'End of script<br/>';

В этом последнем примере я создаю Closure вне класса, но я связываю область видимости с классом, создавая новую ссылку на MyAutoLoader учебный класс. Результатом будет:

End of script
Destroying: MyAutoLoader

Еще несколько советов от bind а также bindTo Вы можете прочитать по ссылке ниже:

Как я могу вызвать функцию ReflectionFunction, закрывающую замыкание, использующее $ this?

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector