Intereting Posts
Захватить текущий первый и последний день недели в php Как удалить знак вопроса из URL Несколько запросов Sub с помощью zend framework Выбор значений атрибутов на основе другого значения атрибута с помощью SimpleXML нужны ссылки preg_match_all Найдите ссылку youtube в строке PHP и преобразуйте ее в код встраивания? Как определить, установлен ли $ _POST? pdo dblib on centos 6.x Приложение Client Server с PHP и Python Могу ли я визуализировать представление, не возвращая его в контроллере действий в zend framework 2? Добавить поле для загрузки в регистровую форму с помощью CodeIgniter symfony2 добавить динамический параметр для маршрутизации, попробуйте с помощью пользовательского загрузчика Сохранить идентификатор сеанса после входа в систему CakePHP как распечатать изображение с помощью PHP: Printer Как я могу сделать регулярную переменную доступной в файлах, включенных методом класса?

Поддерживает ли PHP шаблон RAII? Как?

Большинство ресурсов на PHP никогда не касаются управления памятью, потому что сам язык довольно хорош для этого. Однако в PHP вы часто сталкиваетесь с внешними ресурсами, которые не являются обработкой базы данных, сеансами, транзакциями базы данных и т. Д. Эти внешние ресурсы можно было бы наиболее эффективно использовать с использованием какой-либо формы объекта RAII.

Первоначально я думал, что PHP использует схему сбора мусора, похожую на JVM или CLR, где концепция деструктора не существует. (Помните: каждый думает о сборке мусора неправильным образом – финализаторы не являются деструкторами!) Существует специальный метод __destruct , но я думал, что это «финализатор», похожий на финализатор Java или C #. По этой причине вы не можете использовать RAII на JVM или CLR (блоки using C # вы получите около 95% пути, но это немного отличается …).

Однако Google, похоже, указывает, что PHP поддерживает шаблон RAII , хотя я не могу найти подтверждение этого в документах PHP. Поддерживает ли язык этот язык и ставит логику очистки в __destruct достаточным для выполнения задач RAII?

Это почти тот же вопрос, что и Деструктор в PHP предсказуем? и ответ тот же. PHP использует refcounting, и он обещает, что деструктор будет вызываться немедленно, как только refcount будет равен нулю (обычно, когда объект выходит за рамки). Поэтому, если вы создаете объект и стараетесь не выходить из него, RAII жизнеспособна.

PHP использует подсчет ссылок, поэтому, когда вы закончите с переменной, она будет немедленно очищена. (Если вы не создаете циклы.) Это быстро освобождает ресурсы, поэтому вам вообще не нужно беспокоиться о явном управлении ресурсами, кроме того, чтобы не создавать циклы памяти.

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

Следующий класс ReturnHandler обеспечивает автоматический вызов обработчика, когда ReturnHandler выходит из области видимости. Вы можете иметь несколько return в своей функции ( myfunc ) без необходимости думать о выпуске ресурса перед каждым из них.

 /** * Automatically calls a handler before returning from a function. Usage: * * function myfunc() * { * $resource = new Resource(); * $rh = new ReturnHandler( function() use ($resource) { $resource->release(); } ); * // ... * if(...) { * return; // look, ma, automatic clean up! * } * } */ class ReturnHandler { private $return_handler; public function __construct( $return_handler ) { $this->return_handler = $return_handler; } public function __destruct() { $handler = $this->return_handler; $handler(); } } 

Вот тест на это:

 class ReturnHandlerTest extends PHPUnit_Framework_TestCase { private static function trigger_return_handler(&$var) { $rh = new ReturnHandler(function() use (&$var) { $var++; } ); } public function test() { $a = 0; $this->assertEquals(0, $a); self::trigger_return_handler($a); $this->assertEquals(1, $a); } }