Générateur de PDF atteint ses limites !

Eléphant du PHP | 72 Messages

22 nov. 2006, 15:14

Bonjour à tous :D

Je m'occupe du site ILove5A.be qui propose pour les élèves belges une foule de feuilles de cours numérisées. Pour le téléchargement de ces cours, j'utilise la librairie gratuite FPDF qui me permet de "compiler" plusieurs feuilles dans un seul fichier PDF. Le système me permet d'ajouter facilement des feuilles sans devoir refaire le PDF en local. Très pratique donc. Malheureusement le système montre ses limites car depuis que le nombre de visites (et de téléchargements) a considérablement augmenter, le serveur n'en peut plus d'utiliser sa memoire pour mon script et j'ai été obligé d'abaisser le nombre de feuilles par PDF à 12 ... alors qu'il pouvait en gérer plus de 25 avant.
Aussi, je me demande s'il ne serait pas possible de générer le PDF petit à petit, quite à faire attendre le visiteur quelques secondes ...
J'ai pensé à une interface Flash qui demanderait à intervale régulier au serveur de générer 2-3 pages l'une à la suite de l'autre ... mais dans ce cas comment tout recompiler pour que le tout ne fasse qu'un fichier PDF ?
Je suis donc un peu perdu, c'est pourquoi je solicite vos cerveaux :D pour m'aider à trouver une solution.

Merci d'avance
QMeuh

Eléphant du PHP | 152 Messages

24 nov. 2006, 11:54

12 feuilles ?
ça me parait peu pour atteindre les limites
de FPDF.

Peu être que ton script est trop gourmand ?

Pourrais-tu nous montrer ton code ?

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

24 nov. 2006, 11:59

Bonjour,

Au lieu de générer à la volée à chaque demande le PDF, pourquoi ne pas mettre un cache qui permettrait de générer le PDF qu'à la 1ère demande et ensuite uniquement renvoyer vers le PDF.
ça permettrait d'économiser pas mal de ressources serveur :)
Quand tout le reste a échoué, lisez le mode d'emploi...

Invité
Invité n'ayant pas de compte PHPfrance

24 nov. 2006, 23:07

Au lieu de générer à la volée à chaque demande le PDF, pourquoi ne pas mettre un cache qui permettrait de générer le PDF qu'à la 1ère demande et ensuite uniquement renvoyer vers le PDF.
Impossible, j'y ai bien sûr pensé mais l'espace disque me manque :lol:

Sinon voici le code de la page qui génére le fichier :
<?php 

if (isset ($_GET['id'])) {

header('Content-type: application/pdf');

require('download/fpdf/fpdf.php');

include('includes/config.php');

$id = $_GET['id'];

mysql_connect($dbhost, $dbuser, $dbpasswd) or die('Erreur de connexion');
mysql_select_db($dbname) or die('Base inexistante');  

$sql = 'SELECT * FROM `site_v5_fichiers` WHERE `id` = '.$id;
$query = mysql_query($sql) or die('Erreur1'); 
$file = mysql_fetch_array($query);

$pdf=new FPDF('P','mm','A4');
$pdf->Open();

$pdf->SetAuthor('ILove5A.be');
$pdf->SetCreator('© ILove5A.be');
$pdf->SetTitle($file['titre'].' - '.$file['soustitre']);

$sql = 'SELECT * FROM `site_v5_cours` WHERE `id` = '.$file['cours'];
$query = mysql_query($sql) or die('Erreur2'); 
$cours = mysql_fetch_array($query);

$pdf->SetSubject('Cours de '.$cours['nomannee']);
$pdf->SetFont('Arial','',8);
$pdf->SetTextColor(0,0,0);

$sql = 'SELECT * FROM `site_v5_feuilles` WHERE `fichier` = '.$id.' ORDER BY `id` ASC';
$query = mysql_query($sql) or die('Erreur3'); 
$count = 1;

while ($list = mysql_fetch_array($query)) {

	if ($list['flip'] == 'P') {	$pdf->SetMargins(5,5); }
	else { $pdf->SetMargins(7,4); }

	$pdf->AddPage($list['flip']);
	$chemin = 'feuilles/'.$list['id'].'.jpg';	

	if ($list['flip'] == 'P') {	$pdf->Image($chemin,5,15,200,282); }
	else { $pdf->Image($chemin,7.5,10,282,200); }	

	if ($list['flip'] == 'P') {		

		$pdf->Write(6,'© ILove5A.be - '.$cours['cours'].' > '.$file['titre'].' - '.$file['soustitre'].'','http://www.ilove5a.be/'); 
	} else { 	

		$pdf->Write(4,'© ILove5A.be - '.$cours['cours'].' > '.$file['titre'].' - '.$file['soustitre'].'','http://www.ilove5a.be/');  
	}	

	$pdf->Cell(0,4,'Page '.$count.' de '.$file['pages'].'',0,0,'R');

	$count++;
	
	

}

mysql_close();

$pdf->Output();

} else { header("Location: index.php"); exit(); }

?>

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

24 nov. 2006, 23:29

Il faut dire que ces fichiers PDF sont essentiellement composés de gros scans JPEG qui au total avoisinnent pour la plupart ou même dépassent les 5-6 MiB. J'ai bien peur que la seule solution soit d'implémenter un cache comme le suggère @rthur, et donc trouver un hébergement plus conséquent :?

Ou alors tu sauvegardes tous les fichiers PDF puis tu effaces les images du serveur ?

Eléphant du PHP | 72 Messages

24 nov. 2006, 23:35

Ou alors tu sauvegardes tous les fichiers PDF puis tu effaces les images du serveur ?
Il faudrait alors que j'upgrade mon abonnement chez One.com pour 4 Go car je fais souvent des mises à jours :? Ce serait alors la seule solution ... Il n'existe aucun autre moyen ?
Autrement merci beaucoup de vos réponses :D

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

24 nov. 2006, 23:58

Disons que tu pourrais générer les PDF et les héberger chez un hébergeur gratuit comme free.fr. Tu dois même pouvoir automatiser le truc en PHP pour ne pas tout faire à la main, mais ça reste une solution un peu bancale.

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

25 nov. 2006, 00:40

J'ai créé ça pour tester le concept:
<?php

@set_time_limit(0);
$filename = basename($_SERVER['REQUEST_URI']);

if (!preg_match('#^[0-9]+@[0-9]+@([0-9]+)\\.pdf$#', $filename, $m))
{
	exit;
}

$id = $m[1];
$filepath = 'cache/' . $filename;
$url = '../cache/' . urlencode($filename);

if (!file_exists($filepath))
{
	header('Refresh: 5;url=' . $url, TRUE, 301);
	stream_copy_to_stream(fopen('http://download.ilove5a.be/pdf.php?id=' . $id, 'rb'), fopen($filepath, 'wb'));
}

header('Location: ' . $url, TRUE, 301);
Disons que tu le sauvegardes sous le nom "pdf.php" à l'adresse http://example.com/pdf.php et que tu crées un sous-dossier "cache" dans lequel on peut lire et écrire. À partir de là, tu devrais pouvoir accéder aux fichiers sous la forme d'une url comme http://example.com/pdf.php/2@[email protected]

Si le fichier existe déjà chez example.com alors l'utilisateur est immédiatement redirigé, sinon une copie est téléchargée à partir du site principal puis l'utilisateur est redirigé. Je te laisse tester et améliorer selon tes besoins.

Mammouth du PHP | 1029 Messages

27 nov. 2006, 10:32

Bonjour,

As-tu fais des test avec Fpdi?

Cela te permet de créer des pdf à partir de pdf déja générer, cela éviterais de passer par tes images pour l'utilisateur final.
L'expérience est la somme de toutes nos erreurs.