Jérôme Cutrona

Version statique de l'intranet de Jérôme Cutrona - Rejoindre la version dynamique 🔒

Les exemples et corrections sont potentiellement non fonctionnels.

B.U.T. Informatique - IUT de Reims - Université de Reims

Authentification et sessions - Sujet complémentaire

Navigation

Objectifs de la séance

  • Effectuer les contrôles sur le fichier reçu
  • Générer dynamiquement des images en PHP
  • Transformer une image reçue, en format et en dimensions
  • S'amuser avec les images en PHP

Consignes

Ce sujet complémentaire est la suite du TP « Envoi de fichiers ». Les questions seront logiquement traitées dans le même dépôt Git que le sujet principal.

Renforcement des contrôles sur le fichier reçu

La documentation officielle sur les envois de fichiers mentionne l'utilisation d'un champ caché de formulaire nommé « MAX_FILE_SIZE » qui doit contenir la taille maximale admissible par le serveur Web propulsé par PHP. Classiquement, cette valeur peut être trouvée dans le fichier de configuration de PHP « php.ini », plus précisément dans la directive « upload_max_filesize ». Les valeurs sont exprimées en octets ou, plus souvent, en Kio, Mio ou Gio grâce aux suffixes « K », « M » et « G » (par exemple « 2M » pour 2 Mio, soit 2×1024×1024=2097152 octets). Pour consulter cette valeur programmatiquement, il faut utiliser la function « ini_get() ». Puisque nous sommes dans une démarche de conception et de réutilisation, vous allez développer la classe « ServerConfiguration\Directive » qui consulte les valeurs de façon fiable et permet également d'effectuer les transformations du type chaîne « 2M » en entier « 2097152 ». Diagramme de la classe Directive

Travail à réaliser
  1. Créez la classe « ServerConfiguration\Directive »
  2. Définissez la méthode « get() » qui retourne la valeur de la directive dont le nom lui est passé en paramètre
  3. Définissez la méthode « getInBytes() » qui retourne la valeur en octets de la directive dont le nom lui est passé en paramètre :
    • Récupérez la valeur de la directive demandée
    • Utilisez l'expression rationnelle « '/([0-9]+)([gmk]?)/i' » avec preg_match() pour capturer (les éléments en parenthèse sont capturés et placés dans le tableau « matches » en troisième paramètre de la fonction) la valeur numérique et l'éventuel suffixe d'unité (« K », « M » ou « G »)
    • Selon le suffixe, effectuer les opérations suivantes dans l'ordre et sans exclusivité des cas (un « switch » sans « break » !) :
      G
      valeur numérique = valeur numérique × 1024
      M
      valeur numérique = valeur numérique × 1024
      K
      valeur numérique = valeur numérique × 1024
  4. Définissez la méthode « getUploadMaxFilesize() » qui retourne la valeur en octets de la directive « upload_max_filesize »
  5. Testez la dernière méthode qui devrait retourner « 2097152 »
  6. Ajoutez une méthode de classe « maxFileSize() » à la classe « UserAvatar » qui retourne la valeur en octets de la taille maximale de la propriété « avatar » en base de données
  7. Modifiez le formulaire produit dans la méthode « toHtml() » de la classe « UserProfileWithAvatar » afin qu'il intègre un champ caché « MAX_FILE_SIZE » ayant pour valeur le minimum de « Directive::getUploadMaxFilesize() » et de « UserAvatar::maxFileSize() »
  8. Ajoutez une méthode de classe « isValidFile(string \$filename) » à la classe « UserAvatar » contrôle que le fichier dont le chemin est passé en paramètre est bien un fichier de type PNG et qu'il s'ouvre correctement (lisez simplement ses dimensions avec getimagesize())
  9. Contrôlez que la taille du fichier reçu est bien inférieure à la valeur de « UserAvatar::maxFileSize() » et qu'il est valide au sens de la méthode « UserAvatar::isValidFile() »

Génération dynamique d'images en PHP

PHP, associé à la bibliothèque GD, permet de manipuler des images. Cependant, la bibliothèque propose uniquement une vision non orientée objet. Afin de vous familiariser avec le développement objet en PHP, une encapsulation objet des fonctionnalités GD vous est proposée sous la forme d'une classe MyGdImage. Toutes les fonctions GD qui admettent comme premier paramètre une ressource issue de la création d'une image GD ont été transformées en méthodes de la classe MyGdImage. Par exemple, la fonction GD bool imageFilledRectangle( resource $image, int $x1, int $y1, int $x2, int $y2, int $color ) devient la méthode bool filledRectangle( int $x1, int $y1, int $x2, int $y2, int $color ) de la classe MyGdImage. Notez la disparition du paramètre de type ressource (qui est devenu un attribut de l'instance) ainsi que la suppression du mot 'image' dans le nom de la méthode. Les fonctions de la bibliothèque GD qui n'admettent pas une ressource comme premier paramètre sont des méthodes statiques de la classe MyGdImage. Pour connaître l'ensemble des fonctions GD, consultez la documentation. Pour finir, la construction d'instances de la classe MyGdImage est possible grâce à trois méthodes de classe :

  • MyGdImage::createFromSize(int $sx, int $sy) pour créer une image vide de taille $sx × $sy
  • MyGdImage::createFromString(string $data) pour créer une image à partir d'une chaîne de caractères $data contenant l'équivalent des données d'un fichier image.
  • MyGdImage::createFromFile(string $file, string $type) pour créer une image à partir d'un fichier $file existant sur le serveur. Le type du fichier est donné par $type qui prend ses valeurs dans les constantes de la classe MyGdImage :
    • MyGdImage::GD pour un fichier de type GD
    • MyGdImage::GD2PART pour un fichier de type GD2PART
    • MyGdImage::GD2 pour un fichier de type GD2
    • MyGdImage::GIF pour un fichier de type GIF
    • MyGdImage::JPEG pour un fichier de type JPEG
    • MyGdImage::PNG pour un fichier de type PNG
    • MyGdImage::WBMP pour un fichier de type WBMP
    • MyGdImage::XBM pour un fichier de type XBM
    • MyGdImage::XPM pour un fichier de type XPM

Un exemple de code pourrait être : et le résultat serait :Exemple de génération d'image avec MyGdImage

Travail à réaliser

Transformation de la taille et du type des images reçues

Jusqu'à présent, pour simplifier la réalisation de TP, vous pouvez envoyer des images de type PNG uniquement. Il serait intéressant de proposer à l'utilisateur de soumettre une image de type PNG, JPEG voire GIF qui sont les formats historiques du Web. De plus, à part la limite de taille de contenu à 65535 octets, l'image n'est pas contrainte dans ses dimensions en pixels. Il serait judicieux de redimensionner, sur le serveur, le fichier reçu de l'utilisateur pour en faire une image aux mêmes proportions avec une dimension maximale de 150 pixels en largeur et en hauteur (cette valeur est arbitraire).

Pour cela, vous devez utiliser « MyGdImage ».

Travail à réaliser
  • Consultez la documentation des « Fonctions de bufferisation de sortie »
    Information

    La bibliothèque GD propos uniquement d'enregistrer un fichier ou le transmettre au navigateur du client. Il est donc impossible de récupérer directement les données d'une image générée. Dans le cadre de l'exercice demandé, cela impliquerait d'enregistrer l'image résultat dans un fichier pour pouvoir relire son contenu, ce qui est très inefficace. L'alternative est de capturer le flux de sortie pour récupérer son contenu et ainsi ne pas passer par le disque du serveur pour gagner du temps.

    Afin de vous faciliter la tâche, « MyGdImage », l'encapsulation objet de « GdImage », contient une méthode de capture du tampon de sortie (« protected static function captureOutputBuffer(callable $callback): string ») qui est utilisée dans les méthodes « getJpeg() », « getPng() » et « getGif() » pour récupérer le contenu de l'image générée.

  • Détectez le type d'image reçu et faites en sorte de transformer les types qui ne sont pas PNG
  • Redimensionnez l'image reçue pour que sa dimension la plus grande soit égale à 150 pixels

S'amuser avec les images

Réalisez les scripts permettant d'obtenir les images suivantes : Exercice 2 Exercice 3

Réalisez un ciel étoilé avec la lune dont la phase est passée en paramètre (de 0 à 100) : Exercice 5 Exercice 5

Pour les plus enthousiastes d'entre-vous, utilisation de filter pour réaliser des convolutions : Exercice 4 avec le noyau noyau de convolution détection de contours, devient : Exercice 4