duancheng6500 2017-02-16 14:10
浏览 47

ZipArchive在windows / linux中的工作方式不同

I am trying to zip a directory with ziparchive library in php. I am a linux user. Currently my directory structure is /home/shivanshu/workspace/master-data/data/....

Data further contains files and subdirectories and I want to zip the data folder as it is. My code works fine in Linux but when I run it in windows, the zip is created from the root folder i.e c/../../ which is not desired

My code

    public function createBatchZip($source, $destination, $tpodId){
    $count = 0;
    $response = [
            'tpodResponse' => false,
            'message' => ''
    ];
    if (! extension_loaded ( 'zip' ) || ! file_exists ( $source )) {
        $response = [
                'tpodResponse' => false,
                'message' => Messages::SOURCE_FOLDER_ERROR
        ];
        return $response;
    }

    $zip = new \ZipArchive ();
    if (! $zip->open ( $destination, \ZIPARCHIVE::CREATE )) {
        $response = [
                'tpodResponse' => false,
                'message' => Messages::ZIP_CREATED_ERROR
        ];
        return $response;
    }
    $source = str_replace ( '\\', '/', realpath ( $source ) );
    if (is_dir ( $source ) === true) {
        // Will exclude everything under these directories
        $exclude = array('application', 'framework','tests','tools');

        /**
         * @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) {
            if ($iterator->hasChildren() && !in_array($file->getFilename(), $exclude)) {
                return true;
            }
            return $file->isFile();
        };

        $innerIterator = new \RecursiveDirectoryIterator(
                $source,
                \RecursiveDirectoryIterator::SKIP_DOTS
                );
        $iterator = new \RecursiveIteratorIterator(
                new \RecursiveCallbackFilterIterator($innerIterator, $filter)
                );
        //$files = new \RecursiveIteratorIterator ( new \RecursiveDirectoryIterator ( $source ), \RecursiveIteratorIterator::SELF_FIRST );
        foreach ( $iterator as $file ) {
            $file = str_replace ( '\\', '/', $file );


            $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 ) );
    }

    $zipSuccess =  $zip->close ();
    if($zipSuccess){
        $response = [
                'tpodResponse' => true,
                'message' => Messages::ZIP_CREATED_SUCCESSFULLY . $destination
        ];
    }
    else{
        $response = [
                'tpodResponse' => false,
                'message' => Messages::ZIP_CREATED_ERROR
        ];
    }
    return $response;
}

In place of addString method have also tried the below code

    $relativePath = strstr($file,'data');
    $zip->addFile($file,$relativePath);
    --------------------------------------
   $relativePath = strstr($source,'data');
   $zip->addFile($source,$relativePath);

But this still doesn't give the desired structure.

Please help

  • 写回答

0条回答 默认 最新

    报告相同问题?