draker 0 Zgłoś post Napisano Lipiec 19, 2012 (edytowany) Witam Posiadam skrypt PHP do zarządzania plikami. Konkretnie jest to już rozbudowana strona, gdzie użytkownicy mogą pobierać różne publikacje. W skrypcie istnieje funkcja masowego pobierania - użytkownicy zaznaczają pliki do wyboru, a skrypt je kompresuje i podaje do pobrania gotowe archiwum .zip. Wszystko byłoby OK, gdyby nie jeden szczegół - skrypt kompresji oparty jest o zewnętrzną "bibliotekę" ss_zip, o które nawet Google niewiele wie, a została napisana wiele lat temu. Próbuję to zmienić, gdyż podczas kompresji skrypt potrafi zużyć 2-3GB RAMu, co jest całkowicie nieakceptowalne, bo po chwili zajmuje mi całą pamięć. Moje pytanie brzmi: co najlepiej wykorzystać do takiej kompresji? Zależy mi na tym, by zużywało jak najmniej pamięci RAM, a najlepiej korzystało z dysku twardego. Zastanawiałem się nad użyciem exec (zip); - czy jest to dobry pomysł? W PHP dopiero raczkuję, więc proszę o sprostowanie - poniżej to, jak próbuję zaimplementować te exec(zip), a jeszcze bardziej poniżej obecny kod odpowiadający za kompresje. zamieniam $zip->add_file($zip_verz.$cat_dir.$filename, $filename); na: exec ('zip'.$user_random_id.' '.$filename.' '.$filename); potem copy ($user_random_id.'.zip'. $zip_verz.$cat_dir."tempzipfiles/".$jlistConfig['zipfile.prefix'].$user_random_id.".zip"); Poniżej wklejam kod mojego skryptu odpowiedzialny za pakowanie. // when mass download with checkboxes if (!$direktlink){ // more as one file is selected - zip it in a temp file $download_verz = JURI::base().$jlistConfig['files.uploaddir'].'/'; $zip_verz = JPATH_SITE.'/'.$jlistConfig['files.uploaddir'].'/'; if (count($marked_files_id) > 1) { // build random value for zip filename if (empty($user_random_id)){ $user_random_id = buildRandomID(); } $zip=new ss_zip(); for ($i=0; $i<count($marked_files_id); $i++) { // get file url $database->setQuery("SELECT url_download, cat_id, file_title FROM #__jdownloads_files WHERE file_id = '".(int)$marked_files_id[$i]."'"); $file_data = $database->loadObject(); $filename = $file_data->url_download; $file_title = $file_title.' - '.$file_data->file_title; $cat_id = $file_data->cat_id; $database->setQuery("SELECT cat_dir FROM #__jdownloads_cats WHERE cat_id = '$cat_id'"); $cat_dir = $database->loadResult(); $cat_dir = $cat_dir.'/'; $zip->add_file($zip_verz.$cat_dir.$filename, $filename); } $zip->archive(); // return the ZIP $zip->save($zip_verz."tempzipfiles/".$jlistConfig['zipfile.prefix'].$user_random_id.".zip"); $zip_size = fsize($zip_verz."tempzipfiles/".$jlistConfig['zipfile.prefix'].$user_random_id.".zip"); $zip_file_info = JText::_('JLIST_FRONTEND_SUMMARY_ZIP_FILESIZE').': <b>'.$zip_size.'</b>'; // delete older zip files $del_ok = deleteOldFile($zip_verz."tempzipfiles/"); $filename = $download_verz."tempzipfiles/".$jlistConfig['zipfile.prefix'].$user_random_id.".zip"; $download_link = JRoute::_('index.php?option='.$option.'&Itemid='.$Itemid.'&view=finish&catid='.$cat_id.'&list='.$id_text.'&user='.$user_random_id); } else { // only one file selected $database->setQuery("SELECT cat_id, file_title FROM #__jdownloads_files WHERE file_id = '".(int)$marked_files_id[0]."'"); $cat_id = $database->loadObject(); $filename = JRoute::_('index.php?option='.$option.'&Itemid='.$Itemid.'&view=finish&cid='.(int)$marked_files_id[0].'&catid='.$cat_id->cat_id); $download_link = $filename; $file_title = ' - '.$cat_id->file_title; } } Kod funkcji ss_zip na stronie : http://pastebin.pl/64315 Pewna rzecz mnie jednak martwi: jak ktoś wybierze więcej niż jeden plik, to według napisanego przeze mnie kodu jak skrypt je skompresuje? Przepraszam za dosyć sporą chaotyczność, ale myślenie nie działa najlepiej o pierwszej w nocy. @edit Aha, przecież tam pętla jest! To co w takim wypadku? Chyba exec zip odpada. Co można użyć, by zastąpić obecny skrypt? Edytowano Lipiec 19, 2012 przez draker (zobacz historię edycji) Udostępnij ten post Link to postu Udostępnij na innych stronach
Glibnes 0 Zgłoś post Napisano Lipiec 20, 2012 A może zainteresuj się kompresją gzip? PHP ma własne, wbudowane funkcje do jej obsługi, a i prawdopodobnie stworzyć tarballa to nie problem, wystarczy przedrzeć się przez Manuala: http://www.php.net/manual/pl/book.zlib.php Udostępnij ten post Link to postu Udostępnij na innych stronach
draker 0 Zgłoś post Napisano Lipiec 20, 2012 Właśnie wydaje mi się, że gzip nie jest najlepszą opcją, bo chyba w Windowsach standardowo nie ma obsługi gzipa, a szczególnie w Windowsie XP? Mam sporo dosyć niedoświadczonych userów, którzy nie będą szukać jakiegoś dodatkowego programu, tylko poszukają czegoś u konkurencji. Wczoraj wpadłem na "myśl": zamienić w pętli $zip->add_file na coś w stylu zmiennej, która zawierałaby w sobie $filename odstęp. Potem powtarza się pętla i dodaje się kolejne $filename odstęp. Czy da się takie coś zrobić w jednej zmiennej? Potem wystarczyłoby zrobić exec zip $user_random_id $tazmiennaoktorejmowa Udostępnij ten post Link to postu Udostępnij na innych stronach
draker 0 Zgłoś post Napisano Lipiec 23, 2012 Ktoś ma jakis pomysł? Udostępnij ten post Link to postu Udostępnij na innych stronach