mirror of
https://github.com/Ne-Lexa/php-zip.git
synced 2025-08-29 17:59:55 +02:00
Fixed problem with cloning a zip container.
This commit is contained in:
@@ -4,18 +4,27 @@ namespace PhpZip\Model\Data;
|
||||
|
||||
use PhpZip\Model\ZipData;
|
||||
use PhpZip\Model\ZipEntry;
|
||||
use PhpZip\ZipFile;
|
||||
|
||||
/**
|
||||
* Class ZipNewData.
|
||||
* The class contains a streaming resource with new content added to the ZIP archive.
|
||||
*/
|
||||
class ZipNewData implements ZipData
|
||||
{
|
||||
/** @var resource */
|
||||
private $stream;
|
||||
/**
|
||||
* A static variable allows closing the stream in the destructor
|
||||
* only if it is its sole holder.
|
||||
*
|
||||
* @var array<int, int> array of resource ids and the number of class clones
|
||||
*/
|
||||
private static $guardClonedStream = [];
|
||||
|
||||
/** @var ZipEntry */
|
||||
private $zipEntry;
|
||||
|
||||
/** @var resource */
|
||||
private $stream;
|
||||
|
||||
/**
|
||||
* ZipStringData constructor.
|
||||
*
|
||||
@@ -38,6 +47,12 @@ class ZipNewData implements ZipData
|
||||
} elseif (\is_resource($data)) {
|
||||
$this->stream = $data;
|
||||
}
|
||||
|
||||
$resourceId = (int) $this->stream;
|
||||
self::$guardClonedStream[$resourceId] =
|
||||
isset(self::$guardClonedStream[$resourceId]) ?
|
||||
self::$guardClonedStream[$resourceId] + 1 :
|
||||
0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,8 +94,35 @@ class ZipNewData implements ZipData
|
||||
stream_copy_to_stream($stream, $outStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://php.net/manual/en/language.oop5.cloning.php
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$resourceId = (int) $this->stream;
|
||||
self::$guardClonedStream[$resourceId] =
|
||||
isset(self::$guardClonedStream[$resourceId]) ?
|
||||
self::$guardClonedStream[$resourceId] + 1 :
|
||||
1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The stream will be closed when closing the zip archive.
|
||||
*
|
||||
* The method implements protection against closing the stream of the cloned object.
|
||||
*
|
||||
* @see ZipFile::close()
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$resourceId = (int) $this->stream;
|
||||
|
||||
if (isset(self::$guardClonedStream[$resourceId]) && self::$guardClonedStream[$resourceId] > 0) {
|
||||
self::$guardClonedStream[$resourceId]--;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (\is_resource($this->stream)) {
|
||||
fclose($this->stream);
|
||||
}
|
||||
|
@@ -53,4 +53,20 @@ class ImmutableZipContainer implements \Countable
|
||||
{
|
||||
return \count($this->entries);
|
||||
}
|
||||
|
||||
/**
|
||||
* When an object is cloned, PHP 5 will perform a shallow copy of all of the object's properties.
|
||||
* Any properties that are references to other variables, will remain references.
|
||||
* Once the cloning is complete, if a __clone() method is defined,
|
||||
* then the newly created object's __clone() method will be called, to allow any necessary properties that need to
|
||||
* be changed. NOT CALLABLE DIRECTLY.
|
||||
*
|
||||
* @see https://php.net/manual/en/language.oop5.cloning.php
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
foreach ($this->entries as $key => $value) {
|
||||
$this->entries[$key] = clone $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -12,7 +12,12 @@ use PhpZip\Exception\ZipException;
|
||||
*/
|
||||
class ZipContainer extends ImmutableZipContainer
|
||||
{
|
||||
/** @var ImmutableZipContainer|null */
|
||||
/**
|
||||
* @var ImmutableZipContainer|null The source container contains zip entries from
|
||||
* an open zip archive. The source container makes
|
||||
* it possible to undo changes in the archive.
|
||||
* When cloning, this container is not cloned.
|
||||
*/
|
||||
private $sourceContainer;
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user