|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2020-07-18 16:40 UTC] bugreports2 at gmail dot com
Description: ------------ http://git.php.net/?p=php-src.git;a=commitdiff;h=f3b1f342c887073012f4ca7c1bc1b5259ce4cedc that's cool, but how do you expect switching to the object style when these is no ZipArchive::read(), ZipArchive::entry_name, ZipArchive::entry_filesize(), ZipArchive::entry_read() ZipArchive::extractTo() is *no* replacement when you iterate and decide which files are supposed to be extracted, you need to reqrite the whole code and logic to delete stuff after extract look at mysqli - there is everything and more in the object API and so it *can* be a dropin replacement without changing the whole program logic - and no please don#t be tempted to deprecate tthe old APi there too just because you can PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Oct 24 01:00:02 2025 UTC |
someone my port that code running perfectly for many years to the limited ZipArchive class..... /** * Lokales oder hochgeladenes ZIP-Archiv rekursiv im CMS-Temp-Folder entpacken * Versteckte Dateien und Ordner werden ignoriert * * Wenn keine Dateiendungen uebergeben wurden aktuelle Systemeinstellungen benutzen * Wenn es sich um eine hochgeladene Datei handelt implizit move_uploaded_file() benutzen * * @param mixed $source Pfad zum ZIP-File oder ein $_FILES-Item eines Dateiuploads * @param array $ext Array mit erlaubten Dateiendungen oder Fallback auf CMS-defaults wenn leer * @param bool $normalize_names Dateinamen webkonform normalisieren, Default: Aktiv * * @return array [folder, files, folders] */ public function unpack_zip($source, array $ext=[], bool $normalize_names=TRUE): array { /** Abbrechen wenn kein Server-Support */ if(extension_loaded('zip') === FALSE) { return []; } /** Maximale Skript-Laufzeit erhoehen und bei Verbindungsabbruch weiterlaufen lassen */ ignore_user_abort(TRUE); set_time_limit(0); /** Wenn keine erlaubten Dateiendungen definiert wurden auf CMS-Defaults zurueckfallen */ if(empty($ext)) { global $uploadtypes; $ext = $uploadtypes; } /** Datei-Upload verarbeiten */ if(is_array($source) === TRUE) { /** Check ob es sich um einen Upload handelt */ if(empty($source['error']) && !empty($source['tmp_name']) && !empty($source['name']) && strtolower(substr($source['name'], -4)) === '.zip' && is_uploaded_file($source['tmp_name']) === TRUE) { /** Upload in CMS-Temp-Folder verschieben */ $zip_upload_tmp_name = "{$this->cl_api->CONTENTLOUNGE_BASEDIR}/temp/unpack_zip_" . bin2hex(random_bytes(10)) . '.zip'; if(move_uploaded_file($source['tmp_name'], $zip_upload_tmp_name) === FALSE) { return []; } else { /** Ab jetzt spielen wir der Funktion eine normale Datei als Source-Angabe vor */ chmod($zip_upload_tmp_name, 0660); clearstatcache(TRUE, $zip_upload_tmp_name); $source = $zip_upload_tmp_name; } } } /** ZIP-Archiv oeffnen */ if(!empty($source)) { $zip_handle = zip_open($source); if(is_resource($zip_handle)) { /** Eindeutigen Temp-Folder zum Entpacken */ $zip_tmp_folder = "{$this->cl_api->CONTENTLOUNGE_BASEDIR}/temp/unpack_zip_" . bin2hex(random_bytes(10)); /** Sicherstellen dass der Temp-Pfad nicht mit einem Slash endet */ if(substr($zip_tmp_folder, -1) === '/') { $zip_tmp_folder = substr($zip_tmp_folder, 0, -1); } /** Temp-Dir anlegen */ mkdir($zip_tmp_folder, 0770); /** ZIP-Archiv durchlaufen */ $files_created = FALSE; while(($zip_file_handle = zip_read($zip_handle)) !== FALSE) { /** Nur Dateien mit der gelisteten Erweiterung verarbeiten */ $zip_file_name = utf8_decode(str_replace("\\", '/', zip_entry_name($zip_file_handle))); $zip_file_ext = pathinfo($zip_file_name, PATHINFO_EXTENSION); rh_debug_in_array(strtolower($zip_file_ext), $ext); if(in_array(strtolower($zip_file_ext), $ext, /**strict*/TRUE) === TRUE) { /** Sicherstellen dass wir keine versteckten und MACOSX-Meta Dateien verarbeiten */ if(substr(basename($zip_file_name), 0, 1) !== '.' && strpos($zip_file_name, '/.') === FALSE && strpos($zip_file_name, '/__MACOSX') === FALSE) { /** Absoluten Pfad im Temp-Folder festlegen, einzelne Ordner-Komponenten dabei normalisieren */ $folder_components = explode('/', dirname($zip_file_name)); foreach($folder_components as $folder_key=>$folder_component) { $folder_components[$folder_key] = rh_misc::ConvertMyUploadName($folder_component); } /** Base-Dateinamen behandeln */ switch($normalize_names) { /** Kompletten Dateinamen fuer Web normalisieren */ case TRUE: $zip_file_name = implode('/', $folder_components) . '/' . rh_misc::ConvertMyUploadName(basename($zip_file_name)); $zip_temp_filename = "{$zip_tmp_folder}/{$zip_file_name}"; break; /** Dateiendung in jedem Fall auf Kleinbuchstaben */ case FALSE: $zip_file_name = implode('/', $folder_components) . '/' . basename($zip_file_name); $zip_temp_filename = "{$zip_tmp_folder}/" . str_replace(".{$zip_file_ext}", '.' . strtolower($zip_file_ext), $zip_file_name); break; } /** Sicherstellen dass wir die Subfolder-Struktur beibehalten */ if(is_dir(dirname($zip_temp_filename)) === FALSE) { mkdir(dirname($zip_temp_filename), 0770, TRUE); } /** Temp-File erstellen */ if(zip_entry_filesize($zip_file_handle) > 0) { file_put_contents($zip_temp_filename, zip_entry_read($zip_file_handle, zip_entry_filesize($zip_file_handle))); $files_created = TRUE; } } } } /** ZIP-Archiv wieder schliessen */ zip_close($zip_handle); /** GGf. vorhandene Upload-Datei wieder loeschen */ if(!empty($zip_upload_tmp_name) && file_exists($zip_upload_tmp_name) === TRUE) { unlink($zip_upload_tmp_name); } /** Check ob verwertbare Dateien im Archiv gefunden wurden */ switch($files_created) { /** Keine Dateien entpackt */ case FALSE: (new rh_filesystem)->rmdir($zip_tmp_folder); return []; break; /** Finale Verarbeitung */ case TRUE: /** Check ob erster Ordner alleinestehend UND leer ist und alles darunter eine Ebene nach oben schieben */ $basedir_files = $this->cl_api->folders->readdir($zip_tmp_folder); $basedir_folders = $this->cl_api->folders->readdir_folders($zip_tmp_folder); if(count($basedir_folders) === 1) { $basedir_parent_folder = $basedir_folders[0]; $basedir_folders = $this->cl_api->folders->readdir_folders($basedir_parent_folder); /** Subfolder vorhanden */ if(!empty($basedir_folders)) { foreach($basedir_folders as $basedir_current_folder) { $basedir_current_folder_new = $zip_tmp_folder . str_replace($basedir_parent_folder, '', $basedir_current_folder); rename($basedir_current_folder, $basedir_current_folder_new); } } /** Nur Dateien im Basis-Ordner */ else { $basedir_files = $this->cl_api->folders->readdir($basedir_parent_folder); if(!empty($basedir_files)) { foreach($basedir_files as $basedir_current_file) { $basedir_current_file_new = $zip_tmp_folder . str_replace($basedir_parent_folder, '', $basedir_current_file); rename($basedir_current_file, $basedir_current_file_new); } } } } /** Filesystem-Klasse instanzieren und Liste zurueckgeben, leere Ordner entfernen */ $rh_fs = new rh_filesystem; $file_list = $rh_fs->ListFilesRecursive(/**path*/$zip_tmp_folder, /**details*/TRUE); foreach($file_list['folders'] as $current_folder) { if($rh_fs->is_dir_empty($current_folder) === TRUE) { rmdir($current_folder); } } $file_list = $rh_fs->ListFilesRecursive(/**path*/$zip_tmp_folder, /**details*/TRUE); $file_list['files'] = array_keys($file_list['files']); foreach($file_list['folders'] as $current_folder) { chmod($current_folder, 0770); clearstatcache(TRUE, $current_folder); } foreach($file_list['files'] as $current_file) { chmod($current_file, 0660); clearstatcache(TRUE, $current_file); } natsort($file_list['files']); natsort($file_list['folders']); return ['folder'=>$zip_tmp_folder, 'files'=>$file_list['files'], 'folders'=>$file_list['folders']]; break; } } /** Offenbar kein ZIP-Archiv, abbrechen und ggf. Temp-File loeschen */ else { if(!empty($zip_upload_tmp_name) && file_exists($zip_upload_tmp_name) === TRUE) { unlink($zip_upload_tmp_name); } } } /** Im Zweifel leeren Array zurueckgeben */ return []; }