RecursiveIteratorIterator:包含zip中的目录和php文件 [英] RecursiveIteratorIterator: include directory and php files in zip

查看:200
本文介绍了RecursiveIteratorIterator:包含zip中的目录和php文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ZIPS目录的脚本,但也需要添加* .php文件。

I have a script which ZIPS directories, but need to add *.php files also.

添加类似../index之类的东西会引发错误.php。

Issue having is error is thrown when adding something like ../index.php.

以下脚本产生的错误是:

Error produced by script below is:

Fatal error: Uncaught exception 'UnexpectedValueException' with message 'RecursiveDirectoryIterator::__construct(../index.php): failed to open dir: Not a directory' in /home/mathtest/public_html/trig/admin/save.php:23 Stack trace: #0 /home/mathtest/public_html/trig/admin/save.php(23): RecursiveDirectoryIterator->__construct('../index.php') #1 {main} thrown in /home/mathtest/public_html/trig/admin/save.php on line 23

我的脚本:

<?php

/* CONFIG */

$pathToAssets = array("../images", "../Data", "../css", "../index.php");

$filename = "temp/backup.zip";

/* END CONFIG */


$zip = new ZipArchive();

$zip->open($filename, ZipArchive::CREATE);


//add folder structure

foreach ($pathToAssets as $thePath) {

    // Create recursive directory iterator
    $files = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($thePath), RecursiveIteratorIterator::LEAVES_ONLY
    );


    foreach ($files as $name => $file) {

        if ($file->getFilename() != '.' && $file->getFilename() != '..') {

            // Get real path for current file
            $filePath = $file->getRealPath();

            $temp = explode("/", $name);

            array_shift($temp);

            $newName = implode("/", $temp);

            // Add current file to archive
            $zip->addFile($filePath, $newName);
        }
    }
}

$zip->close();

$yourfile = $filename;

$file_name = basename($yourfile);

header("Content-Type: application/zip");
header("Content-Transfer-Encoding: Binary");
header("Content-Disposition: attachment; filename=$file_name");
header("Content-Length: " . filesize($yourfile));

readfile($yourfile);

unlink('temp/backup.zip');

exit;
?>

我在 http://php.net/manual/en/class.recursiveiteratoriterator.php 以及许多问题,没有运气解决。

I have read about RecursiveIteratorIterator at http://php.net/manual/en/class.recursiveiteratoriterator.php and also many questions here without luck in solving.

仅用../替换../index.php,但包括不想放在拉链中的目录。

Replacing ../index.php with just ../ works, but that includes directories that do not want placed in zip.

任何允许在下载的zip中插入php的输入非常赞赏。

Any input to allow insertion of php in downloaded zip much appreciated.

推荐答案

你可以使用 FilterIterator CallbackFilterIterator 。如果您在多个地方使用相同的过滤器,最好使用 FilterIterator 。为简单起见,我使用 CallbackFilterIterator 并定义使用 preg_match的过滤器功能 决定该文件是否会出现在循环中。

You can use FilterIterator or CallbackFilterIterator. If you use the same filters in multiple places better to use FilterIterator. For the simplicity, I use CallbackFilterIterator and define the filter function that uses preg_match to decide whether the file will be present in the loop.

$path = '../test';

$directories = ['images', 'Data', 'css'];

$filter = function ($current, $key, $iterator) use ($path, $directories) {
    $path = preg_quote($path, '/');
    $directories = implode('|', array_map('preg_quote', $directories));

    if (preg_match('/^' . $path . '\/(' . $directories . ')/', $key)) {
        return true;
    }

    if (preg_match('/^' . $path . '.+\.php$/', $key)) {
        return true;
    }

    return false;
};

$files = new CallbackFilterIterator(
    new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator(
            $path,
            FilesystemIterator::SKIP_DOTS
        ),
        RecursiveIteratorIterator::LEAVES_ONLY
    ),
    $filter
);

foreach ($files as $key => $file) {
    // Do something with files.
    var_dump($key, $file);
}

通知 FilesystemIterator :: SKIP_DOTS 标志。它可以帮助您避免这样的代码:

Take a notice of FilesystemIterator::SKIP_DOTS flag. It helps you to avoid code like this:

if ($file->getFilename() != '.' && $file->getFilename() != '..') {
    // ...
}

另一种方法是使用原始代码仅添加目录,但对于文件使用 ZipArchive :: addPattern 方法:

The other approach will be to use your original code to add directories only, but for files use ZipArchive::addPattern method:

$zip->addPattern('/\.(?:php)$/', $path)

请注意,该模式仅与文件名匹配

这篇关于RecursiveIteratorIterator:包含zip中的目录和php文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆