微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将所有嵌套的 tar.gz 和 zip 解压缩到 PHP 中的目录?

如何解决如何将所有嵌套的 tar.gz 和 zip 解压缩到 PHP 中的目录?

我需要在 PHP提取一个 tar.gz 文件。该文件包含许多 JSON 文件tar.gzzip 文件和子目录。我只需要将 JSON 文件移动到目录 ./Dataset/processing 并继续提取嵌套的 tar.gz 和 zip 以从那里获取所有 JSON 文件。这些文件也可能有嵌套的文件夹/目录。

结构如下:

origin.tar.gz
 ├───sub1.tar.gz
 │   ├───sub2.tar.gz
 │   ├───├───a.json
 │   ├───├───├───├───├───├───...(unkNown depth)
 │   ├───b.json
 │   ├───c.json
 ├───sub3.zip
 │   ├───sub4.tar.gz
 │   ├───├───d.json
 │   ├───├───├───├───├───├───...(unkNown depth)
 │   ├───e.json
 │   ├───f.json
 ├───subdirectory
 │   ├───g.json
 ├───h.json
 ├───i.json
 |   ..........
 |   ..........
 |   ..........
 |   many of them

一旦它被提取出来./Dataset 看起来像这样

Dataset/processing
 ├───a.json
 ├───b.json
 ├───c.json
 ├───d.json
 ├───e.json
 ├───f.json
 ├───g.json
 ├───h.json
 ├───i.json
 |   ..........
 |   ..........
 |   ..........
 |   many of them

我知道如何在 PHP 中使用 PharData 提取 tar.gz,但它只能在单层深度下工作。我在想是否某种递归可以使这项工作适用于多级深度。

$phar = new PharData('origin.tar.gz');
$phar->extractTo('/full/path'); // extract all files in the tar.gz

我稍微改进了我的代码并尝试了这个,它适用于多深度,但当有一个也包含 JSON 的目录(文件夹或嵌套文件夹)时失败。有人可以帮我提取它们吗。

<?PHP

$path = './';

// Extraction of compressed file
function fun($path) {    
    $array = scandir($path); 
    for ($i = 0; $i < count($array); $i++) {
        if($i == 0 OR $i == 1){continue;}
        else {
            $item = $array[$i];
            $fileExt = explode('.',$item);

            // Getting the extension of the file
            $fileActualExt = strtolower(end($fileExt));
            if(($fileActualExt == 'gz') or ($fileActualExt == 'zip')){
                $pathnew = $path.$item; // Dataset ./data1.tar.gz
                $phar = new PharData($pathnew);
                // Moving the files
                $phar->extractTo($path);
                // Del the files
                unlink($pathnew);
                $i=0;
            }
        }
        $array = scandir($path);


    }
}
fun($path);

// Move only the json to ./dataset(I will add it later)
?>

提前致谢。

解决方法

在第一步,像你提到的那样提取你的 tar.gz 文件:

$phar = new PharData('origin.tar.gz');
$phar->extractTo('/full/path'); // extract all files in the tar.gz

然后递归读取目录,将所有json类型的文件移动到你的目标目录中,这里是我带注释的代码:

$dirPath='./';       // the root path of your very first extraction of your tar.gz

recursion_readdir($dirPath,1);


function recursion_readdir($dirPath,$Deep=0){
    $resDir=opendir($dirPath);
    while($basename=readdir($resDir)){
        //current file path
        $path=$dirPath.'/'.$basename;
        if(is_dir($path) AND $basename!='.' AND $basename!='..'){
            //it is directory,then go deeper
            $Deep++;//depth+1
            recursion_readdir($path,$Deep);
        }else if(basename($path)!='.' AND basename($path)!='..'){
            //it is not directory,//when the file is json file
                if(strstr($basename,'json')) {
                        //copy the file to your destination path
                    copy($path,'./dest/' . $basename);

            } else if(strstr($basename,'tar')){
                //when the file is tar.gz file,extract this tar.gz file
                $phar = new PharData($basename);
                $phar->extractTo($dirPath,null,true);
            }
        }

    }
    closedir($resDir);
}
function forChar($char='-',$times=0){
  $result='';
  for($i=0;$i<$times;$i++){
     $result.=$char;
  }
  return $result;
}
,

我做了一些研究后解决了它。这解决了问题。

有3个功能:

  • recursiveScanProtected():它提取所有压缩文件
  • scanJSON():它将扫描 JSON 文件并将它们移动到处理文件夹。
  • delete_files():此函数删除除处理文件夹(其中包含 JSON 文件)和根目录中的 index.php 之外的所有内容。
<?php

// Root directory
$path = './';

// Directory where I want to extract the JSON files
$path_json = $path.'processing/';


// Function to extract all the compressed files
function recursiveScanProtected($dir,$conn) {
    if($dir != '') {
        $tree = glob(rtrim($dir,'/') . '/*');
        if (is_array($tree)) {
            for ($i = 0; $i < count($tree); $i++) {
                $file = $tree[$i];
                if (is_dir($file)) {
                    recursiveScanProtected($file,$conn); // Recursive call if directory
                } elseif (is_file($file)) {

                    $item = $file;
                    $fileExt = explode('.',$item); 
                    // Getting the extension of the file
                    $fileActualExt = strtolower(end($fileExt));
                    // Check if the file is a zip or a tar.gz
                    if(($fileActualExt == 'gz') or ($fileActualExt == 'zip')){

                        // Moving the file - Overwriting true
                        $phar->extractTo($dir.$i."/",true);

                        // Del the compressed file
                        unlink($item);

                        recursiveScanProtected($dir.$i,$conn); // Recursive call
                    }

                }
            }
        }
    }
}
recursiveScanProtected($path,$conn);


// Move the JSON files to processing
function scanJSON($dir,$path_json) {
    if($dir != '') {
        $tree = glob(rtrim($dir,'/') . '/*');
        if (is_array($tree)) {
            foreach($tree as $file) {
                if (is_dir($file)) {
                    // Do not scan processing recursively,but all other directories should be scanned
                    if($file != './processing'){
                        scanJSON($file,$path_json);
                    }
                } elseif (is_file($file)) {

                    $ext = pathinfo($file);

                    if(strtolower($ext['extension']) == 'json'){
                        // Move the JSON files to processing
                        rename($file,$path_json.$ext['basename']);
                    }
                }
            }
        }
    }
}

scanJSON($path,$path_json);

/* 
 * php delete function that deals with directories recursively
 * It deletes everything except ./dataset/processing and index.php
 */
function delete_files($target) {

    if(is_dir($target)){
        $files = glob( $target . '*',GLOB_MARK ); //GLOB_MARK adds a slash to directories returned
        foreach( $files as $file ){
            if($file == './processing/' || $file == './index.php'){
                continue;
            } else{
                delete_files( $file );
            }
        }
        if($target != './'){
            rmdir( $target );
        }
    } elseif(is_file($target)) {
        unlink( $target );  
    }
}

delete_files($path);
?>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。