phpphar

PHP PharData: build .tar archive from directory, with exclusions


TLDR version:

how to utilize PharData::buildFromIterator in order to build .tar archive from /path/to/project/, but excluding a list of files, like /path/to/project/file0.txt, /path/to/project/file1.txt, /path/to/project/file2.txt?


Longer version, what-have-I-tried included:

In order to build .tar archive from dir path, I tried with the simple PharData::buildFromDirectory method which has a second, optional argument which... kind of... does exact opposite of what I need

"pcre regular expression [...] Only file paths matching the regular expression will be included in the archive"

. So I guess, the only option left is to utilize PharData::buildFromIterator which has a simple usage example:

$phar->buildFromIterator(
    new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator('/path/to/project', FilesystemIterator::SKIP_DOTS)
    ),
    '/path/to/project'
);

This example may be a starting point but from here I do not know how to exclude a list of files from iterator?


Solution

  • In case someone finds this question useful, I shall post an answer since I have figured it out how to do it, with solutions to similar problem found here, thanks to user Levi Morrison.

    (tested OK on Windows filesystem, assumes __DIR__ is the directory where it runs)

    $exclude = ['file0.txt', 'file1.txt', 'file2.txt'];
    
    /**
     * @param SplFileInfo $file
     * @param mixed $key
     * @param RecursiveCallbackFilterIterator $iterator
     * @return bool True if you need to recurse or if the item is acceptable
     */
    $filter = function ($file, $key, $iterator) use ($exclude) {
        foreach($exclude as $excludefilename){
            if(
                strcmp(__DIR__ . DIRECTORY_SEPARATOR . $excludefilename, $file) === 0
            ) return false;
        }
        return true;
    };
    
    $innerIterator = new RecursiveDirectoryIterator(
        __DIR__,
        RecursiveDirectoryIterator::SKIP_DOTS
    );
    $iterator = new RecursiveIteratorIterator(
        new RecursiveCallbackFilterIterator($innerIterator, $filter)
    );
    
    $phar = new PharData('project.tar');
    $phar->buildFromIterator($iterator, __DIR__);