Making a temporary dir for unpacking a zipfile into

后端 未结 7 624
心在旅途
心在旅途 2020-12-29 23:05

I have a script that checks a zipfile containing a number of matching PDF+textfiles. I want to unpack, or somehow read the textfiles from the zipfile, and just pick out some

7条回答
  •  心在旅途
    2020-12-29 23:20

    I wanted to add a refinement to @Mario Mueller's answer, as his is subject to possible race conditions, however I believe the following should not be:

    function tempdir(int $mode = 0700): string {
        do { $tmp = sys_get_temp_dir() . '/' . mt_rand(); }
        while (!@mkdir($tmp, $mode));
        return $tmp;
    }
    

    This works because mkdir returns false if $tmp already exists, causing the loop to repeat and try another name.

    Note also that I've added handling for $mode, with a default that ensures the directory is accessible to the current user only, as mkdir's default is 0777 otherwise.

    It is strongly advised that you use a shutdown function to ensure the directory is removed when no longer needed, even if your script exits by unexpected means*. To facilitate this, the full function that I use does this automatically unless the $auto_delete argument is set to false.

    // Deletes a non-empty directory
    function destroydir(string $dir): bool { 
        if (!is_dir($dir)) { return false; }
    
        $files = array_diff(scandir($dir), ['.', '..']);
        foreach ($files as $file) {
            if (is_dir("$dir/$file")) { destroydir("$dir/$file"); }
            else { unlink("$dir/$file"); }
        }
        return rmdir($dir); 
    }
    
    function tempdir(int $mode = 0700, bool $auto_delete = true): string {
        do { $tmp = sys_get_temp_dir() . '/' . mt_rand(); }
        while (!@mkdir($tmp, $mode));
    
        if ($auto_delete) {
            register_shutdown_function(function() use ($tmp) { destroydir($tmp); });
        }
        return $tmp;
    }
    

    This means that by default any temporary directory created by tempdir() will have permissions of 0700 and will be automatically deleted (along with its contents) when your script ends.

    NOTE: *This may not be the case if the script is killed, for this you might need to look into registering a signal handler as well.

提交回复
热议问题