2016-12-12 9 views
2

で解凍フォルダには、私はこのような構造とWindowsで「.zipファイル」を作成しました:PHPでシェル - アクセント

myfile.zip 
    - trénsfèst 
     - file1.png 
     - file2.png 
     - file3.png 

が、私は自分のサーバー上でmyfile.zipを置くためにshell_execを送ります。そして私のシェルファイルでは、このファイルを解凍して特定のフォルダ内の構造体を取得する必要があります。私はunzip myfile.zipを実行すると、すべてのアクセントは解釈されませんています

Archive: myfile.zip 
creating: tr?n'sf?rt/ 
inflating: tr?n'sf?rt/file1.png 
inflating: tr?n'sf?rt/file2.png 
inflating: tr?n'sf?rt/file3.png 

私は、フォルダを削除しようとするいくつかの正方形はアクセントの交換であります。

+0

あなたは何とかファイルを共有することはできますか?私はそれを修正する方法を知っていると思いますが、答えを投稿する前に解決策をチェックしたいと思います。 –

+0

アクセント付きのフォルダをWindows上に作成して(ファイルの有無を問わず)、winrarまたは7zipで圧縮します。ファイルは特定ではありません。 – Remi

+0

問題は、Zip内のファイル名のエンコーディングがシステムロケールによって異なることです。 Windowsの設定によって結果が異なる場合があります。問題をすぐに解決したい場合は、ファイルを共有してください。 –

答えて

0

おかげルスランOsmanovが、私は解決策を見つけました。 私のzipファイルを解凍した後、私はここにconvmvを使用するが、私のプロセスです:この投稿へ

unzip myfile.zip 
convmv --notest -r -f WINDOWS-1252 -t utf8 

感謝:Windows-1252 to UTF-8 encoding

+0

私の答えはconvmv btwを含んでいます。また、ソースロケールに依存するため、常にWindows-1252であると主張することはできません。最後に、あなたの質問はPHPのタグであるので、ziparchiveとiconvを使った私のソリューションがより適切です。 –

1

Windowsは通常、ファイル名はロケールに応じて符号化する全てのアクセント

おかげで私のフォルダを解凍するための解決策はあります。たとえば、ロシアの設定では、通常、CP866のファイル名をエンコードします。ファイル名は、同じロケール、つまりアーカイブが作成されたシステムに応じてロケールでZipに入れられます。

私は何年か前tried to solve this problemエンコーディング

の検出、およびIは、一般的にエンコーディング確実を検出する方法がないという結論に達しました。 PHPでは、あなたはZipArchivemb_detect_encodingで試すことができます。

$zip = new ZipArchive; 
$filename = $argv[1]; 

if (! $zip->open($filename)) 
    die("failed to open $filename\n"); 

for ($i = 0; $i < $zip->numFiles; ++$i) { 
    $encoding = mb_detect_encoding($zip->getNameIndex($i), 'auto'); 
    if (! $encoding) { 
    trigger_error("Failed to detect encoding for " . $zip->getNameIndex($i), E_USER_ERROR); 
    exit(1); 
    } 
    $zip->renameIndex($i, iconv($encoding, 'UTF-8', $zip->getNameIndex($i))); 
} 
$zip->extractTo('/home/ruslan/tmp/unzippped/'); 
$zip->close(); 

しかし、私の経験から、mb_detect_encodingは非常に正確ではありません。

あなたは次のようにencaツールでエンコーディングを検出しようとすることができます:

ruは言語コードです
ls -1 folder | enca -L ru 

(すべての言語コードがenca --list languagesから入手できます)を。しかし、それはあなたが言語を推測する必要があります。実際にはUTF-8に1つのエンコーディングからファイル名を変換するには、あなたがもう一度、enconv、例えば:

ls -1 folder | enconv -L russian -x UTF-8 

を使用することができますが、あなたは言語を推測する必要があります。

上記のいずれかの方法でエンコーディングを検出し、使用可能なすべてのエンコーディングのリストからエンコーディングを選択するようにお勧めします。デフォルトでは、自動検出されたエンコーディングがリストで選択されている可能性があります。個人的には、スマートな自動検出機能を使用せずにエンコーディングを選択できるようにしました。

あなたがソースのエンコーディングを知っているとき

解凍が-pオプションでパイプストリーミングをサポートしています。しかし、それはバルクデータのためだけに機能します。つまり、圧縮されていないすべてのコンテンツをプログラムに渡すファイルにストリームを分割しません。

unzip -p foo | more => foo.zipの内容をパイプ経由でプログラムに送信more

生ストリームを解析することは明らかに難しい作業です。

$path = $argv[1]; 
$from_encoding = isset($argv[2]) ? $argv[2] : 'CP866'; 

if ($handle = opendir($path)) { 
    while ($file = readdir($handle)) { 
    rename($file, iconv($from_encoding, 'UTF-8', $file)); 
    } 
    closedir($handle); 
} 

使用例:

を別の方法として、次のようにZipArchiveを使用する一つの方法は、ディレクトリにファイルを抽出し、このようなスクリプトを含むファイル名を変換することです。

$zip = new ZipArchive; 

$filename = $argv[1]; 
$from_encoding = isset($argv[2]) ? $argv[2] : 'CP866'; 

$zip->open($filename) or die "failed to open $filename\n"; 

for ($i = 0; $i < $zip->numFiles; ++$i) { 
    $zip->renameIndex($i, iconv($from_encoding,'UTF-8', $zip->getNameIndex($i))); 
} 
$zip->extractTo('/target/directory/'); 

$zip->close(); 

使用例:

php script.php file.zip Windows-1252