Connexion FTP, download et traitements en PHP
Dans cette partie, nous allons voir comment nous connecter en
FTP à un serveur en
Php dans le but de downloader des fichiers et les traiter. Il sera donc nécessaire de s'
authentifier par le code puis d'utiliser les fonctions qui permettent de
télécharger les fichiers voulus. Nous verrons aussi comment
décompresser certains fichiers, comment parcourir des fichiers
csv ligne à ligne en découpant l'information sur le séparateur de liste. Nous verrons enfin comment
parcourir des répertoires afin de le purger des informations obsolètes. Le contexte ici est celui d'une concession automobile pour laquelle nous devons récupérer chaque jour les véhicules d'occasion proposés à la vente. Les informations des véhicules sont listées dans un fichier
CSV. Leurs photos avec
URL sont listées dans un fichier texte compressé.
Connexion FTP
Pour vous connecter au serveur, le prestataire doit d'abord vous avoir fourni les informations de
connexion comme le
serveur FTP, le
login et le
mot de passe. Nous plaçons donc ces valeurs dans des variables.
$serveur_ftp="Adresse_du_serveur_FTP";
$login_ftp="Identifiant_de_connexion";
$mp_ftp="Mot_de_passe_de_connexion";
Il est de bon ton de tester ces informations de
connexion avec un
client FTP. En outre, cela vous permettra de connaître l'arborescence et les fichiers présents. Dans notre cas, les deux fichiers que nous souhaitons récupérer sont dans un sous dossier
/datas/ à la racine de la
connexion FTP. Ces deux fichiers se nomment
ct26c3.csv pour les informations de véhicules et
photos.txt.zip pour les informations de photos. Donc nous stockons ces valeurs en variables :
$csv_ftp="ct26c3.csv";
$photos_ftp="photos.txt.zip";
Nous pouvons maintenant nous connecter au
serveur FTP en nous
logant. Pour ce faire, nous utilisons premièrement la fonction
ftp_connect() qui requiert deux arguments : l'adresse du serveur et le port sur lequel se connecter, soit
ftp_connect(Nom_du_serveur,Numero_du_port). Puis nous utilisons la fonction
ftp_login() qui demande trois arguments : L'objet
PHP qui a servi a créé la
connexion FTP, l'identifiant et le mot de passe, soit
ftp_login(Objet_ftp,Login,Mp). Nous ajoutons donc les lignes de code suivantes :
$ftp = ftp_connect($serveur_ftp, 21);
ftp_login($ftp, $login_ftp, $mp_ftp);
Maintenant que la
connexion est établie, nous devons rappatrier les fichiers en les téléchargeant. C'est la fonction
ftp_get() qui se charge du
download. Elle requiert quatre arguments : L'objet
PHP de la
connexion FTP, le chemin de l'emplacement de destination pour le fichier téléchargé (que nous stockons ici dans une variable :
$chemin_extraction), le chemin sur le serveur du fichier à télécharger et enfin le
mode de transfert ici binaire. Nous ajoutons donc les lignes de code suivantes, pour les deux fichiers à downloader :
$chemin_extraction="./chemin_relatif_au_dossier_de_dev/";
ftp_get($ftp, ".".$chemin_extraction.$csv_ftp,"./datas/".$csv_ftp, FTP_BINARY);
ftp_get($ftp, ".".$chemin_extraction.$photos_ftp,"./datas/".$photos_ftp, FTP_BINARY);
Comme vous le remarquez, nous choisissons de conserver les mêmes noms que les fichiers sur le serveur pour les fichiers que nous téléchargeons en local. Les fichiers étant récupérés en local, nous avons besoin de décompresser le fichier des photos afin de pouvoir le lire par le code.
Décompression de fichiers en PHP
Pour réaliser la
décompression, nous avons tout d'abord besoin de désigner le nom du fichier à
décompresser et son emplacement. Le nom, nous le connaissons déjà, il est stocké dans la variable
$photos_ftp. Nous connaissons aussi son emplacement stocké dans la variable
$chemin_extraction. Donc, nous concaténons ces informations dans une seule variable qui représentera le
fichier zippé à
décompresser, en ajoutant la ligne de code suivante :
$fichier_zippeZ = ".".$chemin_extraction.$photos_ftp;
Nous n'oublions pas en préfixe le "." qui permet de désigner le dossier local où se situe la page de code par rapport à laquelle nous raisonnons en relatif. Pour accéder à l'
archive zippée, nous avons besoin de créer un
objet PHP $zip = new ZipArchive; qui pourra implémenter les
méthodes de la
classe PHP pour réaliser la
décompression. Ensuite, nous utiliserons la
méthode open() de l'objet afin d'accéder à l'archive :
$zip->open(Nom_du_fichier_zippe). Puis nous utiliserons sa
méthode extractTo() afin de
décompresser l'archive à l'emplacement désigné :
$zip->extractTo(Emplacement_extraction);. Enfin nous n'oublierons pas de fermer l'archive à laquelle nous avons accédé par la
méthode open() en utilisant cette fois la méthode
close() de l'
objet PHP. Avec un test préalable consistant à vérifier que le fichier à décompresser existe bien, nous ajoutons les lignes de code suivantes :
if(is_file($fichier_zippeZ))
{
$zip = new ZipArchive;
if ($zip->open($fichier_zippeZ))
{
/* getcwd(), chemin d'accès au dossier en cours */
$chemin_extraction = getcwd().$chemin_extraction;
$chemin_extraction =str_replace("\\","/",$chemin_extraction);
$zip->extractTo($chemin_extraction);
$zip->close();
}
}
Après décompression, nous pouvons visualiser le fichier texte dans un éditeur pour savoir comment l'attaquer.
Accès en lecture à un fichier texte
Chaque ligne fournit les informations d'une image. Chaque information, au nombre de trois par ligne, est séparée de la suivante par une tabultation (\t) dans le code. Nous allons donc accéder au fichier txt en lecture grâce à la fonction
fopen() qui requiert deux arguments : Le premier est l'emplacement du fichier texte à parcourir, le second correspond au mode d'ouverture (r pour lecteur :read). Nous stockons le retour de cette fonction dans une variable
$fichier_photos. Pour accéder au fichier texte décompressé, nous ajoutons donc la ligne de code suivante :
$fichier_photos=fopen($chemin_extraction.str_replace(".zip","",$photos_ftp),"r");
Le fichier compressé se nommait photos.txt.zip. Nous utilisons donc la
fonction PHP str_replace() afin de supprimer l'extension .zip et obtenir le nom du fichier ainsi
décompressé. Nous avons besoin de cinq variables pour récupérer les informations. Trois variables pour les trois parties de la photo.
$nom_photo_ftp pour récupérer l'information de la première colonne, soit le nom de la photo.
$chemin_photo_ftp pour récupérer l'information de la deuxième colonne, soit son chemin d'accès sur le
serveur FTP. Il faudra donc la télécharger par
ftp_get(), d'autant que nous n'avons toujours pas fermé la
connexion FTP. Et enfin
$hcode_photo pour récupérer l'information de la troisième colonne, soit le code de hashage de la photo. Ce code permet simplement, lorsqu'il change, de savoir si la photo a été modifiée, auquel cas elle doit être downloadée, dans le cas contraire l'opération est inutile. Ceci permet d'optimiser les opérations lorsqu'elles sont quotidiennes et volumineuses. Nous avons aussi besoin de deux variables pour repérer les positions des colonnes et découper la ligne récupérée en trois informations. Nous nommons ces variables
$position_deb_chemin et
$position_fin_chemin. Nous ajoutons donc le code suivant pour ces déclarations et initialisations de variables :
$nom_photo_ftp="";
$chemin_photo_ftp="";
$hcode_photo="";
$position_deb_chemin="";
$position_fin_chemin="";
Nous allons utiliser la
fonction PHP fgets() afin de récupérer le contenu du fichier texte. Cette fonction a besoin de deux paramètres. Le premier est le nom de la variable sous lequel nous avons stocké les informations de connexion au fichier
$fichier_photos. Le second est une valeur en octets correspondant au volume d'information que nous souhaitons extraire de la ligne. Une ligne entière peut contenir au maximum
4096 octets. Nous stockons les informations de la ligne ainsi retournée dans une variable que nous nommons
$memoire. Et nous parcourons tout le fichier texte, tant que la fin n'est pas atteinte grâce à une
boucle while. Nous initions donc le parcours du fichier txt ainsi :
while(($memoire = fgets($fichier_photos, 4096)) !== false)
{
/* Code de récupération du contenu à venir */
}
Pour le nom de la photo, soit l'information de première colonne, nous allons prélever la position du premier slash (/) à l'aide de la
fonction strpos(), soit le point de départ de l'information en deuxième colonne. Nous allons prélever l'information jusqu'à cette position grâce à la
fonction substr(). Une fois prélevée, l'information contiendra une tabulation à effacer, ce que nous allons faire grâce à la fonction
str_replace(). Entre les accolades de la
boucke while, nous ajoutons donc les lignes de code suivantes :
$position_deb_chemin=strpos($memoire, "/");
$nom_photo_ftp=substr($memoire,0,$position_deb_chemin);
$nom_photo_ftp=str_replace("","",str_replace("\t","",$nom_photo_ftp));
Pour extraire et mémoriser l'information de la deuxième colonne, soit le chemin sur le serveur de la photo, nous allons chercher la position de départ de la seconde tabulation en partant de la position précédente
$position_deb_chemin, toujours grâce à la
fonction strpos(). Puis de nouveau, nous allons exploiter la
fonction substr() pour extraire l'information entre ces deux positions, sur une longueur égale à la différence entre la position d'arrivée et celle de départ. A la suite du précédent code, toujours entre les accolades de la
boucle while, nous ajoutons les deux lignes de code suivantes :
$position_fin_chemin = strpos($memoire, "\t",$position_deb_chemin);
$chemin_photo_ftp=substr($memoire, $position_deb_chemin, $position_fin_chemin - $position_deb_chemin);
Enfin nous prélevons l'information de la troisième colonne, le hcode. Il suffit de désigner le point de départ, juste après la dernière tabulation (position+1), la
fonction substr() se chargera de déterminer le point d'arrivée avec la fin de la ligne. Nous ajoutons donc la ligne de code suivante, en dessous des précédentes :
$hcode_photo = substr($memoire,$position_fin_chemin+1);
Puis nous en profitons pour télécharger la photo grâce à l'information sur le nom de la photo et son chemin que nous venons de récupérer.
ftp_get($ftp, "./chemin_de_destination/".$nom_photo_ftp,".".$chemin_photo_ftp, FTP_BINARY);
Ce qui tout consolidé, donne :
while (($memoire = fgets($fichier_photos, 4096)) !== false)
{
$position_deb_chemin=strpos($memoire, "/");
$nom_photo_ftp=substr($memoire,0,$position_deb_chemin);
$nom_photo_ftp=str_replace("","",str_replace("\t","",$nom_photo_ftp));
$position_fin_chemin = strpos($memoire, "\t",$position_deb_chemin);
$chemin_photo_ftp=substr($memoire, $position_deb_chemin, $position_fin_chemin - $position_deb_chemin);
$hcode_photo = substr($memoire,$position_fin_chemin+1);
ftp_get($ftp, "./wp-content/uploads/sources/photos/ ".$nom_photo_ftp,". ".$chemin_photo_ftp, FTP_BINARY);
}
Maintenant que nous avons terminé la lecture de ce fichier texte, nous devons libérer la mémoire en le fermant grâce à la fonction
fclose() qui nécessite en paramètre, l'objet désignant le fichier texte chargé. Nous ajoutons donc la ligne de code suivante :
fclose($fichier_photos);
N'oublions pas de même de refermer l'
accès FTP car nous n'avons plus besoin de télécharger. Pour ce faire, nous utilisons la fonction
ftp_close() qui demande en paramètre, l'objet qui a servi à établir la
connexion FTP :
ftp_close($ftp);
Lecture d'un fichier CSV en PHP
Un fichier
CSV est un fichier texte avec des caractères spéciaux utilisés pour séparer les informations les unes des autres. Les informations sont donc agencées en colonne.
Dans l'exemple ci-dessus, le
point-virgule(
;) est utilisé comme
séparateur de liste. Nous allons ouvrir ce
fichier CSV en lecture, exactement de la même façon que pour le fichier texte grâce à la fonction
fopen(). Nous avons aussi besoin d'une variable que nous transformerons en tableau grâce à la
fonction explode() pour stocker les informations colonne que nous récupérons. Nous ajoutons donc les deux lignes de code suivantes :
$fichier=fopen($chemin_extraction.$csv_ftp,"r");
$une_voiture = "";
Nous débutons la boucle de lecture ligne à ligne, comme précédemment, en stockant en mémoire le maximum d'octets que peut comporter une ligne. Nous ajoutons donc la boucle suivante :
while(($memoire = fgets($fichier, 4096)) !== false)
{
}
Puis, grâce à la
fonction explode() qui demande deux paramètres, nous stockons chaque valeur de colonne, dans la variable tableau
$une_voiture. Ces deux paramètres sont le caractère qui est utilisé pour découper l'information. Ici il s'agit du séparateur de liste, soit le point-virgule. Le deuxième paramètre est l'information que l'on découpe, soit la ligne que nous venons de récupérer en lecture. Dans les accolades de la
boucle while, nous ajoutons donc la ligne de code suivante :
$une_voiture = explode(";",$memoire);
Pour que toutes les informations stockées dans ce tableau puissent être traitées avant le passage à la ligne suivante du fichier, nous utilisons une
boucle for. Cette dernière permettra de parcourir l'ensemble des valeurs stockées dans les cases du tableau en partant de la première case jusqu'à la dernière. Soit de la position 0 jusqu'à la taille totale du tableau, renvoyée par la fonction
sizeof(). A la suite, nous ajoutons donc le code suivant :
for($i=0;$i
{
}
C'est ensuite un traitement
switch qui permettra de considérer une à une les valeurs ainsi découpées pour les stocker dans des variables indépendantes en vue de les insérer dans une table de base de données à l'aide d'une requête INSERT INTO par exemple. Ce qui donne, une fois consolidé, le code suivant :
while(($memoire = fgets($fichier, 4096)) !== false)
{
$une_voiture = explode(";",utf8_decode($memoire));
for($i=0;$i
{
switch($i)
{
case 1:
/* Traitement */
break;
case 2:
/* Traitement */
break;
case 3:
/* Traitement */
break;
}
}
}
Une fois tous les traitements terminés, il ne faut surtout pas oublier de libérer l'accès en mémoire alloué au fichier CSV :
fclose($fichier);