Skip to content

Instantly share code, notes, and snippets.

@takuya
Last active April 30, 2016 11:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save takuya/cb9859338f0c3cea38d2bfb5fe9e08e5 to your computer and use it in GitHub Desktop.
Save takuya/cb9859338f0c3cea38d2bfb5fe9e08e5 to your computer and use it in GitHub Desktop.
<?php
class ZipByEntryName extends ZipArchive{
// エントリ名でZipを管理する拡張
// return sorted entry names
public $encoding = "utf-8";
protected $default_internal_encoding;
public function __construct(){
$this->default_internal_encoding = mb_internal_encoding();
}
public function open($f_name, $flags=null){
if( preg_match("/^https?:/", $f_name) ){
// $tmp = "/tmp/php-zip-archive-" + md5($f_name);
$tmp = tempnam('/tmp', "php-zip-archive");
file_put_contents($tmp, file_get_contents($f_name));
$f_name = $tmp;
}
parent::open($f_name, $flags);
$encodings = [];
for ($i=0; $i<$this->numFiles;$i++) {
$encodings[] = mb_detect_encoding($this->statIndex($i)["name"], "utf-8,eucjp-win,cp932");
}
$encodings = array_count_values($encodings);
asort($encodings);
$encodings = array_flip($encodings);
$enc_name = end($encodings);
$this->encoding = $enc_name;
}
public function entry_names(){
$names = [];
mb_internal_encoding("utf8");
for ($i=0; $i<$this->numFiles;$i++) {
$e = $this->statIndex($i)["name"];
$e = mb_convert_encoding($e, "UTF-8", $this->encoding);
$names[] = $e;
}
sort($names);
mb_internal_encoding($this->default_internal_encoding);
return $names;
}
public function first_entry(){
mb_internal_encoding("utf8");
$name = $this->entry_names[0];
$name = mb_convert_encoding($name, $this->encoding, "utf-8");
mb_internal_encoding($this->default_internal_encoding);
return $this->getFromName($name);
}
public function files(){
//ディレクトリを無視してファイルを取り出してしまう
$files = [];
mb_internal_encoding("utf8");
$name = null;
foreach( $this->entry_names as $name ){
if ( preg_match( "/\/$/" , $name ) ) {
continue;
}else {
$orig_name = mb_convert_encoding($name, $this->encoding, "utf-8");
$files[$name] = $this->getFromName($orig_name);
}
}
mb_internal_encoding($this->default_internal_encoding);
return $files;
}
public function first_file(){
mb_internal_encoding("utf8");
$name = null;
foreach( $this->entry_names as $entry ){
if ( preg_match( "/\/$/" , $entry ) ) {
continue;
}else {
$name = $entry;
break;
}
}
$name = mb_convert_encoding($name, $this->encoding, "utf-8");
mb_internal_encoding($this->default_internal_encoding);
return $this->getFromName($name);
}
public function entries(){
$names = $this->entry_names;
$entries = array_map( function($e) { return $this->getFromName($e); } , $names );
return $entries;
}
public function entries_with_names(){
$names = $this->entry_names;
$entries = $this->entries;
return array_combine( $names, $entries ) ;
}
public function __get($name){
switch($name){
case "entries":
case "entry_names":
case "first_entry":
case "first_file":
case "files":
case "entries_with_names":
return $this->$name();
}
throw new Exception("Undefined property");
}
}
@takuya
Copy link
Author

takuya commented Apr 30, 2016

日本語対応した。 internal_encoding でおかしくなるっぽい

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment