diff --git a/src/GridFS/StreamWrapper.php b/src/GridFS/StreamWrapper.php index 871e0b2bf..a5136b349 100644 --- a/src/GridFS/StreamWrapper.php +++ b/src/GridFS/StreamWrapper.php @@ -57,6 +57,14 @@ class StreamWrapper /** @var ReadableStream|WritableStream|null */ private $stream; + public function __destruct() + { + /* This destructor is a workaround for PHP trying to use the stream well + * after all objects have been destructed. This can cause autoloading + * issues and possibly segmentation faults during PHP shutdown. */ + $this->stream = null; + } + /** * Return the stream's file document. * @@ -88,6 +96,10 @@ public static function register($protocol = 'gridfs') */ public function stream_close() { + if (! $this->stream) { + return; + } + $this->stream->close(); } diff --git a/tests/GridFS/BucketFunctionalTest.php b/tests/GridFS/BucketFunctionalTest.php index 4ebb3fe0f..0a8523812 100644 --- a/tests/GridFS/BucketFunctionalTest.php +++ b/tests/GridFS/BucketFunctionalTest.php @@ -18,17 +18,22 @@ use function array_merge; use function call_user_func; use function current; +use function exec; use function fclose; use function fread; use function fwrite; use function hash_init; +use function implode; use function is_callable; use function min; use function sprintf; use function str_repeat; use function stream_get_contents; use function strlen; +use function strncasecmp; use function substr; +use const PHP_EOL; +use const PHP_OS; /** * Functional tests for the Bucket class. @@ -708,6 +713,29 @@ public function testExistingIndexIsReused() $this->assertIndexNotExists($this->chunksCollection->getCollectionName(), 'files_id_1_n_1'); } + public function testDanglingOpenWritableStream() + { + if (! strncasecmp(PHP_OS, 'WIN', 3)) { + $this->markTestSkipped('Test does not apply to Windows'); + } + + $path = __DIR__ . '/../../vendor/autoload.php'; + $command = <<test->selectGridFSBucket()->openUploadStream('filename', ['disableMD5' => true]);" 2>&1 +CMD; + + @exec( + $command, + $output, + $return + ); + + $this->assertSame(0, $return); + $output = implode(PHP_EOL, $output); + + $this->assertSame('', $output); + } + /** * Asserts that a collection with the given name does not exist on the * server.