Image avec FPDF

Résolu
cs_sebalex Messages postés 153 Date d'inscription vendredi 25 février 2005 Statut Membre Dernière intervention 6 janvier 2017 - 19 oct. 2009 à 20:08
 Franck - 12 août 2013 à 16:12
Bonsoir à toutes et à tous,

Voici un bout de mon code. Avec ce code (FPDF), je crée un document PDF. A présent, je souhaite qu'en fonction de la base, il s'affiche tel ou tel logo.
$this->Image('../logos/a_a.jpg',95,15,20);

Lorsque j'écris :
class PDF extends FPDF
{
//En-tête
function Header()
{
//Logo
$this->Image('../logos/a_a.jpg',95,15,20);

ça fonctionne mais :

class PDF extends FPDF
{
//En-tête
function Header()
{
//Logo
$this->Image('../logos/'<?PHP echo $row_logo['logo'];?>.jpg',95,15,20);

j'ai un message d'erreur disant que le fichier n'est pas un document reconnu alors que le fichier $row_logo... est le même) !!!

Je n'y comprends plus rien.

Quelqu'un pourrait m'aider ?


Merci mille fois et bonne soirée à tous.


David
A voir également:

12 réponses

neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 18
20 oct. 2009 à 09:53
Ok.
Alors concernant la syntaxe de global, il faut séparer les variables que l'on souhaite rendre accessibles par des virgules, pas par des points-virgules. le point-virgule indique la fin d'une instruction, commande, fonction, bref, qu'il faut passer à autre chose.
global $nom, $logo, $adresse;


Du coup, pour rendre dynamique dans ta classe le logo :
$this->Image('../logos/'.$logo,95,15,20);


Cependant, je crois que la manière de gérer cette variable dans ta classe n'est pas judicieuse. Je vais essayer de ne pas dire de bêtise, c'est pas évident sans voir tout le code dans son ensemble.

Au lieu d'utiliser le mot clé global, il est peut-être plus judicieux, puisque tu étends la classe FPDF, de profiter de l'occasion pour passer le chemin du logo en paramètre lors de l'instanciation de l'objet (ou juste après, peu importe).

En gros, ça donnerait un truc comme ça :
class PDF extends FPDF {
  var $logo;
  function PDF($orientation, $unit, $format) {
    parent::FPDF($orientation, $unit, $format);
  }

  function setLogo($logo) {
    // Il faut passer le chemin complet vers le logo
    $this -> logo = $logo;
  }

  function header() {
    if (file_exists($this -> logo) && !is_dir($this -> logo)) {
      $this->Image($this -> logo,95,15,20);
    }
    // Et la suite...
  }
}


Cette manière de faire est de loin plus propre et plus facile à maintenir.
La méthode setLogo() permet de définir le logo à utiliser comme image. Tel que j'ai écrit le code, il faut passer le chemin complet, mais tu peux facilement modifier le truc pour laisser le chemin en dur dans la classe (ce que je n'aime pas trop faire pour des raisons d'évolutivité et de réutilisabilité : si tu veux utiliser une image qui se trouve ailleurs, tu es coincé et obligé de modifier ton code).
J'ai rajouté une vérification comme quoi le fichier image existe bel et bien, on peut pousser plus les tests, déclencher une erreur si l'image n'existe pas, utiliser une image par défaut... Bref, t'en fais ce que tu veux, quoi, je me suis juste permis de mettre le doigt sur la nécessité de vérifier l'existance du fichier.

Telle que tu avais fait ta classe, si tu voulais générer plusieurs fichiers PDF avec un seul script, tu aurais été sacrément emmerdé. Là, pas de problème : tu instancies une fois la classe, tu lui passes les paramètres, tu génère ton PDF et tu peux recommencer en passant de nouveaux paramètres pour générer un nouveau PDF sans avoir à instancier à nouveau la classe (donc consommation moindre en terme de ressources processeur et mémoire).

J'apprécie très sincèrement ton aide et te remercie de tes efforts. C'est grâce à des personnes comme toi que l'on progresse.

Arrête ton char, Marcel, il parait que j'me la pète et que j'envoie promener les gens en leur disant de lire la doc... ^^
Si t'as d'autres questions, y'a la doc de PHP :o) Mais non, j'plaisante, hésite pas ;)

--
Neige

Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)
3
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 18
19 oct. 2009 à 21:50
Salut,

Mais pourquoi ouvrir une balise PHP dans du code PHP ? Ca n'a pas de sens, donc PHP n'aime pas (et il a bien raison ^^)
Au lieu de :
$this->Image('../logos/'<?PHP echo $row_logo['logo'];?>.jpg',95,15,20); 

écrire :
$this->Image('../logos/'.$row_logo['logo'].'.jpg',95,15,20);


--
Neige

Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)
0
cs_sebalex Messages postés 153 Date d'inscription vendredi 25 février 2005 Statut Membre Dernière intervention 6 janvier 2017
19 oct. 2009 à 22:50
Il s'agit bien sur d'une erreur de ma part. J'entendais bien sans les balises. Mais même comme ça ça ne fonctionne pas

David
0
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 18
19 oct. 2009 à 22:59
Que contient la variable $row_logo['logo'] ?
Pour deboguer :
var_dump($row_logo['logo']);


--
Neige

Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_sebalex Messages postés 153 Date d'inscription vendredi 25 février 2005 Statut Membre Dernière intervention 6 janvier 2017
19 oct. 2009 à 23:06
Elle contient le nom du fichier "logo". Dans mon exemple, au lieu de mettre la variable sous forme de $row_logo.... j'écris directement le nom du fichier et cela fonctionne par contre quand je fais appel à la variable et j'écris $row_logo... ça ne fonctionne plus. J'essayerai avec var_dump.

Merci de ta précieuse aide et bonne soirée.


David
0
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 18
19 oct. 2009 à 23:16
Je me doutais bien de la nature de ce que cette variable contient ;)
L'idée est de vérifier qu'elle contient effectivement ce qu'elle est censée contenir.

Un petit indice : si le code de ton script est tel que tu le présentes, c'est à dire si la variable $row_logo est définie en dehors de la méthode Header(), alors il est normal que ça ne fonctionne pas, puisqu'il y a un problème de portée de variable... Celle-ci n'est pas accessible depuis une fonction si elle n'est pas explicitement importée (global $row_logo; par exemple) ou passée en paramètre à la méthode Header();

--
Neige

Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)
0
cs_sebalex Messages postés 153 Date d'inscription vendredi 25 février 2005 Statut Membre Dernière intervention 6 janvier 2017
19 oct. 2009 à 23:24
Merci mille fois de ces efforts.

Jusqu'à présent, j'utilise un code php relativement simple (pour moi) mais là tu me parles presque "chinois" :). Aurais-tu un chti exemple à me communiquer soit pour le "global..." soit pour passer en paramètre à la méthode Header ();

Ce serait cool.

Bien à toi


David
0
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 18
20 oct. 2009 à 01:01
Comme j'aime bien la doc de PHP, voici un peu de lecture : Portée des variables

Une variable définie dans le script "principal" (celui qui est directement appelé) ne sera pas accessible dans une fonction (ou une méthode d'un objet) sans être importée explicitement.
Pour la rendre accessible, tu peux :
function Header() {
global $row_logo;
//Logo
$this->Image('../logos/'<?PHP echo $row_logo['logo'];?>.jpg',95,15,20);


La ligne global $row_logo; rend la variable $row_logo accessible dans cette méthode. Tu peux donc la manipuler normalement.
Ceci n'est pas la manière la plus recommandée, bien que ça ne présente pas spécialement un risque de sécurité (il ne faut pas le faire de manière systématique avec les variables qui proviennent de saisie utilisateur, comme $_GET pour les arguments dans l'url, $_POST pour les données des formulaires ou $_COOKIE pour les données stockées dans les cookies sur le navigateur client).

Tu peux aussi accéder à cette variable en utilisant l'index du même nom sur le tableau $GLOBALS :
function Header() {
//Logo
$this->Image('../logos/'<?PHP echo $GLOBALS['row_logo']['logo'];?>.jpg',95,15,20); 


Mais cela ne fonctionne que si la variable est définie dans le "script principal", donc pas si elle est définie dans une autre fonction (il me semble...)

L'autre solution, parmi les plus "propres" (du fait qu'on contrôle mieux les données et d'où elles sont accessibles, donc par qui/quoi elles peuvent être manipulées) consiste à passer une variable en argument d'une fonction (ou méthode d'objet). Cela se fait simplement :
ma_fonction($ma_variable);
Ainsi, la variable $ma_variable sera accessible dans la fonction ma_fonction().

Dans ton cas, il s'agit d'une classe qui étend FPDF. Je vois dans la doc de FPDF que :
Cette méthode permet de définir l'en-tête de page. Elle est appelée automatiquement par AddPage() et ne devrait donc pas être appelée explicitement par l'application.

Par conséquent, tu n'as pas de contrôle sur la méthode AddPage (à moins que tu ne la surcharges, c'est à toi de voir dans quelle mesure c'est possible, utile, pertinent, etc). Donc cette solution ne semble pas indiquée.

Donc questions :
- où est-ce que tu définies cette variable $row_logo ?
- que contient-elle effectivement à cet endroit du code ? Cf mon précédent message où je t'indiquais d'utiliser var_dump() pour le savoir (fonction qui renseigne sur le type et le contenu de la variable)

--
Neige

Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)
0
cs_sebalex Messages postés 153 Date d'inscription vendredi 25 février 2005 Statut Membre Dernière intervention 6 janvier 2017
20 oct. 2009 à 09:31
Merci encore et pour être vraiment précis, voici la structure :

J'ai une base de données (MySql) avec un champ "logo", un champ "nom" et un champ "adresse".
Dans mon script initial, j'écris :

mysql_select_db($database_connexion, $connexion);
$query_club "SELECT * FROM clubs WHERE id_club '$row_licences[id_club]'";
$club = mysql_query($query_ club, $connexion) or die(mysql_error());
$row_ club = mysql_fetch_assoc($club);

Ensuite je détermine les variables :

$nom = $row_club['nom_club'];
$adresse = $row_club['adresse_club'];
$logo = $row_club['logo']; // Dans mon exemple, la donnée s'appelle "a_a.jpg" (ce fichier se trouve dans l'arborescence du site)

Ensuite j'écris mon script d'entête :

class PDF extends FPDF
{
//En-tête
function Header()
{
global $nom; $logo; $adresse;
//Logo
$this->Image('../logos/a_a.jpg',95,15,20);
$this->SetFont('Arial','B',9);
//Titre
$this->Cell(0,18,'',0,2,'C');
$this->SetTextColor(100);
$this->Cell(0,10,''.$nom.'',0,2,'C');
$this->SetFont('Arial','',5);
$this->SetTextColor(0);
$this->Cell(0,2.5,''.$adresse.'',0,2,'C');
//Saut de ligne
$this->Ln(17);
//Décalage à droite
$this->Cell(110);
}

Pour les variables $nom et $adresse, lors de la création du PDF, le script reprend les données de la BDD (donc ok) mais pour le logo, j'ai un message disant que le fichier image n'est pas supporté. J'aimerais savoir comment écrire le code à la place du nom du fichier (en rouge).


J'apprécie très sincèrement ton aide et te remercie de tes efforts. C'est grâce à des personnes comme toi que l'on progresse.


Bien à toi





David
0
cs_sebalex Messages postés 153 Date d'inscription vendredi 25 février 2005 Statut Membre Dernière intervention 6 janvier 2017
20 oct. 2009 à 10:22
Tu es le meilleur !!!

J'ai écris :

$this->Image('../logos/'.$logo,95,15,20); (avec global $nom, $logo, ...)

Et ça fonctionne à merveille.


A présent, je suis confronté au problème de la taille du logo. En effet, 95, 15, 20 correspond à un logo mais pas à d'autres. Comment pourrais-je faire pour qu'automatiquement, le logo se présente correctement sur le PDF ?

Une dernière ligne droite et après je te confirme que tu peux te la péter car t'es vraiment bon ;-)


David
0
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 18
20 oct. 2009 à 10:44
Qui est-ce qui t'a payé pour dire autant d'âneries ? T'as du accepter une sacré chèque quand même !!

Bref.
Si le logo n'a pas à être redimensionné, tu peux utiliser la fonction getimagesize()
$info = getimagesize($logo);
list($width, $height) = $info;
// je te laisse le soin de mettre la hauteur et la largeur au bon endroit, parce que je ne sais pas où c'est ^^
$this -> Image('../logos/'.$logo, ..., ..., ...);


Si tu veux redimensionner pour éviter que ce soit trop grand, il faut faire un rapide calcul, avec un produit en croix, rien de bien sorcier.

Pour que cela fonctionne, il est impératif que PHP soit compilé avec GD. En général, c'est le cas sur la quasi totalité des serveur mutualisés. pour le savoir, il suffit d'utiliser la fonction extension_loaded() ou de jeter un oeil au phpinfo() du serveur.

--
Neige

Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)
0
Bonjour,

En passant par la, FPDF s'occupe très bien de redimensionner tes images.

http://www.fpdf.org/

> Manuel > Image

Image(string file [, float x [, float y [, float w [, float h [, string type [, mixed link]]]]]])

w
Largeur de l'image dans la page. Il y a trois cas possibles :

Si la valeur est positive, elle représente la largeur en unité utilisateur
Si la valeur est négative, sa valeur absolue représente la résolution horizontale en dpi
Si elle n'est pas indiquée ou vaut zéro, elle est calculée automatiquement

h
Hauteur de l'image dans la page. Il y a trois cas possibles :

Si la valeur est positive, elle représente la hauteur en unité utilisateur
Si la valeur est négative, sa valeur absolue représente la résolution verticale en dpi
Si elle n'est pas indiquée ou vaut zéro, elle est calculée automatiquement


Enjoy ;)
0
Rejoignez-nous