php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #53809 Phar::mount()'ed Files Don't Show Up In Dir Listings
Submitted: 2011-01-22 04:40 UTC Modified: 2011-01-22 08:52 UTC
Votes:3
Avg. Score:4.0 ± 0.8
Reproduced:0 of 1 (0.0%)
From: panman at traileyes dot com Assigned:
Status: Open Package: PHAR related
PHP Version: 5.3.5 OS: Win 7 32 bit
Private report: No CVE-ID: None
 [2011-01-22 04:40 UTC] panman at traileyes dot com
Description:
------------
When using any sort of directory listings the Phar::mount()'ed files don't show up. Ex: readdir() scandir() SPL::DirectoryIterator() For the test below, the following folder structure should be setup:

make.php = The test script below
list.php = Also in the test script below
page1.html = <p>Page 1</p>
page2.html = <p>Page 2</p>
page3.html = <p>Page 3</p>

Test script:
---------------
<?php
// make.php

try {
    $p = new Phar('test.phar');
    $p->addFile('list.php');
    $p->addFile('page1.html');
    $p->addFile('page3.html');
    $p->setStub('<?php
Phar::interceptFileFuncs();
Phar::webPhar("test.phar", "list.php");
Phar::mount(__DIR__ . "/page2.html", "page2.html");
__HALT_COMPILER();');
    echo 'Done making test.phar';
} catch (Exception $e) {
    echo 'Exception caught: ' . $e->getMessage();
}
?>



<?php 
// list.php

echo "<h3>readdir()</h3>\r\n";
$handle = opendir(Phar::running());
while (false !== ($file = readdir($handle))) {
    if ($file == "." || $file == "..") continue;
    echo "$file<br>\r\n";
}

echo "<h3>scandir()</h3>\r\n";
foreach (scandir(Phar::running()) as $file) {
    if ($file == "." || $file == "..") continue;
    echo "$file<br>\r\n";
}

echo "<h3>SPL::DirectoryIterator()</h3>\r\n";
foreach (new DirectoryIterator(Phar::running()) as $file) {
    if ($file->isDot()) continue;
    echo $file->getFilename() . "<br>\r\n";
}
?>

Expected result:
----------------
Visiting: make.php
Done making test.phar

Visiting: test.phar/list.php

readdir()
=========
list.php
page1.html
page2.html
page3.html

scandir()
=========
list.php
page1.html
page2.html
page3.html

SPL::DirectoryIterator()
========================
list.php
page1.html
page2.html
page3.html

Actual result:
--------------
Visiting: make.php
Done making test.phar

Visiting test.phar/list.php

readdir()
=========
list.php
page1.html
page3.html

scandir()
=========
list.php
page1.html
page3.html

SPL::DirectoryIterator()
========================
list.php
page1.html
page3.html

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-01-22 08:52 UTC] panman at traileyes dot com
I was thinking about this some more and came up with a possible reason why this doesn't work, along with bug 53801. The Phar's manifest is registered when Phar::mapPhar() or Phar::webPhar() is called. Well, since the files that are Phar::mount()'ed come after one of the "loading" methods then those files are not included in the manifest.

I tried to fix this by moving the Phar::mount()'s before the Phar::webPhar() but that didn't work. I'm thinking that's because Phar::mount() won't work until it can look at a loaded manifest.

I also tried calling Phar::mapPhar() after the Phar::mount()'s but that didn't do anything. Not sure if it doesn't re-load the manifest after it's been loaded once...

Anyway, it would be nice if Phar::mount() would register itself with the manifest automatically or have Phar::mapPhar() re-load the manifest, including the Phar::mount()'ed files.
 [2011-01-24 22:31 UTC] panman at traileyes dot com
So it doesn't seem to be manifest related as I took a look at the source code and 
phar_mount_entry does appear to be adding the path to both mounted_dirs hash and 
manifest hash. So it must be that PHP directory iterators are not looking at the 
manifest.?. Is this something that Phar::interceptFileFuncs() could help resolve? 
I'm not fluent in C so I don't know how to properly read all of the source code.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 11:01:29 2024 UTC