Zipping files using PHP
Posted: Tue Aug 16, 2005 5:14 am
Currently, i have php file (process_extract_papers.php) that helps to extract papers (documents) from the database and zip it into a zip file. However, as the number of papers increase, i realized that zipping of papers stops halfway. I suspect its because of the memory allocated is insufficient. When archiving, it zips to the /tmp folder.
I am wondering if there is anyway to zip the papers successfully without changing the memory size allocated. But i have one php file (build_cd_structure.php) that manage to archive files successfully even with the increasing amount of papers coming in.
I am wondering if anyone can help combine the code from build_cd_structure.php with process_extract_papers.php and get it working. Thanks in advance.
I am wondering if there is anyway to zip the papers successfully without changing the memory size allocated. But i have one php file (build_cd_structure.php) that manage to archive files successfully even with the increasing amount of papers coming in.
I am wondering if anyone can help combine the code from build_cd_structure.php with process_extract_papers.php and get it working. Thanks in advance.
Code: Select all
//process_extract_papers.php
<?php
define(START, 0); //First record to retrieve
define (FINISH, 10000); // Last record to retrieve
$php_root_path = ".." ;
$privilege_root_path = "/admin" ;
require_once("includes/include_all_fns.php");
session_start();
require_once("includes/libzip.php");
// extract ( $_SESSION , EXTR_REFS ) ;
$err_message = " Unable to process your request due to the following problems: <br>\n" ;
$db = adodb_connect();
if (!$db){
echo "Could not connect to database server - please try later.";
exit;
}
// Get the temp directory to zip to
$tmpDir = get_cfg_var("upload_tmp_dir");
if (!($tmpDir)) $tmpDir = "/tmp";
if ( $HTTP_POST_VARS["download"] === "Start Download" )
{
$saveasname = $HTTP_POST_VARS['zipfilename'] ;
$filename = $tmpDir."/".$saveasname ;
if ( file_exists ( $filename ) )
{
// Send binary filetype HTTP header
header('Content-Type: application/octet-stream');
// Send content-length HTTP header
header('Content-Length: '.filesize($filename));
// Send content-disposition with save file name HTTP header
header('Content-Disposition: attachment; filename="'.$saveasname.'"');
// Output file
readfile($filename);
// Done
exit ;
}
}
//Make the SQL statement accroding to user selection
switch($HTTP_POST_VARS["extractType"]){
case 1:
//All papers from paper table
$papersSQL = "SELECT * FROM " . $GLOBALS["DB_PREFIX"] . "Paper P, " . $GLOBALS["DB_PREFIX"]."Track T ";
$papersSQL .= "WHERE P.TrackID = T.TrackID ";
$papersSQL .= "ORDER BY P.TrackID ASC, P.PAPERID ASC";
$dirName = "papers";
break;
case 2:
//Accepted papers
$papersSQL = "SELECT * FROM " . $GLOBALS["DB_PREFIX"] . "Paper P," . $GLOBALS["DB_PREFIX"]."PaperStatus PS, " . $GLOBALS["DB_PREFIX"]."Track T ";
$papersSQL .= " WHERE P.PaperStatusID = PS.PaperStatusID";
$papersSQL .= " AND P.TrackID = T.TrackID";
$papersSQL .= " AND PS.PaperStatusName = 'Accepted'";
$papersSQL .= " ORDER BY P.TrackID ASC, P.PAPERID ASC";
$dirName = "accepted_papers";
break;
case 3:
//Rejected papers
$papersSQL = "SELECT * FROM " . $GLOBALS["DB_PREFIX"] . "Paper P," . $GLOBALS["DB_PREFIX"]."PaperStatus PS, " . $GLOBALS["DB_PREFIX"]."Track T ";
$papersSQL .= " WHERE P.PaperStatusID = PS.PaperStatusID";
$papersSQL .= " AND P.TrackID = T.TrackID";
$papersSQL .= " AND PS.PaperStatusName = 'Rejected'";
$papersSQL .= " ORDER BY P.TrackID ASC, P.PAPERID ASC";
$dirName = "rejected_papers";
break;
case 4:
//All papers except withdrawn
$papersSQL = "SELECT * FROM " . $GLOBALS["DB_PREFIX"] . "Paper P, " . $GLOBALS["DB_PREFIX"]."Track T";
$papersSQL .= " WHERE P.TrackID = T.TrackID ";
$papersSQL .= " AND P.Withdraw = 'false' ";
$papersSQL .= " ORDER BY P.TrackID ASC, P.PAPERID ASC";
$dirName = "papers_not_withdrawn";
break;
case 5:
//Withdrawn papers
$papersSQL = "SELECT * FROM " . $GLOBALS["DB_PREFIX"] . "Paper P, " . $GLOBALS["DB_PREFIX"]."Track T";
$papersSQL .= " WHERE P.TrackID = T.TrackID ";
$papersSQL .= " AND P.Withdraw = 'true' ";
$papersSQL .= " ORDER BY P.TrackID ASC, P.PAPERID ASC";
$dirName = "withdrawn_papers";
break;
}
//Execute the query
$papersResult = $db -> Execute($papersSQL);
if(!$papersResult){
die ("Could not retrieve papers from database - please try again");
}
if( ( $totalpapers = $papersResult -> RecordCount() ) == 0){
do_html_header("No Requested Papers");
echo "<p>There are no papers of the requested type. <br>You may wish to try to extract other types.</p><a href=\"extract_papers.php\">Back</a>";
do_html_footer();
exit;
}
//Create a new class of zip library
$zipfile = new zipfile();
// add the subdirectory ... important!
$zipfile -> add_dir("$dirName/");
//Make the zip file name
if(!empty($HTTP_POST_VARS["zipfilename"]))
$zipfilename = $HTTP_POST_VARS["zipfilename"].".zip";
else
{
$conferenceInfo = get_conference_info();
$zipfilename = $conferenceInfo -> ConferenceCodeName.".zip";
}
do_html_header("Extract Papers");
?>
<form name="downloadForm" id="downloadForm" method="post" action="process_extract_papers.php">
<p>File extraction in progress...</p>
<input name="status" READONLY type="text" id="status" value="0 % Completed" size="20" maxlength="0">
<input type="hidden" name="zipfilename" value="<?php echo $zipfilename ; ?>">
<p>
<input type="submit" name="download" DISABLED id="download" value="Start Download">
</p>
</form>
<?php
do_html_footer();
// Set the timeout to infinity
set_time_limit ( 0 ) ;
// Set up TableOfContents
$TableOfContents = "<html><head>\n<title> Commence Conference System </title>\r\n" ;
$TableOfContents .= "<meta http-equiv='Content-Type' content='text/html'; charset='iso-8859-1'>\r\n </head>\n" ;
$TableOfContents .= "<h1>Commence Conference System</h1><br>\r\n" ;
$TableOfContents .= "<table width='100%' border='1' cellspacing='0' cellpadding='4'>\r\n" ;
$TableOfContents .= "<tr> <td width='70%'> </td> <td width='30%'> </td> </tr>\r\n" ;
//Loop each paper and add to zip file
$currentPage = 1; //Current Page
$currentTrack = 0; //Current Track
$i = 0; //Set loop counter
while($paperInfo = $papersResult -> FetchNextObj())
{
//Call the function to get the lastest file of the paper
$fileInfo = get_latestFile($paperInfo -> PaperID , &$err_message );
$data = $fileInfo -> File;
$name = $fileInfo -> FileName;
//Get the file type by fetchinglast 4 characters
//$fileType = substr($name,strlen($name) - 4); //Fails for .ps
$fileType = strstr($name,'.') ;
// Prepare the file structure
$currentFileName = "paper_".$paperInfo -> TrackID."_".$paperInfo -> PaperID.$fileType;
$filePath = "$tmpDir/$currentFileName";
$fileStructure = $dirName."/".basename($filePath);
//add entry to TableOfContents
$authors = retrieve_authors($paperInfo -> PaperID , &$err_message );
// Output Table of Contents Entries
if ($paperInfo -> TrackID > $currentTrack){ // Output Group Header
$currentTrack = $paperInfo -> TrackID;
$TableOfContents .= "<tr><td colspan=2 align=\"center\"><H2>".$TRACK_NAME.": ".$paperInfo -> TrackName."</H2></td></tr>\r\n";
}
$TableOfContents .= "<tr> <td> <a href=$currentFileName> #";
$TableOfContents .= $paperInfo -> PaperID ;
$TableOfContents .= " " ;
$TableOfContents .= stripslashes($paperInfo -> Title);
$TableOfContents .= "</a><br>";
$TableOfContents .= $authors ;
$TableOfContents .= "</td> <td>page $currentPage </td></tr>\r\n" ;
// Increment current page
$currentPage += $paperInfo -> NumberOfPages ;
// add the binary data stored in the string 'data'
$zipfile -> add_file($data,$fileStructure);
/* // Debug use only
echo "\$totalpapers= $totalpapers<br>" ;
echo "\$i= $i<br>" ;
echo "<br><br><br>" . $percentage_completed . "%<br>";
exit ;
*/
// Update status
$percentage = number_format(++$i / $totalpapers * 100, 1) ;
$percentage_completed = $percentage . " % Done" ;
echo '<script language="JavaScript" type="text/javascript" >' ;
echo "document.downloadForm.status.value='$percentage_completed'" ;
echo '</script>' ;
} // End while loop
//Close TableOfContents
$TableOfContents .= "</table></html>" ;
// Prepare the file structure
$filePath = $tmpDir."/index.htm";
$fileStructure = $dirName."/".basename($filePath);
// add the binary data stored in the string 'TableOfCOntents'
$zipfile -> add_file($TableOfContents,$fileStructure);
$fp=fopen( $tmpDir."/".$zipfilename , 'wb' ) ;
if ($fp) // ok, push the data
{
echo '<script language="JavaScript" type="text/javascript" >' ;
echo "document.downloadForm.status.value='Creating Zip archive'" ;
echo '</script>' ;
if ( !fwrite($fp, $zipfile -> file() ) )
{
echo "Problem in writing to file '$zipfilename' - please try again.";
exit;
}
else
{
echo '<script language="JavaScript" type="text/javascript" >' ;
echo "document.downloadForm.status.value='Finished'" ;
echo '</script>' ;
echo '<script language="JavaScript" type="text/javascript" >' ;
echo "document.downloadForm.download.disabled=false" ;
echo '</script>' ;
}
} // End if $fp condition
?>Code: Select all
//build_cd_structure.php
<?php
$php_root_path = ".." ;
$privilege_root_path = "/admin" ;
require_once("includes/include_all_fns.php");
session_start();
$new_include_path = ini_get('include_path').":$php_root_path/includes/pear";
ini_set('include_path', $new_include_path);
require_once($php_root_path."/includes/pear/HTML/Progress.php");
$err_message = " Unable to process your request due to the following problems: <br>\n" ;
//Call the function to get the conference information
$conferenceInfo = get_conference_info();
require_once($php_root_path."/includes/pear/Tar.php");
require_once($php_root_path."/admin/includes/libzipfile.php");
class File_Archiver
{
function File_Archiver( $filename ) {}
function AddString( $archival_path, $data ) {}
}
class Tar_Archiver extends File_Archiver
{
var $COMPRESSION_TYPE = false;
var $archive_file;
function Tar_Archiver( $filename )
{
echo $COMPRESSION_TYPE;
$this -> $archive_file =
new Archive_Tar($filename, $COMPRESSION_TYPE);
$this -> $archive_file -> create(array());
}
function AddString( $archival_path, $data )
{
$this -> $archive_file -> addString( $archival_path, $data );
}
}
class BZip2_Archiver extends Tar_Archiver
{
var $COMPRESSION_TYPE = 'bz2';
}
class GZip_Archiver extends Tar_Archiver
{
var $COMPRESSION_TYPE = 'gz';
}
class Zip_Archiver extends File_Archiver
{
var $filename;
var $archive_file;
function Zip_Archiver( $filename )
{
$this -> filename = $filename;
$this -> archive_file = new zipfile();
}
function AddString( $archival_path, $data )
{
$this-> archive_file -> add_file( $data , $archival_path);
$file = fopen($this -> filename, 'w');
fwrite($file, $this -> archive_file -> file());
}
}
if (!$HTTP_POST_VARS["Submit"])
{
/* START Select Archive Type page */
do_html_header("Build CD Structure");
?>
<form name="form1" method="post">
<div style="padding-top: 3mm">
Select the type of archive should be exported:
</div>
<div>
<table cellpadding="1">
<tr>
<td><input type="radio" name="enctype" value="bz2" checked /></td>
<td>bzip2</td>
<td>(*.tar.bz2)</td>
</tr>
<tr>
<td><input type="radio" name="enctype" value="gz" /></td>
<td>gzip</td>
<td>(*.tar.gz)</td>
</tr>
<tr>
<td><input type="radio" name="enctype" value="zip" /></td>
<td>zip</td>
<td>(*.zip)</td>
</tr>
</table>
</div>
<div style="padding-top: 3mm">
Base filename: <input name="filename"><br />
(conference name will be used if none given)
</div>
<div style="padding-top: 3mm">
<input type=submit name="Submit" value="Build Archive">
</div>
</form>
<?php
exit;
/* END Select Archive Type page */
}
if ( $HTTP_POST_VARS["Submit"] == "Build Archive" ) {
/* START Compiling Archive Structure page */
$archive_papers = get_papers_in_order();
// If there's no papers, tell the user.
if (count($archive_papers) == 0)
{
do_html_header("No Papers Available");
?>
<br />
<div style="padding-top: 3mm">
No papers have been accepted and scheduled yet. Without any
scheduling data, the CD structure cannot be built.
</div>
<div style="padding-top: 3mm">
If you still wish
to export papers, use the "Extract All Papers" function instead.
</div>
<?php
do_html_footer();
exit;
}
// Set up progress bar
$bar = new HTML_Progress();
$bar->setAnimSpeed(100);
$bar->setIncrement(1);
$bar->setBorderPainted(true);
$ui =& $bar->getUI();
$ui->setCellAttributes('active-color=#000084 inactive-color=#3A6EA5 width=4 spacing=0');
$ui->setBorderAttributes('width=1 style=inset color=white');
$ui->setStringAttributes(array(
'width' => 200,
'height' => 20,
'font-size' => 14,
/*'background-color' => '#C3C6C3',*/
'valign' => 'top'
));
$ui->setCellCount(100);
// Start building archive
require_once($php_root_path."/includes/pear/Tar.php");
require_once($php_root_path."/includes/pear/Zip.php");
// Get the temp directory to put the archive in
$tmpDir = get_cfg_var("upload_tmp_dir");
if (!($tmpDir)) $tmpDir = "/tmp";
if ($HTTP_POST_VARS["filename"])
$basename = $HTTP_POST_VARS["filename"];
else
$basename = $conferenceInfo -> ConferenceCodeName;
// Create the archive file
switch ($HTTP_POST_VARS["enctype"])
{
case 'bz2':
$saveasname = "$basename.tar.bz2";
$filename = $tmpDir."/".$saveasname ;
$tarFile = new BZip2_Archiver($filename);
break;
case 'gz':
$saveasname = "$basename.tar.gz";
$filename = $tmpDir."/".$saveasname ;
$tarFile = new GZip_Archiver($filename);
break;
case 'zip':
$saveasname = "$basename.zip";
$filename = $tmpDir."/".$saveasname ;
$tarFile = new Zip_Archiver($filename);
break;
default:
$saveasname = "$basename.tar";
$filename = $tmpDir."/".$saveasname ;
$tarFile = new Tar_Archiver($filename);
break;
}
$cdindex_path = $php_root_path.$privilege_root_path."/cdindex/";
ob_start();
include($cdindex_path."technical_program.php");
$htmlFile = ob_get_contents();
ob_end_clean();
$tarFile -> AddString("technical_program.html",$htmlFile);
ob_start();
include($cdindex_path."author_index.php");
$htmlFile = ob_get_contents();
ob_end_clean();
$tarFile -> AddString("author_index.html",$htmlFile);
// Tell progress bar how many papers need to be processed.
$bar->setMaximum(count($archive_papers));
// Define archiving proceedure for papers
function archive_next_paper($percent, &$bar)
{
global $archive_papers;
global $tarFile;
$paperInfo = $archive_papers[$bar -> getValue()];
if (!$paperInfo) return; // Skip empty entries (applies to 100% too)
$fileInfo = get_latestFile($paperInfo -> PaperID , &$err_message );
$fileEnding = strstr($fileInfo -> FileName, '.');
$data = $fileInfo -> File;
$name = $paperInfo -> PaperID .$fileEnding;
$tarFile -> AddString("papers/".$name, $data);
}
// Tell progress bar to archive a paper for each 'tick'
$bar->setProgressHandler('archive_next_paper');
// Start building head info
ob_start();
?>
<style type="text/css">
<?php echo $bar->getStyle(); ?>
</style>
<script type="text/javascript">
<?php echo $bar->getScript(); ?>
</script>
<?php
// Attach head info to page
$homepage -> AddExtraHeadData(ob_get_contents());
ob_end_clean();
do_html_header("Compiling CD Structure...");
?>
<center>
<span class="ProgressBar">
<?php
echo $bar->toHtml();
?>
</span>
<style type="text/css">
/* This line hides the download link initially */
.DownloadLink {display: none}
</style>
<span class="DownloadLink">
<br /><br />
<form name="form1" method="post">
<input type=hidden name="SaveAsName" value="<?php echo $saveasname ?>">
<input type=hidden name="FileName" value="<?php echo $filename ?>">
<input type=submit name="Submit" value="Download File">
</form>
</span>
</center>
<?php
do_html_footer();
// Set the timeout to infinity [run() will take a while]
set_time_limit ( 0 ) ;
// Page has reached "end", but now code is added to move progress bar.
$bar->run();
?>
<style type="text/css">
/* The progress bar must have completed, so show the download link */
.ProgressBar {display: none}
.DownloadLink {display: block}
</style>
<?php
exit;
/* END Compiling Archive Structure page */
}
/* Archive download at the top, so extra characters don't interfer */
if ( $HTTP_POST_VARS["Submit"] == "Download File" ) {
$saveasname = $HTTP_POST_VARS["SaveAsName"];
$filename = $HTTP_POST_VARS["FileName"];
/* START Archive Download */
if ( file_exists ( $filename ) )
{
// Send binary filetype HTTP header
header('Content-Type: application/octet-stream');
// Send content-length HTTP header
header('Content-Length: '.filesize($filename));
// Send content-disposition with save file name HTTP header
header('Content-Disposition: attachment; filename="'.$saveasname.'"');
// Output file
readfile($filename);
// Done
exit;
}
/* END Archive Download */
}
?>