Pergunta

I have a zip file into a directory like this:

drwxr-xr-x 2 salome  salome  4096 Dec 16 17:41 staff.zip

When I unzip the file with ZipArchive class, all the upzipped files are owner by nobody user. Is there a way to avoid this owner change?

  1. I am able to use ftp if it is required (only as salome user).
  2. This script eventually will be shared at multiple hosts, so the idea is keep it as generic as possible.
Foi útil?

Solução

You might consider extending the zipArchive class and override the extractTo method to also perform a chown() on the files in the directory.

Based on the use case you discussed in the comments, you also might want to consider the use of the Phar archive format. php.net/manual/en/intro.phar.php

Phar's would allow your module submitters to submit a file file of executable PHP code that you would not need to extract at all.

Outras dicas

Ok, I have resolved the problem of nobody user. I will try to explain all my workaround.

@Mike Brant's answer

Mike suggest to me make use of chown() function overriding extractTo() method. Well, before to willing with it, I tested the chown() function standalone constantly it printed the error:

failed to create stream: Permission denied in ...

Looks like chown will not work for the major shared hostings

FTP functions

So, keeping going I though that FTP functions I made a script that works fine, at least for now xD. This is a resume what the script does for one zipped file:

  1. Create a temp file using tmpfile().
  2. Using ftp_fput() to put the temp file in the current directory with the zipped file.
  3. Give write permissions using ftp_site and CHMOD 0777.
  4. Read the zipped file content with $content = $zip->getFromName('zipped-file.txt');.
  5. Put the content to the new file using fputs($fp, $content);.
  6. Close connections

The code below illustrates the complete process

$zip = new ZipArchive;
$ftp_path_to_unzip = '/public_html/ejemplos/php/ftp/upload/';
$local_path_to_unzip = '/home/user/public_html/ejemplos/php/ftp/upload/';

if ($zip->open('test.zip') == TRUE) {
    
    //connect to the ftp server
    $conn_id = ftp_connect('ftp.example.com');
    $login_result = ftp_login($conn_id, 'user', 'password');    
    
    //if the connection is ok, then...
    if ($login_result) {
        
        //iterate each zipped file
        for ($i = 0; $i < $zip->numFiles; $i++) {
            $filename = $zip->getNameIndex($i);
            
            //create a "local" temp file in order to put it "remotely" in the same machine
            $temp = tmpfile();
            
            //create the new file with the same name from the extracted file in question
            ftp_fput($conn_id, $ftp_path_to_unzip . $filename, $temp, FTP_ASCII);
            
            //set write permissions, eventually we will put its content
            ftp_site($conn_id, "CHMOD 0777 " . $ftp_path_to_unzip . $filename);
            
            //open the new file that we have created
            $fp = fopen($local_path_to_unzip . $filename, 'w');
            
            //put the content from zipped file
            $content = $zip->getFromName($filename);
            fputs($fp, $content);
            
            //close the file
            fclose($fp);
            
            //now only the owner can write the file
            ftp_site($conn_id, "CHMOD 0644 " . $ftp_path_to_unzip . $filename);
            
        }
    }
    
    // close the connection and the file handler
    ftp_close($conn_id);
    
    //close the zip file
    $zip->close();
}

This is the firt step to start a more complex customization, because the code above is not able to know if the zipped file is a "directory" or "file".

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top