12039


Mac OSX上でPHP 5.6.2を使っています。

以下のように`zip`で圧縮ファイルを作成しました。  
そのファイルを`unzip`で解凍すると、パーミッションを正しく再現できるのですが、PHPのZipArchiveクラスを使って解凍すると、実行権限がなくなってしまいます。

PHPを使って、実行権限をを正しく解凍するよい方法はないでしょうか？  
なお、圧縮ファイルの種類や、PHPのライブラリの種類は問いませんが、先日質問をさせていただいた、シンボリックリンクを含む圧縮ファイルが正しく解凍できる方法であることが前提になります。

先日の質問  
[PHPでシンボリックリンクを含む圧縮ファイルを解凍したい](https://ja.stackoverflow.com/questions/11999)

### 圧縮ファイルの作成

command.shには実行権限が付いています。

[code]

    $ ls -l
    total 8
    -rwxr-xr-x  1 foo  bar  22  7  5 10:20 command.sh
    
    $ zip ../command.zip *
      adding: command.sh (stored 0%)
    
[/code]

### unzipで解凍

command.shの実行権限は付いたまま正しく解凍されます。

[code]

    $ unzip command.zip -d tmp
    Archive:  command.zip
     extracting: tmp/command.sh
    
    $ ls -l tmp
    total 8
    -rwxr-xr-x  1 foo  bar  22  7  5 10:20 command.sh
    
[/code]

### PHPのZipArchiveで解凍

command.shの実行権限が無くなってしまいます。

[code]

    $ php unzip.php 
    
    $ ls -l tmp
    total 8
    -rw-r--r--  1 foo  bar  22  7  5 10:42 command.sh
    
[/code]

PHPの解凍用プログラム

[code]

    <?php
    
    $zip = new ZipArchive;
    $zip->open("command.zip");
    $zip->extractTo("tmp");
    $zip->close();
    
[/code]


CC BY-SA 3.0
2015-07-05T01:53:58.183
12037
2015-07-05T06:47:52.120
2017-04-13T12:52:38.920
-1
9529
question
php
PHPのZipArchiveで圧縮ファイルを解凍するとパーミッションが変わってしまう


シンボリックリンクと同じく`getExternalAttributesIndex`を使ってパーミッションを復元します。

[code]

    <?php
    
    function extractToSym($zip, $dir)
    {
      for ($idx=0 ; $s = $zip->statIndex($idx) ; $idx++) {
        if ($zip->getExternalAttributesIndex($idx, $opsys, $attr) && $opsys==ZipArchive::OPSYS_UNIX) {
          $st_mode = $attr >> 16;
          if (($st_mode & 0120000) === 0120000) {
            symlink($zip->getFromIndex($idx), $dir . '/' . $s['name']);
          } else {
            $zip->extractTo($dir, $s['name']);
            chmod($dir . '/' . $s['name'], $st_mode & 07777);
          }
        }
      }
    }
    
    $zip = new ZipArchive();
    if ($zip->open('samples.zip') === TRUE) {
      extractToSym($zip, '.');
      $zip->close();
    }
    
[/code]


CC BY-SA 3.0
2015-07-05T03:45:22.987
12039
2015-07-05T06:47:52.120
2015-07-05T06:47:52.120
3639
3639
12037
answer