Bug #75101 [Com]: `PharData` caches file contents, even through file deletion

From: Date: Fri, 20 Apr 2018 08:56:50 +0000
Subject: Bug #75101 [Com]: `PharData` caches file contents, even through file deletion
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-214813@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=75101&edit=1 ID: 75101 Comment by: inuyasha dot smith at dist dot info Reported by: d28b312d at opayq dot com Summary: PharData caches file contents, even through file deletion Status: Open Type: Bug Package: PHAR related Operating System: Windows 10 + Cygwin PHP Version: Irrelevant Block user comment: N Private report: N New Comment: I can confirm this bug. In my case I'm replacing a tar.gz file I previously opened and reopening it gives me the same output. Quick fix would be to copy the file to a temporary location so it has a different name and doesn't get cached. Previous Comments: ------------------------------------------------------------------------ [2017-11-26 03:39:27] zeitgeist at ukr dot net And in addition to this. I use PharData to decompress downloaded .tar.gz files in infinite loop. <?php while (true) { $storagePrefix = '/home/myusername/storage'; // in my script this is another absolute file path echo "Downloading...\n"; file_put_contents($storagePrefix.'/export_xml.tar.gz', file_get_contents('http://localhost/export/1402/630/export_xml.tar.gz')); // real url goes here... echo "Decompressing...\n"; $p = new \PharData($storagePrefix.'/export_xml.tar.gz'); $p->decompress(); $this->comment('Extracting...'); $p = new \PharData($storagePrefix.'/export_xml.tar'); $p->extractTo($storagePrefix.'/export_xml'); // parsing logic goes here... echo "Cleaning out..."; File::deleteDirectory($storagePrefix.'/export_xml'); File::delete($storagePrefix.'/export_xml.tar.gz'); File::delete($storagePrefix.'/export_xml.tar'); echo "Done.\n"; sleep(3); } /* // lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 16.04.2 LTS Release: 16.04 Codename: xenial PHP 7.1.4-1+deb.sury.org~xenial+1 (cli) (built: Apr 11 2017 22:12:32) ( NTS ) Copyright (c) 1997-2017 The PHP Group Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies with Zend OPcache v7.1.4-1+deb.sury.org~xenial+1, Copyright (c) 1999-2017, by Zend Technologies */ ?> On first loop cycle everything is ok - I get decompressed files in export_xml folder. Then I delete them in the end of first loop cycle. But during the second loop cycle I see the following error: [BadMethodCallException] Unable to add newly converted phar "/home/myusername/storage/export_xml.tar" to the list of phars, a phar with that name already exists This error related to string "$p->decompress();" . Looks like PharData think that export_xml.tar file exists at that moment, but the file does not. I expect that PharData could successfully decompress newly downloded .tar.gz file, but it doesn't happen... ------------------------------------------------------------------------ [2017-08-21 09:29:06] d28b312d at opayq dot com Description: ------------ - PHP shipped with Cygwin (7.0.19), can't find anything in the patch notes to suggest this is fixed in newer versions. PharData seems to cache file contents even when the file is no longer on the disk. Constructing a new PharData with the same filename will produce the same object as before. I understand there is an alias parameter, but this seems like totally unexpected behaviour especially as these functions seem to be the go-to functions for extracting tar archives these days. Looking in the source code I see that this seems to be partially deliberate behaviour as phar_open_parsed_phar tries to open an already existing phar file, however, if the file has been deleted off disk and a new PharData object is created then surely new data should be loaded? Also does this mean that once a PharData object is created and a tar file opened that the entire contents of the tar is held in memory for the duration of the PHP script? There seems to be no way to remove this caching, as shown in the test script the tgz file is removed and then opened again with a new file (with different contents), and yet the same file is opened somehow. I've tried calling unset() on the PharData object before creating a new one or calling clearstatcache(), but to no avail. Interestingly and of note, even though the default format is Phar::TAR, it seems that it auto-detects TGZ files and decompresses them fine. Test script: --------------- <?php $url = 'http://thrysoee.dk/editline/libedit-%s-3.1.tar.gz'; $downloadFile = '/tmp/foo.tgz'; file_put_contents($downloadFile, fopen(sprintf($url, '20170329'), 'r')); var_dump(new PharData($downloadFile)); unlink($downloadFile); file_put_contents($downloadFile, fopen(sprintf($url, '20160903'), 'r')); var_dump(new PharData($downloadFile)); Expected result: ---------------- I expect the second object to be the new file, as shown in the edited output below: /tmp $ php /tmp/phpbugtest.php object(PharData)#1 (4) { ["pathName":"SplFileInfo":private]=> string(40) "phar:///tmp/foo.tgz/libedit-20170329-3.1" ["fileName":"SplFileInfo":private]=> string(20) "libedit-20170329-3.1" ["glob":"DirectoryIterator":private]=> bool(false) ["subPathName":"RecursiveDirectoryIterator":private]=> string(0) "" } object(PharData)#2 (4) { ["pathName":"SplFileInfo":private]=> string(40) "phar:///tmp/foo.tgz/libedit-20160603-3.1" ["fileName":"SplFileInfo":private]=> string(20) "libedit-20160603-3.1" ["glob":"DirectoryIterator":private]=> bool(false) ["subPathName":"RecursiveDirectoryIterator":private]=> string(0) "" } Actual result: -------------- /tmp $ php /tmp/phpbugtest.php object(PharData)#1 (4) { ["pathName":"SplFileInfo":private]=> string(40) "phar:///tmp/foo.tgz/libedit-20170329-3.1" ["fileName":"SplFileInfo":private]=> string(20) "libedit-20170329-3.1" ["glob":"DirectoryIterator":private]=> bool(false) ["subPathName":"RecursiveDirectoryIterator":private]=> string(0) "" } object(PharData)#1 (4) { ["pathName":"SplFileInfo":private]=> string(40) "phar:///tmp/foo.tgz/libedit-20170329-3.1" ["fileName":"SplFileInfo":private]=> string(20) "libedit-20170329-3.1" ["glob":"DirectoryIterator":private]=> bool(false) ["subPathName":"RecursiveDirectoryIterator":private]=> string(0) "" } ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=75101&edit=1

« previous php.bugs (#214813) next »