Viewed   67 times

Directory is something like:

home/
    file1.html
    file2.html
Another_Dir/
    file8.html
    Sub_Dir/
        file19.html

I am using the same PHP Zip class used in PHPMyAdmin http://trac.seagullproject.org/browser/branches/0.6-bugfix/lib/other/Zip.php . I'm not sure how to zip a directory rather than just a file. Here's what I have so far:

$aFiles = $this->da->getDirTree($target);
/* $aFiles is something like, path => filetime
Array
(
    [home] => 
    [home/file1.html] => 1251280379
    [home/file2.html] => 1251280377
    etc...
)

*/
$zip = & new Zip();
foreach( $aFiles as $fileLocation => $time ){
    $file = $target . "/" . $fileLocation;
    if ( is_file($file) ){
        $buffer = file_get_contents($file);
        $zip->addFile($buffer, $fileLocation);
    }
}
THEN_SOME_PHP_CLASS::toDownloadData($zip); // this bit works ok

but when I try to unzip the corresponding downloaded zip file I get "operation not permitted"

This error only happens when I try to unzip on my mac, when I unzip through the command line the file unzips ok. Do I need to send a specific content type on download, currently 'application/zip'

 Answers

3

Here is a simple function that can compress any file or directory recursively, only needs the zip extension to be loaded.

function Zip($source, $destination)
{
    if (!extension_loaded('zip') || !file_exists($source)) {
        return false;
    }

    $zip = new ZipArchive();
    if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
        return false;
    }

    $source = str_replace('\', '/', realpath($source));

    if (is_dir($source) === true)
    {
        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

        foreach ($files as $file)
        {
            $file = str_replace('\', '/', $file);

            // Ignore "." and ".." folders
            if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) )
                continue;

            $file = realpath($file);

            if (is_dir($file) === true)
            {
                $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
            }
            else if (is_file($file) === true)
            {
                $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
            }
        }
    }
    else if (is_file($source) === true)
    {
        $zip->addFromString(basename($source), file_get_contents($source));
    }

    return $zip->close();
}

Call it like this:

Zip('/folder/to/compress/', './compressed.zip');
Saturday, December 24, 2022
5

PHP has the perfect solution for you built in.

Example

// Construct the iterator
$it = new RecursiveDirectoryIterator("/components");

// Loop through files
foreach(new RecursiveIteratorIterator($it) as $file) {
    if ($file->getExtension() == 'html') {
        echo $file;
    }
}

Resources

  • DirectoryIterator - Manual
Saturday, September 3, 2022
 
2

What I've done in the past is to use a setup like this:

define('DIR_BASE',     dirname( __FILE__ ).'/'); 
define('DIR_SYSTEM',   DIR_BASE.'app/');
etc.

This would be placed in a file root of your project, which will give you access to other areas of your file structure relative to the root.

For your case, it would look like this:

define('DIR_BASE',     dirname( __FILE__ ).'/');
define('DIR_CSS',      DIR_BASE.'css/');
define('DIR_PHP',      DIR_BASE.'php/');
define('DIR_CONTENT'   DIR_BASE.'content/');

This would go in getpath.php in your root, and would give you the ability to reference any file or directory regardless of where it is placed in the directory structure (be sure to include it wherever you'll be using them). You wouldn't need to change your directory structure or anything like that, and you don't have to worry about any vulnerabilities with something like this, since it's internal.

Edit I keep coming back to the structure of the system. Is this a multi-site system that uses the same CSS through out? If not, then what is the justification for having the directory structure laid out like this? Can you give just a little more detail please?

Tuesday, October 4, 2022
 
5

By default, zip will store the full path relative to the current directory. So you have to cd into public_html before running zip:

$output = 'cd /home/user/public_html; zip -rq my-zip.zip folder-one -x missthis/*';
shell_exec($output);
Wednesday, November 2, 2022
 
5

GitHub provides RSS feeds for both directories and files that can do this. See Setting up an Github Commit RSS feed

Using that you can set up an email alert using a service like https://blogtrottr.com/ to send you an email whenever the feed is updated.

Example: To watch this directory: https://github.com/torvalds/linux/tree/master/Documentation use this atom feed https://github.com/torvalds/linux/commits/master/Documentation.atom

Example: To watch a file: https://github.com/torvalds/linux/commits/master/Documentation/Makefile https://github.com/torvalds/linux/commits/master/Documentation/Makefile.atom

Friday, November 18, 2022
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :