 |
 |
|
|
 |
| |
 |
Downloads > Add-On |
 |
|
 |
| |
|
|
|
|
| |
Memory optimisation
InformationsAuthor: Philip Clarke License: Freeware
DescriptionNormally FPDF compresses the entire PDF in the _putpages() method at the very end of PDF
generation, this can lead to a large uncompressed PDF being stored in memory.
This modification compresses each finished page in _endpage() reducing the overall memory
usage when generating large PDFs.
To test with minimal external influences, use a file such as the provided test.php. In one
terminal window as root run top like so:
~> top -q | grep php
then run the script from the command line, using:
~> php -q test.php > with_opt.pdf
The "top" terminal window will scroll detailing memory usage of php (press q to exit).
Then altering test.php to use the base class and running:
~> php -q test.php > no_opt.pdf
will show the original behaviour giving identical sized PDF files (no_opt.pdf and
with_opt.pdf). On a 600 MHz dual processor typical results were that the optimised php
code uses a maximum of 7.3 Megabytes wheareas the original uses 15 M. Both tests
typically take 2 minutes 15 secs. Over very large reports (2000 pages +) the optimised
version is very slightly slower by a few seconds.
Source
<?php require('fpdf.php');
class PDF_Opt extends FPDF {
function _putpages() { $nb=$this->page; if(!empty($this->AliasNbPages)) { //Replace number of pages for($n=1;$n<=$nb;$n++) $this->pages[$n]=($this->compress) ? gzcompress(str_replace($this->AliasNbPages, $nb, gzuncompress($this->pages[$n]))) : str_replace($this->AliasNbPages, $nb, $this->pages[$n]) ; } if($this->DefOrientation=='P') { $wPt=$this->fwPt; $hPt=$this->fhPt; } else { $wPt=$this->fhPt; $hPt=$this->fwPt; } $filter=($this->compress) ? '/Filter /FlateDecode ' : ''; for($n=1;$n<=$nb;$n++) { //Page $this->_newobj(); $this->_out('<</Type /Page'); $this->_out('/Parent 1 0 R'); if(isset($this->OrientationChanges[$n])) $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]', $hPt, $wPt)); $this->_out('/Resources 2 0 R'); if(isset($this->PageLinks[$n])) { //Links $annots='/Annots ['; foreach($this->PageLinks[$n] as $pl) { $rect=sprintf('%.2f %.2f %.2f %.2f', $pl[0], $pl[1], $pl[0]+$pl[2], $pl[1]-$pl[3]); $annots.='<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /Border [0 0 0] '; if(is_string($pl[4])) $annots.='/A <</S /URI /URI '.$this->_textstring($pl[4]).'>>>>'; else { $l=$this->links[$pl[4]]; $h=isset($this->OrientationChanges[$l[0]]) ? $wPt : $hPt; $annots.=sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]>>', 1+2*$l[0], $h-$l[1]*$this->k); } } $this->_out($annots.']'); } $this->_out('/Contents '.($this->n+1).' 0 R>>'); $this->_out('endobj'); //Page content $this->_newobj(); $this->_out('<<'.$filter.'/Length '.strlen($this->pages[$n]).'>>'); $this->_putstream($this->pages[$n]); $this->_out('endobj'); } //Pages root $this->offsets[1]=strlen($this->buffer); $this->_out('1 0 obj'); $this->_out('<</Type /Pages'); $kids='/Kids ['; for($i=0;$i<$nb;$i++) $kids.=(3+2*$i).' 0 R '; $this->_out($kids.']'); $this->_out('/Count '.$nb); $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]', $wPt, $hPt)); $this->_out('>>'); $this->_out('endobj'); }
function _endpage() { //End of page contents $this->pages[$this->page] = ($this->compress) ? gzcompress($this->pages[$this->page]) : $this->pages[$this->page]; $this->state=1; }
}
?>
|
ExampleHere is an example of test script.
<?php ini_set('memory_limit', '100M'); ini_set('max_execution_time', 0);
define('FPDF_FONTPATH', 'font/'); require('memory_opt.php');
// for testing purposes only stops a bug where command line php // believes that headers have already been sent
class TESTING_PDF extends PDF_Opt {
function Output() { echo $this->buffer; }
}
$pdf = new TESTING_PDF(); $pdf->Open(); $pdf->AddPage(); $pdf->SetFont('Arial', '', 9); // generate a constant amount of text for testing for($i=1; $i<200; $i++) $txt .= 'ashfsd kjsahkasjh akjhdsfjkh djshf sjkh ' ; for($i=1; $i<1000; $i++) $pdf->Write(9, $txt); $pdf->Close(); $pdf->Output();
?>
|
DownloadZIP | TGZ
| | |