From 15a92f070eed99fa24c5cf606fc0ab86cc50bd66 Mon Sep 17 00:00:00 2001 From: Dustin Wilson Date: Mon, 7 Feb 2022 13:43:20 -0600 Subject: [PATCH] Added Document::destroy() --- README.md | 16 ++++++++++++++++ lib/Document.php | 7 ++++++- tests/cases/TestDocument.php | 31 ++++++++++++++++++++++++++++++- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d1d0ac6..b9e13ac 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,8 @@ partial class Document extends Node implements \ArrayAccess { ?string $charset = null ); + public function destroy(): void; + public function registerXPathFunctions( string|array|null $restrict = null ): void; @@ -116,6 +118,20 @@ Creates a new `MensBeam\HTML\DOM\Document` object. gb18030 ``` +#### MensBeam\HTML\DOM\Document::destroy #### + +Destroys references associated with the instance so it may be garbage collected by PHP. Because of the way PHP's garbage collection is and the poor state of the library PHP DOM is based off of, references must be kept in userland for every created document. Therefore, this method should unfortunately be manually called whenever the document is not needed anymore. + +##### Example ##### + +```php +namespace MensBeam\HTML\DOM; + +$d = new Document(); +$d->destroy(); +unset($d); +``` + #### MensBeam\HTML\DOM\Document::registerXPathFunctions #### Register PHP functions as XPath functions. Works like `\DOMXPath::registerPhpFunctions` except that the php namespace does not need to be registered. diff --git a/lib/Document.php b/lib/Document.php index 3ff33e2..ba4d458 100644 --- a/lib/Document.php +++ b/lib/Document.php @@ -617,6 +617,11 @@ class Document extends Node implements \ArrayAccess { return $this->_innerNode->getWrapperNode($this->_innerNode->createTextNode($data)); } + public function destroy(): void { + self::$cache->delete($this); + self::$cache->delete($this->_innerNode); + } + public function getElementsByName(string $elementName): NodeList { # The getElementsByName(elementName) method steps are to return a live NodeList # containing all the HTML elements in that document that have a name attribute @@ -812,7 +817,7 @@ class Document extends Node implements \ArrayAccess { } - public function __toString() { + public function __toString(): string { return $this->serialize(); } } \ No newline at end of file diff --git a/tests/cases/TestDocument.php b/tests/cases/TestDocument.php index c293e8f..e26f2cc 100644 --- a/tests/cases/TestDocument.php +++ b/tests/cases/TestDocument.php @@ -18,7 +18,8 @@ use MensBeam\HTML\DOM\{ Text, XMLDocument }; -use org\bovigo\vfs\vfsStream; +use MensBeam\HTML\DOM\Inner\Reflection, + org\bovigo\vfs\vfsStream; /** @covers \MensBeam\HTML\DOM\Document */ @@ -315,6 +316,34 @@ class TestDocument extends \PHPUnit\Framework\TestCase { } + /** + * @covers \MensBeam\HTML\DOM\Document::__construct + * @covers \MensBeam\HTML\DOM\Document::destroy + * @covers \MensBeam\HTML\DOM\DOMImplementation::__construct + * @covers \MensBeam\HTML\DOM\Node::__construct + * @covers \MensBeam\HTML\DOM\Inner\Document::__construct + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::delete + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::has + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::key + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::set + * @covers \MensBeam\HTML\DOM\Inner\Reflection::getProtectedProperty + */ + public function testMethod_destroy(): void { + $d = new Document(); + + $reflection = new \ReflectionClass(Document::class); + $cache = $reflection->getStaticPropertyValue('cache'); + $innerArrayCount = count(Reflection::getProtectedProperty($cache, 'innerArray')); + $wrapperArrayCount = count(Reflection::getProtectedProperty($cache, 'wrapperArray')); + + $d->destroy(); + + $cache = $reflection->getStaticPropertyValue('cache'); + $this->assertNotEquals(count(Reflection::getProtectedProperty($cache, 'innerArray')), $innerArrayCount); + $this->assertNotEquals(count(Reflection::getProtectedProperty($cache, 'wrapperArray')), $wrapperArrayCount); + } + + /** * @covers \MensBeam\HTML\DOM\Document::getElementsByName *