Fiche PHP : les fichiers

Objet de la fiche

État de la fiche Terminée validée


Plan de la fiche :

Avant propos

Cette fiche aborde les possibilités offertes par PHP pour manipuler les fichiers. On verra entre autres comment en créer de différents types, comment les manipuler (avec PHP ou javascript), comment les télécharger, ou les enregistrer sur le serveur.

Points d'accés et navigation dans les répertoires

Répertoire exemple pour les informations sur les chemins

Un chemin en langage informatique correspond aux informations successives que l'on doit fournir pour atteindre le fichier ou le dossier recherché.

Les points d'entrée

Quel que soit le type de chemin choisi, il existe deux points d'entrée :

A partir du dossier où se situe le point d'entrée du script.

Utilisé par les développeurs pour construire leurs scripts, inclure des images, inclures d'autres fichiers etc.

Le chemin du point d'entrée à partir de la racine du serveur est donné par l'instruction

<?php str_replace($_SERVER['DOCUMENT_ROOT'] ,'',dirname(__FILE__)); ?>

qui donne comme résultat "/Tutoriaux/PHP"

Note :

  • $_SERVER['DOCUMENT_ROOT'] donne "/mnt/154/sda/3/1/monwebfacile" qui est le chemin physique du serveur jusqu'à la racine.
  • dirname(__FILE__) donne "/mnt/154/sda/3/1/monwebfacile/Tutoriaux/PHP" qui donne le chemin physique du serveur jusqu'au répertoire d'entrée.
  • str_replace permet d'obtenir le point d'entrée par rapport à la racine du site.


$_SERVER['PHP_SELF'] => /Tutoriaux/PHP/PHP_Fichiers.php

Exemple 1 :

Lorsque l'on veut accéder à un site on appelle souvent un fichier index.php (mais on peut l'appeler autrement) qui se situe à la racine du site.
"http://monwebfacile.free.fr" sans préciser le fichier index qui est automatiquement chargé s'il existe, ou bien "http://monwebfacile.free.fr/Monfichier.php." en précisant le fichier à charger.

Toutes références de chemin à l'intérieur de ces fichiers se feront par rapport à la racine du site

Exemple 2 :

On peut aussi choisir un autre point d'entrée dans le site.

"http://monwebfacile.free.fr/Tutoriaux/PHP/PHP_Fichiers.php"

Toutes les références de chemin à l'intérieur de ce fichier se feront par rapport au répertoire PHP.

A partir de l'arborescence physique du serveur.

Utilisé par les développeurs principalement pour trouver, créer, sauvegarder ... des fichiers dans l'arborescence.

Le chemin physique du serveur jusqu'à la racine est donné par

$_SERVER['DOCUMENT_ROOT'] => /mnt/154/sda/3/1/monwebfacile

Le chemin physique complet d'un fichier du serveur est donné par

dirname(__FILE__) => /mnt/154/sda/3/1/monwebfacile/Tutoriaux/PHP

Les chemins

Absolus

Relatifs

Les chemins relatifs se basent toujours sur le dossier où se situe le point d'entrée du programme., il est donc important de connaitre ce point d'accés.

Les chemins relatifs permettent de se rendre d'une ressource à l'autre en se promenant dans l'ensemble des répertoires pouvant contenir d'autres répertoires et/ou fichiers. Des règles élémentaires indiquent la marche à suivre pour aller d'une point à un autre dans l'arborescence du site web hébergé.

  • Descendre dans les répertoires

    Soit une page web à la racine du site. On veut y ajouter sous forme d'include le fichier "Commun_Body_Tutos.txt".

    <?php include "Tutoriaux/Includes/Commun_Body_Tutos.txt"; ?> => à partir de la racine pour atteindre le fichier on doit d'abord passer par le répertoire Tutoriaux puis par le répertoire "Includes" qui est lui-même un répertoire de "Tutoriaux" pour pouvoir accéder au fichier "Commun_Body_Tutos.txt".

    Si la page web avait été dans le répertoire "Tutoriaux" on aurait du faire <?php include "Includes/Commun_Body_Tutos.txt"; ?>. Dans ce cas on n'avait plus à passer par le répertoire "Tutoriaux".

    Qu'il y ait un ou plusieurs répertoires à descendre, le principe est toujours le même : descendre plusieurs répertoires équivaut à descendre plusieurs fois un répertoire.

  • Remonter dans les répertoires

    Si la page web est à la racine du site on ne pourra pas remonter plus avant.

    Si la page web est par exemple été dans le répertoire "Tutoriaux" et que l'on veuille aller chercher une ressource.

    Qu'il y ait un ou plusieurs répertoires à remonter, le principe est toujours le même : remonter plusieurs répertoires équivaut à remonter plusieurs fois un répertoire.

  • Explorer des répertoires

basename

dirname(__FILE__) => /mnt/154/sda/3/1/monwebfacile/Tutoriaux/PHP;

  • __FILE__ => Chemin complet et nom de fichier.
  • __DIR__ => Le répertoire du fichier.
    Pour éviter certains problèmes posés par la solution à base de dirname, PHP 5.3 introduit cette nouvelle constante magique. Celle-ci vaut exactement la même chose que dirname(__FILE__), mais évite les deux problèmes soulevés par la solution à base de dirname, à savoir :
    • La syntaxe est trés courte, donc plus rapide à saisir, et ainsi diminue le risque de fautes de frappe lorsque la commande est souvent utilisée,
    • La constante est calculée à la compilation du code, entrainant un gain au niveau des performances.

Instructions de base pour la manipulation des fichiers et des chaines

fopen()

Création d'une ressource nommée, spécifiée par le paramètre $filename, sous la forme d'un flux.

Syntaxes

fopen(string $filename,string $mode)

Paramètre $filename

Nom du fichier avec son arborescence.

Paramètre string $mode

ValeursCommentaires
'r'Ouvre en lecture seule, et place le pointeur de fichier au début du fichier.
'r+'Ouvre en lecture et écriture, et place le pointeur de fichier au début du fichier.
'w'Ouvre en écriture seule ; place le pointeur de fichier au début du fichier et réduit la taille du fichier à 0. Si le fichier n'existe pas, on tente de le créer.
'w+'Ouvre en lecture et écriture ; place le pointeur de fichier au début du fichier et réduit la taille du fichier à 0. Si le fichier n'existe pas, on tente de le créer.
'a'Ouvre en écriture seule ; place le pointeur de fichier à la fin du fichier. Si le fichier n'existe pas, on tente de le créer. Dans ce mode, la fonction fseek() n'affecte que la position de lecture, les écritures surviennent toujours.
'a+'Ouvre en lecture et écriture ; place le pointeur de fichier à la fin du fichier. Si le fichier n'existe pas, on tente de le créer. Dans ce mode, la fonction fseek() n'affecte que la position de lecture, les écritures surviennent toujours.
'x'Crée et ouvre le fichier en écriture seulement ; place le pointeur de fichier au début du fichier. Si le fichier existe déjà, fopen() va échouer, en retournant FALSE et en générant une erreur de niveau E_WARNING. Si le fichier n'existe pas, fopen() tente de le créer. Ce mode est l'équivalent des options O_EXCL|O_CREAT pour l'appel système open(2) sous-jacent.
'x+'Crée et ouvre le fichier pour lecture et écriture; le comportement est le même que pour 'x'.
'c'Ouvre le fichier pour écriture seulement. Si le fichier n'existe pas, il sera crée, s'il existe, il n'est pas tronqué (contrairement à 'w') et l'appel à la fonction n'échoue pas (comme dans le cas de 'x'). Le pointeur du fichier est positionné au début. Ce mode peut être utile pour obtenir un verrou (voyez flock()) avant de tenter de modifier le fichier, utiliser 'w' pourrait tronquer le fichier avant d'obtenir le verrou (vous pouvez toujours tronquer grâce à ftruncate()).
'c+'Ouvre le fichier pour lecture et écriture, le comportement est le même que pour le mode 'c'.
'rb'Ouvre le fichier en mode binaire.

Retour

Retourne une ressource représentant le pointeur de fichier, ou FALSE si une erreur survient.

fputs()

Ecrit en mode binaire une chaine de caractères dans le fichier référencé par la ressource retournée par fopen().

Syntaxe

fputs(ressource fichier, chaine de caractères, optionnel : longueur de la chaine)

Paramètres

  • Paramètre 1 : Pointeur de système de fichiers de type resource habituellement créé par la fonction fopen().
  • Paramètre 2 : La chaîne à écrire.
  • Paramètre optionnel : Si la longueur de la chaine est fournie, l'écriture s'arrêtera après le nombre d'octets défini, ou à la fin de la chaîne (le premier des deux).

fread()

Lecture d'un fichier en mode binaire

Syntaxes

string fread ( ressource fichier , int $length )

  • Paramètre 1 : Pointeur de système de fichiers de type resource habituellement créé par la fonction fopen().
  • Paramètre 2 : Taille length d'octets à lire. Une fois les données lues le pointeur de fichier est positionné à sa valeur initiale + $length.

Retour

Retourne la chaîne lue, ou FALSE si une erreur survient.

fgets()

Récupère la ligne courante sur laquelle se trouve le pointeur du fichier

unpack()

Déconditionne des données depuis une chaîne binaire.

Retour

Retourne un tableau associatif contenant les éléments déconditionnés d'une chaîne binaire.

fclose()

ferme le ficher

Syntaxes

fclose(ressource fichier )

explode()

Coupe une chaîne en segments. explode() retourne un tableau de chaînes, chacune d'elle étant une sous-chaîne du paramètre string extraite en utilisant le séparateur delimiter.

Syntaxes

array explode ( string $delimiter , string $string [, int $limit = PHP_INT_MAX ] )

Paramètre

Retour

Informations sur les fichiers

Taille

$taille(int) = filesize ( string $pathFichier );

Dimensions des fichiers 'image'

$infoSize = getimagesize(string $pathFichier [, array $imageinfo ] );

Retourne un tableau d'éléments.

  • $infoSize[0] : L'index 0 contient la largeur.
  • $infoSize[1] : L'index 1 contient la hauteur.
  • $infoSize[2] : L'index 2 est une constante parmi IMAGETYPE_XXX constants, indiquant le type de l'image.
  • $infoSize[3] : L'index 3 contient la chaîne à placer dans les balises IMG : height="xxx" width="yyy".
  • $infoSize["channels"] : en principe 3 pour des images RGB et 4 pour des images CMYK.
  • $infoSize["bits"] : nombre d'octets pour chaque couleur.

Plus d'autres informations de type IPTC (International Press Telecommunication Council) avec le paramètre optionnel imageinfo.

On utilisera iptcparse($imageinfo) pour analyser le bloc binaire IPTC et rechercher les balises simples. Cette partie est explicitée dans cette fiche au chapitre 'Lecture des tags de fichiers images'

Exemple


Dates des fichiers

Les fonctions suivantes permettent respectivement de déterminer la date d'accés, la date de modification (attributs,droits) etc ..
La valeur renvoyée correspond au nombre de secondes écoulées depuis le 1er janvier 1970 (c'est le format epoch UNIX). Il sera donc nécessaire d'utiliser la fonction date pour remettre en forme de cette valeur.

fileatime()

int fileatime ( string $filename )
Donne la date à laquelle le fichier a été accédé pour la dernière fois. Retourne FALSE si une erreur survient. Attention cette information n'est pratiquement jamais mise à jour par les systèmes.

filemtime()

int filemtime ( string $filename )
Donne la date à laquelle le fichier a été modifié pour la dernière fois. Retourne FALSE si une erreur survient.

filectime()

int filectime ( string $filename )
Renvoie la date à laquelle l'inode (1) a été accédé pour la dernière fois. Retourne FALSE si une erreur survient.

Formatage du résultat avec l'objet date

Note1
Un nœud d'index ou inode (contraction de l'anglais index et node) est une structure de données contenant des informations à propos d'un fichier stocké dans certains systèmes de fichiers (notamment de type Linux/Unix). À chaque fichier correspond un numéro d'inode (i-number) dans le système de fichiers dans lequel il réside, unique au périphérique sur lequel il est situé. Les inodes peuvent, selon le système de fichiers, contenir aussi des informations concernant le fichier, tel que son créateur (ou propriétaire), son type d'accès (par exemple sous Unix : lecture, écriture et exécution), etc (Source wikipedia).

Lecture de répertoires



Créer ou lire des fichiers texte pur, xml, json

Généralités

Structures

Fichiers texte pur

Fichiers xml

json

Créer ou lire un fichier PDF

Nous allons voir dans cette partie comment générer automatiquement un fichier PDF : son contenu, mais aussi les entêtes et pieds de page, ainsi que la possibilité d'appliquer un filigramme.

La librairie FPDF

Prérequis

Nous allons utiliser comme base la classe FPDF qui est une classe PHP permettant de générer des documents PDF en pur PHP, c'est-à-dire sans utiliser la librairie PDFlib. Cette librairie est libre de droit ce qui signifie que vous êtes libre de l'utiliser et de la modifier comme vous bon vous semble. Par exemple en ajoutant des classes pour répondre à vos besoins spécifiques : la classe de base est FPDF et si l'on veut ajouter un script, il suffit de créer une classe qui en hérite.

Principales fonctionnalités de FPDF

  • Choix des unités, du format des pages et des marges,
  • Gestion des en-têtes et pieds de page,
  • Saut de page automatique,
  • Saut de ligne automatique et justification,
  • Images (JPEG et PNG),
  • Couleurs,
  • Liens,
  • Support des polices TrueType et Type1,

FPDF ne nécessite aucune extension et fonctionne avec PHP 4 et PHP 5.

Installation de la librairie

Déclaration

Les bases d'un fichier pdf

Création/ouverture du fichier

Instantiation avec 3 paramètres de base : new PDF('type portrait(P ou L pour paysage)','unité de référence des mesures (mm ou autre)','format A4 (ou autre)')

Exemple : $PDF = new PDF('P','mm','A4'); pour instancier un fichier de type portrait, avec des unités en mm et au format A4

Fermeture du fichier

$PDF->Output(Paramètre 1,Paramètre 2);

  • paramètre 1 : Nom du fichier. Avec son répertoire (si nécessaire pour sauvegarde sur le serveur) si paramètre 2 => F.
  • paramètre 2 :
    • F => Enregistrement du fichier dans un répertoire du serveur avec le nom et dans le répertoire définis par le paramètre 1.
    • D => Prompt utilisateur pour choisir l'ouverture ou la sauvegarde du fichier sur le poste client. Paramètre 1 => nom du fichier.
    • I => Ouverture automatique dans le navigateur aprés avoir été généré. Paramètre 1 => nom du fichier.
    • S => Retourne le contenu du fichier pdf sous forme de chaines de caractères. Paramètre 1 => vide.

Exemple $PDF->Output("toto",F); pour enregistrer le document avec le nom 'toto' dans le répertoire courant du serveur.

Element de description du document

Titre

$PDF->SetTitle("Chaine de caractères : titre du document");

Auteur

$PDF->Setauthor("Chaine de caractères : Auteur du document");

Créateur

$PDF->SetCreator("Chaine de caractères : Créateur du document");

Sujet

$PDF->Setsubject("Chaine de caractères : Sujet du document");

Mots-clés

$PDF->SetKeywords("Chaine de caractères : Liste des mot clés du document"); La liste est une suite de mots séparés par des espaces ou une virgule.

Paramétrage général des pages

Saut de page

$PDF->SetAutoPageBreak(paramètre1, paramètre2);

  • paramètre1 = false => le saut automatique de page n'est pas activé, true => saut de page actif
  • paramètre2 : valeur du reste de marge de bas de page avant d'enclencher le saut de page.

Exemple 1 : $PDF->SetAutoPageBreak(false, 0);

Exemple 2 : $PDF->SetAutoPageBreak(true, 10); pour un saut automatique des pages s'il ne reste plus que 10 mm en bas de page

Marges

$PDF->SetMargins(Marge gauche,Marge haut,Marge droite,Marge gauche);

Les différentes marges sont définies dans les unités définis dans l'instantiation

Exemple : $PDF->SetMargins(5,5,5,5); pour définir une marge de 5 mm

Couleur du texte

Fixe la couleur pour le texte. Elle peut être indiquée en composantes RGB ou en niveau de gris. La méthode peut être appelée avant que la première page ne soit créée et la valeur est conservée de page en page. La méthode peut aussi être appelée pour changer ponctuellement la couleur d'un texte particulier.

$PDF->SetTextColor(param1,param2Optionnel,param3Optionnel);

  • param1 (r) : Si g et b sont renseignés, composante de rouge; sinon, indique le niveau de gris. Valeur comprise entre 0 et 255.
  • param2Optionnel (g) : Composante de vert (entre 0 et 255).
  • param3Optionnel (b) Composante de bleu (entre 0 et 255).

Exemple : $PDF->SetTextColor(0); pour définir la couleur noire pour le texte.

Police de caractères

Fixe la police utilisée pour imprimer les chaînes de caractères. Il est obligatoire d'appeler cette méthode au moins une fois avant d'imprimer du texte, sinon le document résultant ne sera pas valide. La police peut être soit une police standard, soit une police ajoutée à l'aide de la méthode AddFont().
Les polices standard utilisent l'encodage Windows cp1252 (Europe de l'ouest). La méthode peut être appelée avant que la première page ne soit créée et la police est conservée de page en page.

Note : pour les polices standard, il est nécessaire que les fichiers de métrique soient accessibles. Il y a trois possibilités pour cela :

  • Ils sont dans le répertoire courant (celui du script en cours d'exécution)
  • Ils sont dans un des répertoires définis par le paramètre include_path
  • Ils sont dans le répertoire défini par la constante FPDF_FONTPATH
    Exemple dans notre cas : define('FPDF_FONTPATH','phptopdf/font/');

Note : Si le fichier correspondant à la police demandée n'est pas trouvé, l'erreur "Could not include font metric file" est générée.

$PDF->SetFont(parametre1,parametre2,parametre3)

  • parametre1 : Famille de la police. Il peut s'agir d'un nom défini par AddFont() ou bien d'une desfamilles standard :
    • Courier(caractères de largeur fixe)
    • Helvetica ou Arial(synonymes; sans serif)
    • Times (avec serif)
    • Symbol (symboles)
    • ZapfDingbats (symboles)

    Note :Le nom n'est pas sensible à la casse.
    Il est également possible de passer une chaîne vide, auquel cas la famille courante est conservée.

  • parametre2 : Style de la police. Les valeurs possibles sont (indépendamment de la casse). Chaîne vide : normal
    • B : gras
    • I : italique
    • U : souligné
    • Combinaison quelconque comme par exemple "BI" pour gars, italique. La valeur par défaut est le style normal. Les styles gras et italique ne s'appliquent pas aux familles Symbol et ZapfDingbats
  • parametre3 : Taille de la police en points. La valeur par défaut est la taille courante. Si aucune taille n'a encore été spécifiée depuis le début du document, la valeur prise est 12.

Exemple : $PDF->SetFont("Arial",'B',15); pour une police de type Arial en gras et de 15

Ecriture d'un texte

Il existe plusieurs méthodes pour écrire du texte :

  • La méthode Write(Hauteur de la ligne,Chaîne à imprimer,link) : imprime du texte à partir de la position courante. Lorsque la marge droite est atteinte (ou que le caractère \n est rencontré), un saut de ligne est effectué et le texte continue à partir de la marge gauche. Au retour de la méthode, la position courante est située juste à la fin du texte.
  • La méthode Text(Abscisse de l'origine,Ordonnée de l'origine,Chaîne à imprime) imprime une chaîne de caractères. L'origine est à gauche du premier caractère, sur la ligne de base. Cette méthode permet de positionner précisément une chaîne dans la page.
  • La méthode Cell()

Style du document

Insérer une image

Saut de page

Entête est bas de page

Numérotation des pages

Fond de page

Construction de tableaux

Exemple

Le but est de présenter sous forme d'un fichier PDF le résultat d'un DIR (listage de répertoires, sous-répertoires et fichiers) de la partie PHP de monwebfacile. Le fichier est automatiquement créé lorsque l'on clique sur la commande getDIR.


Télécharger un fichier (download)

Il peut être utile d'avoir un bouton sur son site pour pouvoir télécharger un fichier particulier. Ce bouton peut prendre la forme d'une boite de sélection, d'un lien hypertexte ou autre.

Principe

Principe téléchargement

Remarques sur le PHP

Le plus important est d’ajouter les bonnes en-têtes au document pour que le navigateur interprète correctement les données reçues.

  • "Content-Disposition" pour forcer le dialogue de sauvegarde (dialogue qui s'ouvre lorsque vous demandez le téléchargement et vous propose d'ouvrir ou de sauvegarder le fichier) et fournir une information (en principe un nom de fichier par défaut), à afficher dans le dialogue de sauvegarde.

    Attention le nom du fichier :

    • ne doit pas contenir de carctères spéciaux: < > \ " / : | ? * espace.
    • ne doit pas être référencé avec un chemin d'accés (uniquement le nom et son extension).
    • doit théoriquement être entre double quotes, mais la plus part des navigateurs acceptent sans double quotes.
  • "Content-Transfer-Encoding" pour faciliter le transport d'informations via different protocoles (exp RFC 821 restreint les messages mail à 7-bit US-ASCII). Il définit un ensemble de méthodes pour représenter des données binaires sous forme de texte ASCII. L'en-tête MIME « Content-Transfer-Encoding » indique la méthode utilisée.
  • "Content-Type" indique le type de média internet (type MIME) du contenu du message, consistant en un type et un sous-type ( exp : « Content-Type: text/plain »).
  • "Content-Length" indique la longueur du fichier au dialogue de sauvegarde.
  • "Pragma: no-cache", "Cache-Control: must-revalidate, public", "Expires: 0" pour ne pas mettre en cache le fichier transféré lors de la réception.
    • "Pragma: no-cache" : permet au navigateur d'indiquer au cache de récupérer le document auprès du serveur d'origine plutôt que de lui renvoyer celui qu'il conserve.
    • "Cache-Control: must-revalidate, public" : must-revalidate force le cache à se reconnecter au serveur avec un If-Modified-Since (y at'il eu une modification depuis ..).
      Cache-control comporte souvent les mentions post-check=0, pre-check=0 : il faut savoir que si ces deux directives sont initialisées à 0 elles sont totalement ignorées, il n'est donc pas nécessaire de les faire apparaître.
      public => la réponse peut être mise en cache par n'importe quel cache. Private => la réponse est destinée à un client unique et ne doit pas être mis en cache par un cache partagé. Un serveur proxy ne doit pas mettre en cache la réponse bien qu'un client puisse le faire.
    • "Expires: 0" : cette directive indique aux caches pour combien de temps la donnée associée reste fraîche. Après échéance, les caches vérifieront toujours auprès du serveur original si le document a changé.
  • readfile() lit le fichier et l'envoie dans le buffer de sortie.

Envoyer un fichier (upload)

But


Le but est de sélectionner à partir d'un formulaire, un ou des fichiers du disque dur pour les transférer vers un serveur distant. Les contrôles de taille (< 500000k), type (jpeg uniquement), dimension (hauteur > 100px) ainsi que le préview sont basés sur l'API File de HTML5. Ces contrôles sont utilisés à titre didactique pour montrer comment exploiter ces informations. Le bouton effacer permet d'effacer localement la sélection du fichier.

Avertissement

Les serveurs PHP Apache limitent la dimension des fichiers en upload et download à 2 Mo.

On peut vérifier cela par un phpinfo().

Deux solutions si vous n'êtes pas propriétaire du serveur (mais ça ne marche pas à tous les coups !!):

  • Par exemple pour augmenter ces tailles à 10 Mo => rajouter dans le fichier htaccess :
    • SetEnv upload_max_filesize 10M
    • SetEnv post_max_size 10M
  • Si votre hébergeur a activé le mode suPHPV (Note1), allez dans le dossier où est localisé le script, créez un fichier que l'on nommera php.ini, avec pour contenu :
    • upload_max_filesize = 10M
    • post_max_size = 10M

Note1 : suPHP est un outil pour exécuter des scripts PHP mais en utilisant des permissions paramétrées par l'utilisateur (on se substitue aux permissions du serveur). Cela consiste en un module Apache (mod_suphp) et une "setuid root binary" (suphp voir Note2) qui est appelée par Apache pour changer l'uid ( identifiants du ou des propriétaires) du process qu'exécute l'interpréteur PHP.

Note2 : suphp vient d'UNIX et concerne les droits d'accés permettant à des utilisateurs de dérouler un exécutable avec leurs propres droits.

Mécanismes utilisés

Cet exercice va nous permettre d'aborder plusieurs sujets dont certains que nous avons déjà vus dans des fiches précédentes :

  • L'attribut multipart/form-data du formulaire pour spécifier que l'on enverra des données binaires (fichier) et du texte (champs de formulaire). Indispensable dans les cas de tranfert de fichiers.
  • L'utilisation de la balise <input> dans un environnement multifichiers :
    • l'attribut multiple pour autoriser la sélection de plusieurs fichiers : multiple="multiple"
    • l'attribut name sous forme de tableau pour identifier une sélection de plusieurs fichiers : name="n_files[ ]"
    • L'attribut HTML accept qui permet de spécifier des types MIME pour l'envoi d'un fichier. Exemple accept="text/html,text/plain"

      Dans l'exemple ci-contre accept="image/jpeg" permet lors de la recherche des fichiers de pouvoir sélectionner uniquement les fichiers de type jpeg. On remarquera toutefois que la sélection de tous les fichiers existe aussi dans le choix (*.*) donc rien n'empêche de sélectionner un autre type de fichier (gif par exemple) et de tenter de le télécharger. C'est la raison pour laquelle il faut faire le test dans le code avant l'envoi.

    Exemple
    <input type="file" id="files" name="n_files[ ]" accept="image/jpeg,image/gif,image/png" multiple="multiple" />
  • La personnalisation de la balise <input>
  • la mise en oeuvre de l'API FileReader pour prévisualiser les fichiers avant de les transférer. Le principe de cette API a été décrit dans la fiche JVS_HTML5 rubrique "Lecture de fichiers locaux : API Files".
  • Une barre de progression lors du chargement des fichiers locaux. Exemple déjà vu ICI.

Principales méthodes

Deux méthodes générales sont à notre disposition pour transférer les données vers le serveur une fois que l'on a a validé le formulaire. Les deux actions utilisent la méthode POST (car cette requête n'a aucune restriction sur le nombre de données transmises), mais l'une nécessite en fin de traitement le rechargement de la page appelante (méthode post classique), alors que l'autre agit de manière totalement transparente sans avoir à recharger la page (méthode AJAX).

Les informations du formulaire sont reçues dans la page PHP sous forme de tableaux (superglobal) $_POST pour les champs textuels (text, checkbox, select, textarea, ...), et $_FILES pour les informations concernant les champs de type file. Les fichiers sont temporairement placés dans le dossier temporaire du serveur.

Upload : méthode POST classique

L'exemple consiste à utiliser un formulaire (method="post") pour transférer un fichier dans le serveur via un appel à une page PHP. Lorsque le processus est terminé la page PHP rappelle le formulaire avec des informations par la méthode GET (paramètres dans l'URL) sur le résultat (ok ou non) et le nom du fichier qui a été enregistré.

Remarques sur le code du formulaire

Remarques sur le code PHP

  • Les données de fichier transférées sont disponibles dans le tableau $_FILES[][] référencé par l'élément 'n_files' du formulaire :
    • $_FILES['n_files']['name']; donne le nom du fichier.
    • $_FILES['n_files']['type']; donne le type MIME du fichier.
    • $_FILES['n_files']['size']; donne la taille du fichier.
    • $_FILES['n_files']['tmp_name']; donne l'emplacement temporaire du fichier dans le serveur.
    • $_FILES['n_files']['error']; donne des informations si une erreur survient lors du transfert :
      • $_FILES['n_files']['error'] == UPLOAD_ERR_NO_FILE : pas de fichier disponible.
      • $_FILES['n_files']['error'] == UPLOAD_ERR_INI_SIZE : fichier dépassant la taille maximale autorisée par PHP.
      • $_FILES['n_files']['error'] == UPLOAD_ERR_PARTIAL : fichier transféré partiellement.
      • $_FILES['n_files']['error'] == UPLOAD_ERR_NO_TMP_DIR : le dossier temporaire est manquant.
      • $_FILES['n_files']['error'] == UPLOAD_ERR_CANT_WRITE : échec de l'écriture du fichier sur le disque du serveur.
      • $_FILES['n_files']['error'] == UPLOAD_ERR_EXTENSION : une extension PHP a arrêté l'envoi de fichier.
  • file_exists() et mkdir() créent le répertoire de sauvegarde définitif.
  • move_uploaded_file() transfère le fichier du répertoire temporaire vers le répertoire définitif.
  • header ("Location:".$adrRetour."?imgErr=false&nomFile=".$uploadNameFile); retourne à la page appelante avec comme informations supplémentaires imgErr false ou true suivant le résultat du tranfert et nomFile comme nom du fichier stocké sur le serveur.

Exemple de traitement pour un seul fichier avec préview

Exemple général avec possibilités d'upload de fichiers multiples

Upload : méthode AJAX

Par souci de clarté la base du code utilisé est celui de l'exemple général avec possibilités d'upload de fichiers multiples détaillé ci-dessus et qui a été fortement allégé de toutes fioritures (barre de progression lors du chargement local et possibilité de consulter les fichiers distants). De même pour la partie PHP : supression de l'analyse détaillée des erreurs, des caractéristiques des fichiers récupérés ainsi que la partie retour des résultats.

Modifications de la partie formulaire

Le formulaire lui même

onsubmit et action n'ont plus à être renseignés car la connexion se fait au travers de la reqête AJAX

Utilisation de FormData.append ()

FormData.append () est la méthode utilisée pour manipuler des fichiers, blobs ou des chaines de caractères. Il permet de présenter les données sous forme d'objet exploité par le formulaire pour le transfert d'informations vers le serveur.

En fonction des objets à manipuler les syntaxes suivantes sont à appliquer :

  • formData.append(name, file, filename); pour des fichiers.
  • formData.append(name, blob, filename); pour des blobs : type de donnée permettant le stockage de données binaires (le plus souvent des fichiers de type image, son ou video) dans le champ d'une table d'une base de données.
  • formData.append(name, value); pour des chaines.

Le premier paramètre (name) spécifie le nom de l'entrée de données (files[] dans notre formulaire).
Le deuxième paramètre spécifie s'il s'agit d'un type fichier (f = files[i] dans notre formulaire), blob, ou chaine qui sera utilisée comme valeur pour l'entrée de données.
Dans le cas de type fichier ou blob on peut spécifier un nom de fichier comme paramètre optionnel.

Exemples :

  • formData.append("nom", "Groucho");
    formData.append("numTelephone", 0123456789);
  • var content = '<a id="a"><b id="b">hello!</b></a>'; // Le corps d'un fichier html.
    var blob = new Blob([content], { type: "text/xml"});

    formData.append("webmasterfile", blob);

Note: The fields "webmasterfile" contient un fichier. Le nombre relatif au champ "numTelephone" assigned to the field "accountnum" est immédiatement converti en chaine de caractères "0123456789" par la méthode FormData.append(). Le champ valeur peut être un Blob, un Fichier, ou une chaine: Si la valeur est ni un Blob ou un Fchier, la value est immédiatement convertie en chaine de caractères.

Ce qui se traduit dans notre cas :

  • Initialisation d'une variable globale

  • Insertion de formData.append dans la boucle d'analyse des fichiers

Requête AJAX
Variables globales
Envoi des données

Remarque event.preventDefault() : Un événement est un changement d'état de l'environnement qui peut être intercepté par le code JavaScript. Dans certains cas, l'action implicite (par défaut) correspondante est alors annulable : il est par exemple possible d'empêcher que l'activation d'un lien entraîne la navigation vers l'URL associée. Pour les types d'événements qui l'autorisent, il est possible grâce à cette méthode d'annuler l'action implicite correspondante. Par exemple, l'action implicite associée à un événement de type submit est l'envoi au serveur du formulaire concerné.

Supervision de la réponse

Modification de la partie PHP

Pas de changement fondamental, si ce n'est l'allègement du code. La requête renvoie

  • 'nonOK' si une erreur est survenue : if($erreurUpload) echo 'nonOK';
  • 'OK' si la requête s'est déroulée sans problèmes : if($erreurUpload) echo 'OK';

Exemple complet

Cas d'un serveur FTP

Attention : Les serveurs du FAI Free (ainsi que d'autres d'ailleurs) n'acceptent pas la fonction ftp_connect(). Ce qui suit est alors purement indicatif et on ne pourra pas faire d'exemples pratiques.

Le serveur FTP

Echanges

  • Le mode classique
    « FTP » signifie File Transfer Protocol (protocole de transfert de fichiers) et sert à faire transiter des fichiers entre un serveur et un client. C'est un protocole (parmi tant d'autres) très utilisé qui est, en général, associé au port 21.
  • Le mode sécurisé
    La connexion est réalisée en mode SSL (Secure Socket Layer). SSL est un protocole de sécurisation des échanges, développé par Netscape. Il a été conçu pour assurer la sécurité des transactions sur Internet (notamment entre un client et un serveur) et il est intégré depuis 1994 dans les navigateurs.
    Lorsque l'on utilise une connexion SSL, on ne parle plus de FTP mais de FTPS : File Transfer Protocol over SSL

Les méthodes disponibles

ftp_connect() ou ftp_ssl_connect() : Ouverture d'une connexion (éventuellement sécurisée) FTP avec le serveur.
Définition

La fonction ftp_connect() retourne une ressource FTP qui va servir au maniement des fichiers en cas de succès, ou FALSE si une erreur survient.

Syntaxe

$ftp_stream = ftp_connect("host", port , timeout); ou $ftp_stream = ftp_ssl_connect("host", "port" , timeout);

Paramètres Description
host Chaine de caractères comme adresse du serveur FTP. Ce paramètre ne doit jamais avoir de slash final et ne doit pas être préfixé par ftp://.
port Spécifie un numéro de port alternatif pour la connexion. S'il est omis ou définie à zéro, alors le port par défaut utilisé sera 21.
timeout Spécifie le délai de connexion pour toutes les opérations de sous séquences du réseau. S'il est omis, la valeur par défaut sera 90 secondes. Le délai de connexion peut être modifié et interrogé à n'importe quel moment avec les fonctions ftp_set_option() et ftp_get_option().
Exemple

$ftp_stream = ftp_connect("ftpperso.free.fr", 21,90) or exit('Erreur : connexion au serveur impossible.');

$ftp_stream = ftp_ssl_connect("ftpperso.free.fr", 21,90) or exit('Erreur : connexion sécurisée au serveur impossible.');

ftp_login() : Identification aprés l'ouverture de la connexion FTP.
Définition

Il faut obligatoirement être identifié pour pouvoir interagir avec le serveur FTP. La fonction retourne TRUE en cas de succès ou FALSE si une erreur survient. Si l'identification échoue, PHP lancera une alerte.

Syntaxe

ftp_login($ftp_stream,$username,$password);

Paramètres Description
$ftp_stream Identifiant de la connexion FTP renvoyé par la fonction ftp_connect().
$username Nom de l'utilisateur de la connection FTP.
$password Mot de passepour accéder à la connection FTP.
Exemple

$login_result = ftp_login($ftp_stream,"monNom","monMDP") or exit('Erreur : Identification impossible.');

ftp_close() : Fermeture de la connexion FTP.
Définition

Ferme la connexion ftp_stream et libère les ressources. La fonction retourne TRUE en cas de succès ou FALSE si une erreur survient. Si l'identification échoue, PHP lancera une alerte.

Syntaxe

ftp_close($ftp_stream);

Exemple

$close_result = ftp_close($ftp_stream) or exit('Erreur : Fermeture de la connexion impossible.');

ftp_nlist() : Lister les fichiers sur le serveur.
Définition

Retourne un tableau avec le nom de tous les fichiers.

Syntaxe

$ftp_FilesList = ftp_nlist(ftp_stream,"repertoire");

Paramètres Description
$ftp_stream Identifiant de la connexion FTP renvoyé par la fonction ftp_connect().
repertoire Le dossier à lister. Ce paramètre peut également inclure des arguments, e.g. ftp_nlist($conn_id, "-la /your/dir"); Notez que ce paramètre n'est pas échappé, il peut donc y avoir des comportements non-désirés si le nom des fichiers contient des espaces ou d'autres caractères. Si "repertoire" = "." signifie que l'on travaille sur le dossier actuel.
Exemple
ftp_put() : Envoyer un fichier vers le serveur.
Définition

Enregistre un fichier local sur le serveur FTP et écrase le fichier existant. Retourne TRUE ou FALSE suivant que la fonction aboutit ou est en erreur. 550 : fichier ou répertoire inexistant ou accés non autorisé

Syntaxe

$put_result = ftp_put(ftp_stream,fichier distant,fichier local,mode,startpos);

Paramètres Description
ftp_stream Identifiant de la connexion FTP.
fichier distant Requis. Specifie l'adresse du fichier distant.
fichier local Requis. Specifie le path du fichier à uploader.
mode Requis. Specifie le mode de transfert. Valeurs possibles :
  • ASCII : L'intérêt du mode ASCII et d'éviter les problèmes de compatibilités dues aux différences de gestion des fin de ligne (EOL) selon les systèmes d'exploitation. En général cela ne pose pas de problème, mais c'est plus propre de respecter les conventions du système hôte. En mode ASCII, le client FTP va modifier le format des retours chariot en fonction du système d'exploitation du client et du serveur. Sur Windows, les retours chariot seront composé de 2 caractères : retour chariot et nouvelle ligne : \r\n
  • BINARY : Le mode binary est le plus simple à comprendre. Il transfère le fichier sur le serveur sans le modifier, ainsi les fichiers uploadé ou downloadé en mode Binary sont identiques à l'octet près entre le client et le serveur.
  • AUTO, le client FTP va automatiquement choisir le mode Binary ou le mode ASCII en fonction de l'extension du fichier. Les fichiers qui contiennent du texte (comme les fichiers .txt, .php, .css, .js, .sql...) seront transféré en mode ASCII, tandis que les autres fichiers (images .jpg, .png, vidéos .mp4...) seront transférés en mode Binary.
startpos Optionnel. Specifie la position dans le fichier distant pour démarrer l'upload.
Exemple

$put_result = ftp_put(ftp_stream,"fichier destinataire","mon fichier","AUTO") or exit('Erreur : Transmission du fichier impossible.');

ftp_get() : Recevoir un fichier du serveur.
Définition

Télécharger un fichier du serveur FTP. Retourne TRUE ou FALSE suivant que la fonction aboutit ou est en erreur. 550 : fichier ou répertoire inexistant ou accés non autorisé

Syntaxe

$get_result = ftp_get(ftp_stream,"dossier où envoyer","fichier à télécharger",mode);

Paramètres Description
ftp_stream Identifiant de la connexion FTP.
fichier distant Requis. Specifie l'adresse du fichier distant.
fichier local Requis. Specifie le path du fichier à uploader.
mode Requis. Specifie le mode de transfert. Valeurs possibles : FTP_ASCII ou FTP_BINARY.
Exemple

$get_result = ftp_get(ftp_stream,"mon répertoire destinataire","mon fichier sur le serveur","AUTO") or exit('Erreur : Réception du fichier impossible.');

ftp_pasv Active ou désactive le mode passif
Définition

Si la connexion au serveur FTP passe par un Firewall ou un NAT (chez le client, ou au niveau du client). Dans ce cas, il faut activer le mode passif, pour éviter des problèmes lors des manipulations avec le serveur FTP (par exemple, pour la fonction ftp_nlist).

Syntaxe

$pasv_result = ftp_pasv ( $ftp_stream , $pasv )

Paramètres Description
$ftp_stream Identifiant du lien de connexion FTP.
$pasv TRUE : mode passif activé, False : mode passif désactivé.
  • En mode actif, c'est le client FTP qui va déterminer le port à utiliser et le serveur FTP qui initialisera la connexion.
  • En mode passif, c'est le serveur FTP qui va déterminer le port à utiliser et le client FTP qui initialisera la connexion. Ce mode est le mode recommandé.

Cette fonction retourne TRUE en cas de succès ou FALSE si une erreur survient.

On dispose d'autres fonctionnalités interressantes en particulier :

Codage base 64

C'est quoi?

Le codage base 64 est un codage permettant de transformer toute donnée binaire en une donnée n’utilisant que les 64 caractères ASCII disponibles sur la plupart des systèmes informatiques, et acceptés par les protocoles de transmission de messages (courrier électronique), ou encore pour les photos des formats VCF (contacts).

Tout fichier texte ou image peut être transformé en une combinaison des caractères suivants : les 26 caractères A-Z, les 26 caractères a-z, les 10 caractères 0-9 et les caractères + et / soit 26+26+10+2 = 64 d'ou le nom de codage base 64.

Mécanisme d'encodage

Quelques rappels

  • Le bit : c'est l'unité la plus simple dans un système de numération, ne pouvant prendre que deux valeurs, désignées le plus souvent par les chiffres 0 et 1.
  • L'octet ou byte: c'est le regroupement de 8 bits pour coder une information. Le bit de poids faible est celui situé le plus à droite. Ce système binaire permet de représenter des valeurs entre 0 et 255.
    • 00000000 est un octet de valeur 0 (tous les bits sont à 0).
    • 00000001 est un octet de valeur 1 (le bit de poids faible est à 1).
    • 00100000 est un octet de valeur 32.
    • 10000000 est un octet de valeur 128.
    • 10100010 est un octet de valeur 162 (bit de pois 128 + bit de poids 32 + bit de poids 2).
  • Quelques déclinaisons de l'octet :
    • 1 kilo-octet (ko) = 1 024 octets,
    • 1 mégaoctet (Mo) = 1 024 ko = 1 048 576 octets,
    • 1 gigaoctet (Go) = 1 024 Mo = 1,073 milliard d'octets ...
  • Le Word :
    est un ensemble de 16 bits (2 octets). On trouve aussi le double word (4 octets) etc ..
  • La notation hexadécimale (base 16)
    On a souvent recours à la base 16 ou notation hexadécimale pour éviter d'avoir des représentations de nombre binaires à rallonge. La base 16 utilise 16 chiffres mais comme notre numération ne sait en représenter que 10 (0-9), on utilise les lettres de A à F pour aller de 10 à 16. On coupe l'octet, le word ou le double word en tranche de 4 bits (16 valeurs) que l'on va représenter en valeur hexadécimale :
    • l'octet 00100000 fractionné en 4 bits va donner 2 groupes : 0010 et 0000. Chaque groupe codé en héxadécimal va donner pour valeur : 20.
    • l'octet 10100010 fractionné en 4 bits va donner 2 groupes : 1010 et 0010. Chaque groupe codé en héxadécimal va donner pour valeur : A2 (A pour la valeur 10).
  • Le codage ASCII
    Chaque caractère (octet) possède son équivalent en code numérique sur 1 octet: c'est le code ASCII (American Standard Code for Information Interchange).

Table des codes ASCII étendu

Comment lire cette table

Remarque : Un click sur un caractère donne les valeurs décimales et hexadécimales du caractère sélectionné.

Encodage 64bits

Le principe du codage 64bits consiste à découper les données binaires du fichier en tranches de six bits. 6 bits soit 64 combinaisons qui correspondent à l'index dans le jeu de caractères par Base64 (table d'encodage : A-Z, a-z, 0-9, + et/ ).

Pour obtenir les index dans le jeu de caractères les octets du fichier sont fractionnées dans des buffers de 24 bits (3 octets à la fois). Le résultat du buffer est lui même fractionné en 4 paquets de 6 bits chacun, soit 4 index.

Table d'encodage
SextetdécimalCode SextetdécimalCode SextetdécimalCode SextetdécimalCode
0000000A 0000011B 0000102C 0000113D
0001004E 0001015F 0001106G 0001117H
0010008I 0010019J 00101010K 00101111L
00110012M 00110113N 00111014O 00111115P
01000016Q 01000117R 01001018S 01001119T
01010020U 01010121V 01011022W 01011123X
01100024Y 01100125Z 01101026a 01101127b
01110028c 01110129d 01111030e 01111131f
10000032g 10000133h 10001034i 10001135j
10010036k 10010137l 10011038m 10011139n
10100040o 10100141p 10101042q 10101143r
10110044s 10110145t 10111046u 10111147v
11000048w 11000149x 11001050y 11001151z
110100520 110101531 110110542 110111553
111000564 111001575 111010586 111011597
111100608 111101619 11111062+ 11111163/
Mécanisme

Le principe d'un programme d'encodage consiste à lire dans le fichier source trois octets consécutifs (si il y en a bien encore trois à lire), et écrire dans le fichier de sortie les quatre codes correspondant, et ceci jusqu’à avoir parcouru complètement le fichier source.

Bien entendu si la taille (en octets) du fichier n’est pas un multiple de trois, à la fin du fichier le nombre d’octets réellement lus dans le fichier peut très bien n’être que 1 ou 2.

En effet le codage base 64 code des sextets. Que faire si la donnée à coder n’a pas une longueur multiple de 8 ? La longueur en bits d’un fichier est multiple de 8 mais pas nécessairement multiple de 6. Trois cas de figures peuvent se présenter :

  • Le fichier à coder a une longueur en bits multiple de 6 : la longueur est de 6k bits autrement dit k sextets à coder. Dans ce cas chacun des k sextets est codé, et le fichier codé contient les k codes correspondant à ces k sextets.
  • Le fichier à coder a une longueur égale à 6k+2 bits, autrement dit contient k sextets plus deux bits isolés. À ces deux derniers bits on vient alors ajouter quatre bits nuls pour former un dernier sextet qui est codé, et on ajoute à la suite de ce dernier code un double symbole = (qui ne fait pas partie de l’alphabet cible et qui indique donc que seuls les deux bits de poids forts du code précédent les deux = sont à prendre en compte pour le décodage).
  • Le fichier à coder a une longueur égale à 6k+4 bits, autrement dit contient k sextets plus quatre bits isolés. À ces quatre derniers bits on vient alors ajouter deux bits nuls pour former un dernier sextet qui est codé, et on ajoute à la suite de ce dernier code un simple symbole = (qui ne fait pas partie de l’alphabet cible et qui indique donc que seuls les quatre bits de poids forts du code précédent le = sont à prendre en compte pour le décodage).

Lire un fichier codé en 64bits

Syntaxe générale

"data:typeMime;base64,Contenu du fichier"

Pour des images

<img src="data:image/jpg;base64,/9j/4AAQSkZJRgABAQE.........." alt="aperçu d'une image encodée en base64" />

<img src="data:image/gif;base64,/9j/4AAQSkZJRgABAQE.........." alt="aperçu d'une image encodée en base64" />

<img src="data:image/png;base64,/9j/4AAQSkZJRgABAQE.........." alt="aperçu d'une image encodée en base64" />

Pour des fichiers texte

<script type="text/javascript" src="data:application/javascript;base64,/9j/4AAQSkZJRgABAQEAWg..." ></script>

<link rel="stylesheet" type="text/css" href="data:text/css;base64,/9j/4AAQSkZJRgABAQEAWgBaAAD.." />

Dans un environnement CSS

.maclasse { background-image: url('data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAWgBaAAD/4gxYSUNDX1BST0ZJ...'); }

Avantages et inconvéniens

  • Une image générée en base 64 ne peut pas être mise en cache par le navigateur,
  • Les images doivent être de tailles raisonnables au risque d'alourdir le chargement et la navigation. A titre d'exemple un fichier encodé devient plus lourd d'environ 33%,
  • L'encodage de fichier css ou javascript donne des fichiers carrément illisibles.
  • Ce codage est trés pratique lorsque l'on veut créer des fichiers de types cartes de visite (vcf) et que l'on désire y inclure une petite photo.

Exemple

L'exemple suivant va nous montrer un fichier image gif (qui peut être aussi un gif animé) dans sont format classique et dans son format codage 64bit.

FichiersContenu partiel hexadécimalAprés encodage 64bits
Fichier de départ
(type image)
/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQj
hCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAAmACEDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAt
RAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXq
DhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8Q
AtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eH
l6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDskyBxUgLetQz3EFpB5txKsaDu1V
bHW7K8lKIWT+6XXAb6UropQb1sWL6/jsLZp5yQi8cDJOa5PUvE91coUt18mM++WIrZ8XnbpOPV1rkba0mvGCQoSMgFjwBUSbvY6qNOPLzM6Pzn/vt+dFWfsD/3o/zooFaJja5YXZuDN5z3Ke
jdVHsOlZUSzTMIoQ5b0B6fWvQpLRZV6c1DDpSI5O0DJyaHEcKySsYDwTW+mRDUZzcRtKoEZPCde/f+VbGkGyuMpAyh04MeMFaqeL4hFpsYUceYM+3BrlIpHWeORHZXDDDKeaV7MqMeeF0ene
UPQUVW+0H+8fzoq7nP7OXcnjPFTLRRVGJU1CATwlWwQRjBrkb3REWXfA4TDAlT0ooqJHRTbR1PmD+6KKKKBXZ//9k=
											

Générateur d'encodage 64bits pour les images

Générateur

Remarques sur le code

Lecture des tags de fichiers images

Méta données

Les métadonnées servent à décrire ou à définir toutes sortes de données comme des fichiers image, texte, son ou vidéo mais aussi des photos. Dans ce chapître on se limitera aux fichiers de type image, mais le principe général pourra être appliqué à d'autres fichiers comme par exemples les fichiers son que nous verrons dans le chapître suivant.

Méta données EXIF

EXIF pour exchangeable image file format, concerne les informations relatives à la caméra qui a pris la photo ainsi que les différents réglages associés (des iformations fixes comme par exemple le modèle de caméra utilisée, et aussi des informations dynamiques relatives aux prises de vues comme par exemple l'orientation, l'ouverture, la vitesse etc ...). Ces informations sont stockées dans l'image lors de la prise de vue.

Ce format de métadonnées n’est pas standardisé, il est toutefois utilisé par de nombreux constructeurs d’appareils photographiques numériques.

Noms des champs Commentaires
FileNameNom du fichier
FileNameNom du fichier
FileDateTimeDate fichier
FileSizeTaille
FileTypeType
MimeTypeType mime
SectionsFoundSections
ImageDescriptionDescription de l'image
MakeFabricant
ModelModèle
OrientationOrientation
XResolutionRésolution en X
YResolutionRésolution en Y
ResolutionUnitUnité pour la résolution
SoftwareLogiciel
DateTimeDate de modification
ArtistArtiste
YCbCrPositioningPositionnement YCbCr
CopyrightDroit de copie (Copyright)
ExposureTimeTemps d'exposition (s)
FNumberNombre-F
ExposureProgramProgramme d'exposition
ExifVersionVersion EXIF
DateTimeOriginalDate et Heure d'origine
DateTimeDigitizedDate et heure numérisée
ComponentsConfigurationConfiguration des composantes
CompressedBitsPerPixelBits par pixel compressé
ExposureBiasValueValeur compensation Exposition
MaxApertureValueOuverture maxi.
MeteringModeMode calcul exposition
LightSourceSource lumière
FlashFlash
FocalLengthLongueur de focale (mm)
UserCommentEncodage commentaires
SubSecTimeHeure fractions de sec.
SubSecTimeOriginalHeure d'origine fractions sec.
SubSecTimeDigitizedHeure numérisée fractions sec.
FlashPixVersionVersion FlashPIx
ColorSpaceMode de couleur(BPP)
ExifImageWidthLargeur de l'image
ExifImageLengthHauteur de l'image
InteroperabilityOffsetPosition interopérabilité
SensingMethodMéthode capteur
FileSourceSource du fichier
SceneTypeType de scène
CustomRenderedRendu personnalisé
ExposureModeMode exposition
WhiteBalanceEquilibrage des blancs
DigitalZoomRatioGros plan numérique
FocalLengthIn35mmFilmLongueur de focale (35mm)
SceneCaptureTypeType de capture de scène
GainControlContrôle des gains
ContrastContraste
SaturationSaturation
SharpnessNetteté
SubjectDistanceRangePlage de distance du sujet
JPEGInterchangeFormatLengthTaille de la vignette
JPEGInterchangeFormatDécalage de la vignette
InterOperabilityIndexIndex IOP
InterOperabilityVersionVersion IOP

Les métadonnées IPTC

L'IPTC définit un standard pour stocker des informations relatives à une image. Ces informations peuvent être le nom de l'image, le titre de l'image, des mots-clés associés à l'image, l'auteur de l'image, le copyright... Elles permettent de décrire l'image. Les données IPTC font partie du fichier. Elles sont dans l'image et de ce fait on peut manipuler l'image sans perdre ces informations.

Attention : Les métadonnées IPTC n'existent que dans les images aux formats jpg, jpeg et tiff. Le métadonnées ne sont pas pour autant exclusives à ces formats. Les images au format png par exemple possèdent d'autres types de métadonnées.

Les métadonnées IPTC sont constituées d'un certain nombre de sous métadonnées stockées dans le fichier lui-même.

Ref sous métadonnées Noms des champs Commentaires
000version enregistrement
005Object NameNom de l'objet.
007Edit StatusStatut éditorial.
010UrgencyPriorité - 0 à 8 -.
015CategoryCatégorie.
020Supplemental CategoryCategories supplémentaires.
022Fixture IdentifierIdentifiant.
025KeywordsMots clé.
026Locationlocalisation.
030Release DateDate sortie/disponibilité.
035Release TimeHeure sortie/disponibilité.
040Special InstructionsInstruction spéciale.
045Reference serviceService de référence (associé avec les champs 47 et 50).
047Reference DateDate de référence.
050Reference NumberNuméro de référence.
055Date CreatedDate création.
060Time CreatedHeure de création.
065Originating ProgramProgramme d'origine.
070Program versionVersion du programme.
075Object cycleCycle de l'objet - a = matin, b = après midi, c = soir -.
080By-lineCréateur.
085By-line TitleTitre du créateur.
090CityVille.
092Région.
095Province/StateProvince/état.
101Country/Primary Location NamePays.
103Original Transmission ReferenceRéférence de la transmission (otr).
105HeadlineEntête/titre.
110CreditSource/fournisseur de l'objet.
115SourceSource photo (propriété intellectuelle).
116Copyright NoticeCopyright.
118ContactContact.
120Caption/AbstractLégende/résumé.
122Writer/EditorAuteur.
130Image TypeType de l'image.

Décodage des tag Images jpeg

Les informations contenues dans l'image sont récupérées avec la fonction GetImageSize qui peut retourner plus d'informations dans le paramètre optionnel sous forme de tableau associatif (getimagesize(fichier,paramètre optionnel)). Dans cette variable seront stockés entre autres les champs IPTC non vides, en fait particulièrement le marker APP13 défini par Adobe Photoshop et l'IPTC pour un fichier JPEG, mais aussi d'autres markers que nous n'aborderons pas dans ce propos.

PHP met à notre disposition plusieurs méthodes pour lire les tags

Les tags IPTC du marqueur APP13

La méthode iptcparse()

Les tag EXIF

La méthode exif_read_data()

Lit les en-têtes EXIF des images JPEG et TIFF. Avec cette fonction, on peut lire les données méta générées par les appareils photos numériques.

Décodage des tag Images png

Les fichiers PNG ont dans leurs spécifications la possibilité d'intégrer une zone de commentaires chunk compressée et donc illible sans programme adapté.

Le format des fichiers PNG se compose d'une part d'une entête et d'autre part de multiples block de données communément appelés CHUNK.

Chaque chunk est composé de 4 parties :

  • Sa taille : un entier non signé de 4 octets, décrivant la taille du segment.
  • Son type : 4 caractères (4 octets) composés de caractères ASCII alphanumériques (A-Z, a-z, 65 à 90 et 97 à 122) permettant de qualifier la nature du chunk.
  • Les données elle mêmes.
  • Un CRC (cyclic redundancy check) sur 4 octets pour vérifier l'intégrité du chunk.
  • Les chunks peuvent être présents dans n'importe quel ordre, toutefois le premier doit être le chunk IHDR et le dernier le chunk IEND.

    L'entête

    8 caractères héxa : \x89PNG\x0d\x0a\x1a\x0a

    Les principaux Chunk

    Chunks Contenu Commentaires
    IHDR
    • Largeur (4 bytes)
    • Hauteur ( 4 bytes)
    • Nombre de bits par échantillon ( 1 byte)
    • Type de couleur (1 byte) => 1 (palette), 2 (color), 4 (alpha channel)
    • Méthode de compression (1 byte)
    • Méthode filtrage (1 byte)
    • Méthode interface (1 byte)
    Entêtes de l'image.
    PLTE
    • Rouge: 1 byte (0 = noir, 255 = rouge)
    • Vert: 1 byte (0 = noir, 255 = vert)
    • Bleu: 1 byte (0 = noir, 255 = bleu)
    Palette. Nécessaire si le type de couleur et égal à 3 (indexed color). De 1 à 256 entrées palette avec 3 informations (3 byte) par palette.
    cHRM
    • White Point x: 4 bytes
    • White Point y: 4 bytes
    • Red x: 4 bytes
    • Red y: 4 bytes
    • Green x: 4 bytes
    • Green y: 4 bytes
    • Blue x: 4 bytes
    • Blue y: 4 bytes
    Chromaticités du rouge, vert, et bleu utilisés.
    tEXt

    Les chunks iTXt, tEXt, et zTXt sont utilisés comme informations textuelles associées à l'image.

    Chaque text chunk est structuré par un mot clé qui indique le type d'information concernée par le texte associé. Les mots clé suivants sont prédéfinis :

    Mots cléTextes
    TitleCourt texte pour le titre de l'image.
    AuthorAuteur.
    DescriptionDescription de l'image.
    CopyrightCopyright.
    Creation TimeDate de création
    SoftwareLogiciel utilisé pour créer l'image.
    DisclaimerAvertissement légal.
    WarningAvertissement lié à la nature du contenu.
    SourceAppareil utilisé pour la prise de vue.
    CommentCommentaire divers; Conversion de commentaire de GIF

    Structure :

    • Mot clé : 1-79 bytes (caractere)
    • Séparateur (Null) : 1 byte
    • Texte : n bytes (caractere)
    iTXt

    Les chunks iTXt, tEXt, et zTXt sont utilisés comme informations textuelles associées à l'image.

    Chaque text chunk est structuré par un mot clé qui indique le type d'information concernée par le texte associé. Les mots clé suivants sont prédéfinis :

    Ce chunk is sémantiquement équivalent à equivalent aux chunks tEXt et zTXt, mais au format d'encodage UTF-8. Sa structure est définie de la façon suivante :

    • Mot clé : 1-79 bytes (caractere)
    • Séparateur (Null) : 1 byte
    • Compression flag : 1 byte
    • Méthode de compression : 1 byte
    • Language : 0 ou plusieurs bytes (caractere)
    • Séparateur (Null) : 1 byte
    • Translated keyword: 0 ou plusieurs bytes
    • Séparateur (Null) : 1 byte
    • Text : 0 ou plusieurs bytes
    zTXt

    Les chunks iTXt, tEXt, et zTXt sont utilisés comme informations textuelles associées à l'image.

    Chaque text chunk est structuré par un mot clé qui indique le type d'information concernée par le texte associé. Les mots clé suivants sont prédéfinis :

    Ce schuk contient des données textuelles comme tEXt, cependant zTXt profite de la compression. zTXt est recommandé pour stocker de grands blocs de texte. Sa structure est définie de la façon suivante :

    • Mot clé : 1-79 bytes (caractere)
    • Séparateur (Null) : 1 byte
    • Méthode de compression : 1 byte. 0=> Décompressable par gzuncompress()
    • Texte compressé : n bytes
    pHYs
    • Pixels par unité, X : 4 bytes
    • Pixels par unité, Y : 4 bytes
    • Spécification unité : 1 byte
      • 0 : non spécifié
      • 1 : le mètre
    Dimensions Physique des Pixels
    sRGB

    1 Byte d'information

    • 0: Perception
    • 1: Colorimétrie relative
    • 2: Saturation
    • 3: Colorimétrie absolue
    Représentativité de l’espace colorimétrique d’un écran
    IDAT Contient les données de l'image. Un fichier peut contenir plusieurs chunk IDAT. Si c'est le cas, ils doivent apparaître strictement consécutivement.
    IEND Dernière info. Marque la fin des données du fichier.

    Méthode utilisée pour le décodage

    Exemple de décodage de tag d'images jpeg et png


    Lecture des tags de fichiers audio (mp3 ou ogg)

    Généralités

    Cette rubrique vous explique comment lire les tag ID3 sans installation d'extensions PECL (PHP Extension Community Library) ou autres.
    ID3 est le nom des métadonnées pouvant être insérées dans un fichier audio comme MP3. Ces métadonnées permettent d'avoir des informations sur le contenu du fichier comme le titre, le nom de l'interprète, les commentaires, etc.

    Attention : des tag autres que ID3 sont parfois utilisés pour les fichiers MP3 comme le tag APEv1 utilisé avec le Monkey's Audio format. Dans les fichiers MP3, le tag APE se situe tout à fait en fin de fichier (aprés APETAG), bien séparé du corps du fichier.

    Monkey's Audio est à la fois un algorithme et un format de fichier pour des compressions audio sans perte. Monkey's Audio ne rejette pas de données durant la phase d'encodage, comme peuvent le faire des méthodes de compression comme AAC, MP3, Vorbis et Musepack.

    structure des tag ID3 pour fichiers de type mp3

    structure des tag APE pour fichiers de type mp3

    structure des tag ogg pour fichiers de type ogg

    Exemple complet et son code php

    Explications du code

    On va prendre pour exemple un fichier mp3 décodé par un éditeur hexadécimal et dont le début montre des informations concernant les tags id3 et on va détailler le programme PHP pour les lire. Tout d'abord on peut consulter le résultat suivant qui donne les libellés de tag avec leur explications.

    0. Chaque traitement de récupération des données est fait au niveau d'une classe spécifique : class ID3TagsReader pour les fichiers mp3 et class oggTagsReader pour les fichiers ogg. Le traitement d'affichage est réalisé par un tronc commun qui fait une boucle sur l'ensemble du répertoire et qui en fonction du type de fichier appelle la classe concernée. On détaillera plus précisément le contenu et le fonctionnement de la classe ID3TagsReader {}.

    1. Tout d'abord il faut ouvrir le fichier pour l'exploiter en lecture.

    2. On vérifie que l'on a bien affaire à des tag ID3 (3 premiers caractères du fichier).

    3. On vérifie la version des Tags (4 ème et 5 ème caractères du fichier) afin d'appliquer les syntaxes de tag correspondant à la version trouvée.
    Pour cela bin2hex() convertit des données binaires en représentation hexadécimale.
    et hexdec() convertit de hexadécimal en décimal. Soit 3.0 pour notre fichier.

    4. Pour chaque Tag ('TIT2', 'TALB', 'TPE1', 'TPE2', 'TRCK', ....), on va voir si ce dernier existe (strpos() != FALSE). S'il existe (toujours avec strpos()) on va déterminer sa position de début dans le fichier et la longueur de son contenu.

    • strpos ($fichier,$chaine à rechercher,$start) cherche la position de la première occurrence dans une chaîne. Si la chaine à rechercher n'est pas une chaîne, le champ est converti en entier, et utilisé comme caractère de code ASCII correspondant.
    • Si le paramètre optionnel $start est spécifié, la recherche commencera à partir de ce nombre de caractères compté depuis le début de la chaîne.
    • strpos() retourne FALSE si l'occurrence n'a pas été trouvée.

    La longueur est calculée sur les 3 caractères qui suivent le libellé du tag.

    5. On a le départ de la chaine et sa longeur, on va donc pouvoir récupérer les données avec substr().
    substr($chaine,$start,$longueur) retourne un segment de chaîne débutant à la position $start et d'une longueur de $longueur.

    $iPos+11 car onze octets (4 octets pour le tag et 7 octets pour la longueur de l'information) sépare la position du début du tag de celui du début de l'information.

    6. On rajoute une petite analyse de la chaine pour vérifier que les caractères sont valides, et un traitement spécial dans le cas du tag TCON qui peut renvoyer le numéro de genre en lieu et place du libellé : cette information est de la forme "(numéro genre)", on doit donc éliminer les parenthèses pour obtenir un indice exploitable.


    Application au projet de site web



Respectons la propriété intellectuelle