Skocz do zawartości
Zaloguj się, aby obserwować  
draker

Kompresja plików przez PHP

Polecane posty

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 przez draker (zobacz historię edycji)

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

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

Bądź aktywny! Zaloguj się lub utwórz konto

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto

Zarejestruj nowe konto, to proste!

Zarejestruj nowe konto

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się

Zaloguj się, aby obserwować  

×