Approfondissement
Aperçu des sections
-
Ce cours permet de découvrir des usages un peu plus avancées de PHP. Moins fréquents que les concepts de bases, ils sont quand même utilisés très largement dès qu'on développe une application en PHP.
-
L'envoi d'e-mails est une fonctionnalité très répandue dans les technologies web. Que ce soit pour un simple formulaire de contact, des campagnes marketing "de masse", ou bien encore l'envoi d'e-mails automatiques programmés dans votre logiciel (mails de maintenance, fonctionnalités pour les clients,....), le mail reste un moyen de communication privilégié.
Pour ceux qui travaillent beaucoup avec les e-mails dans leurs projets, je vous conseille de bien vous renseigner sur l'environnement "mail", car il y a de nombreuses choses à savoir qui ne dépendent pas de PHP. PHP propose une utilisation aisée de l'envoi d'e-mails, mais il vous faudra néanmoins avoir une configuration minimale pour que cela fonctionne bien.Selon votre environnement, la gestion des e-mails peut être très différente :
- en local : il vous faudra certainement passer par un service tiers pour envoyer des e-mails
- en mutualisé : vous aurez certainement accès à un serveur mail installé sur la machine (postfix, sendmail,...), mais vous n'aurez pas la main sur toute sa configuration
- en dédié : vous pourrez avoir votre propre serveur d'e-mails, mais du coup il vous faudra le configurer vous même, et cela peut vite se compliquer si l'on souhaite des e-mails "nickels".
Datant d'avant le web (premier e-mail de l'histoire en 1971), l'e-mail hérite de quelques lourdeurs techniques, lié au protocole utilisé (SMTP), au "formatage" des e-mails, et à la couche de sécurité requises par de nombreux "mailers" modernes. Donc ne vous étonnez pas si l'envoi d'e-mail ne coule pas de source dans votre application, vous rencontrerez certainement de nombreux obstacles (configuration du serveur mail, gestion des certificats de sécurité, blacklistage, réception du courrier dans les spams, etc... la liste est longue ^^).Dans ce cours, nous n'entrerons pas dans l'univers du mail (qui est très vaste), mais nous allons voir les quelques méthodes standards pour envoyer des mails grâce à PHP.
Le serveur de messagerie
L'envoi de mail passe toujours par le protocole SMTP, mais il y a différentes manières de l'utiliser. De la même manière que l'on utilise un serveur de base de données pour stocker puis requêter des données, on utilisera un serveur de messagerie pour envoyer des e-mails. Le transit des e-mails se fait via les protocoles SMTP ou POP/IMAP, et on sort donc de l'usage standard de HTTP. Donc pour envoyer un e-mail, on doit faire transiter des informations entre le serveur web et le serveur de messagerie.
Voici deux grands cas d'école :
Se connecter à un mailer existant, via un compte utilisateur
Une manière simple, mais pas très glorieuse, d'envoyer des e-mails, c'est d'utiliser un compte existant sur un service de messagerie (ex : Gmail). Cela veux dire que votre programme va utiliser un compte sur un service extérieur pour envoyer des mails à votre place.
Il vous faudra donner vos identifiants quelque part dans votre environnement, et PHP va se connecter au service pour transmettre le contenu de l'e-mail à la plateforme. Elle se chargera par la suite de l'envoyer au destinataire "à votre place". Les techniques pour mettre ça en place diffèrent selon les messageries et selon votre environnement, donc à vous de voir la configuration requises pour que tout marche bien.Par exemple : dans Laragon, il vous suffit juste de renseigner votre user/password dans le menu des e-mails, et de désactiver une option de sécurité sur votre compte Google. Cela permet à Laragon et PHP de se connecter à votre compte Google facilement, puis d'envoyer l'e-mail par l'intermédiaire du serveur de Gmail.
Cette approche est très utilisée dans le web, car relativement simple, et facile à mettre en œuvre. Mais elle à l'inconvénient d'être "bridée" par la plateforme utilisée. Vous aurez du mal à envoyer des e-mails propres (avec votre nom de domaine par exemple), tous les mails seront envoyés depuis l'adresse xxxxx@gmail.com. Donc pas très pro. On peut contourner ce problème, mais ça restera une approche "bricolage", qui dépendra entièrement de ce que la messagerie est encline à vous offrir.
Se connecter à son propre serveur SMTP
Une approche plus propre, si vous avez un serveur mail à disposition correctement configuré, consiste à se connecter au serveur de messagerie afin que le mail parte directement de "chez vous". Dans un environnement pré-configuré (ex : hébergement mutualisé), PHP se connecte automatiquement au serveur mail installé par défaut. Dans d'autre cas, il faudra passer par la configuration d'une connexion propre, bien souvent par l'utilisation de classes dédiées (ex : PHP Mailer). Il vous faudra alors renseigner les informations nécessaires à la connexion au serveur SMTP (un peu comme avec une base de données).
Voici un exemple d'une configuration de connexion à un serveur mail sur le framework CodeIgniter :
$config = array(
'wordwrap' => true,
'protocol' => 'smtp',
'smtp_host' => 'ssl://ssl0.ovh.net', /*Hôte du serveur + protocole cryptée*/
'smtp_port' => '465', //Port
'smtp_timeout' => '3',
'smtp_user' => 'contact-dev@xxxxxxx.com', /*Utilisateur (compte déclaré) avec un nom de domaine propre*/
'smtp_pass' => SMTP_PASSWORD, /*Ici, le mot de passe est stocké dans une constante dans un fichier dédié aux mots de passe*/
'charset' => 'utf-8',
'newline' => "\r\n",
'mailtype' => 'html'
);Dans cet exemple, le programme va se connecter au serveur SMTP, lui transmettre le contenu du mail, puis le serveur SMTP enverra l'e-mail. Donc ça n'est pas votre programme qui va envoyer l'email directement, c'est bien le serveur mail.L'envoi d'e-mails du point de vue du programme
Avec PHP, il y a différents moyens d'envoyer un e-mail. PHP offre nativement la fonction mail() qui permet de couvrir de nombreux cas de figures, mais on utilisera souvent une librairie dédiée à la gestion des e-mails pour avoir plus de souplesse dans la création et l'envoi de nos mails.
La fonction mail() de PHP
Facile d'utilisation, la fonction mail() peut-être très utile lorsque tout est bien configuré. On peut lui envoyer jusqu’à 5 paramètres :
- le destinataire
- le sujet du mail
- le contenu du mail
- les entêtes SMTP (header)
- des paramètres optionnels
L'envoi d'e-mails dépendant en grande partie du protocole SMTP, nous ne nous attarderons pas sur la mécanique de ce protocole ici. J'encourage ceux qui ont une forte problématique d'envoi d'e-mails à se renseigner plus en détails sur Internet. Voici la page vers la documentation officielle de la fonction mail de PHP.
Cette fonction renvoi true en cas de succès, et false en cas d'erreur.
Voici un exemple de ce que pourrait être un bout de script qui envoi un mail via la fonction mail() :
La variable $values représente des champs de formulaires que l'utilisateur vient de remplir.//Sujet du mail
$subject = "Demande d'information : ".$values['objet'];
//Contenu du mail
$text = "Message de : ".$values['nom']."\n";
$text .= "Objet : ".$values['objet']."\n";
$text .= $values['message']."\n\n";
$text .= "Adresse email de l'expéditeur : ".$values['email']."\n";
//Headers
$head = "MIME-Version: 1.0
Date: ".date('r')."
From: xxx.fr <contact@xxx.fr>
X-Mailer: PHP/".PHP_VERSION."
Reply-To: <".$values['email'].">
Content-Type: text/plain
";
//Envoi du mail via la fonction mail()
mail('contact@xxx.fr', $subject, $text, $head, '-f contact@xxx.fr'); /*Utilisation de mail(), avec les bonnes variables en paramètres*/
PHP MailerSi la fonction mail() ne marche pas sur votre serveur, vous pouvez utiliser la classe PHPMailer, très utile pour contourner le problème et vous connecter à un serveur de messagerie distant.
https://www.webtolosa.com/2019/12/20/tuto-envoyer-un-mail-avec-phpmailer/
-
Devoir
-
PHP offre de nombreuses fonctions natives qui vous permettent d'interagir avec l'OS et le système de fichiers. Dans un environnement Linux, vous serez restreints par les permissions de l'utilisateur qui exécute PHP, mais vous pouvez tout de même faire de nombreuses choses.
Toutes ces fonctions peuvent être très utiles dans certains cas, surtout lorsque l'on travaille sur des problématiques ou on ne peut pas s'appuyer sur la base de données, voici quelques exemples :
- script d'import de fichier (ex : un fichier d'export CSV fourni par un logiciel tiers (Excel, open data, logiciel de compta, etc...))
- stockage d'informations dans l’arborescence (ex : les images sont rarement stockées en bdd, il faut donc les stocker dans un dossier)
- lire des fichiers de config (json, ini, ou tout autre format)
- obtenir des infos sur l'os, un répertoire, ou un fichier (date de modification, espace disque disponible, lister le contenu d'un dossier, etc...)
Un exemple : le dossier de stockage des images uploadées dans Wordpress :
Cette image représente l’arborescence classique d'un Wordpress. On retrouve le dossier wp-content, qui comprend lui-même le dossier uploads. Ce dossier va stocker toutes les images qui ont été uploadées au fil du temps, avec un dossier par année, et un sous-dossier par mois. Dans l'exemple, on voit le dossier "2018", et tous les mois jusqu’à juin (01, 02, ...., 06). À l'intérieur de ce dossier "06", il y a l'image originale qui a été uploadée (malcare.jpg) par l'utilisateur du Wordpress, puis il y a plusieurs formats différents de la même image (small, medium, big, etc... avec la résolution dans le nom du fichier).
Pour réaliser ceci, Wordpress doit donc :
- créer des dossiers et des sous dossiers dynamiquement (mois, années, etc...)
- renommer des fichiers
- copier un ensemble de fichiers à l'intérieur de ces dossiers
Pour ce faire, il utilisera forcément des fonctions liées au système de fichiers telles que :
- mkdir : pour créer des dossiers (même nom que la commande shell, pratique)
- copy : pour copier un fichier
- unlink : pour supprimer un fichier
- etc...
Note : pour conclure sur le stockage des images, sachez qu'en général on stockera uniquement le chemin vers le fichier image en BDD. Ce qui permettra d'avoir l'image en BDD, et le fichier image dans un fichier. Voici un thread Stackoverflow sur le sujet.Voici d'autres fonctions PHP concernant le système de fichiers qui sont couramment utilisées :
- fopen, fread, fgetcsv,... : lecture de fichiers
- chgrp, chown, chmod,... : changer les propriétaires ou les permissions d'un fichier/dossier (similaire aux commandes Linux)
- basename, pathinfo, lstat,... : méta-informations concernant un fichier/dossier
- etc...
Bref, il existe de nombreux cas ou l'on va avoir besoin de manipuler des fichiers ou bien des informations concernant le système de fichier. Vous trouverez une liste de toutes les fonctions permettant de faire ceci sur cette page https://www.php.net/manual/fr/ref.filesystem.php. -
Il est possible, et assez fréquent, d'écrire des scripts PHP qui ne sont dédiés à être exécutés en ligne de commande. Donc hors de l'environnement standard avec le serveur Web.
Les deux environnements se nomment respectivement :
- CGI : pour Common Gateway Interface. C'est le fonctionnement classique de PHP, quand il est connecté au serveur web (voir un wiki sur le CGI)
- CLI : pour Command Line Interface. C'est le fait de lancer un script non pas via une requête HTTP, mais directement en ligne de commande
Avant d'exécuter un script PHP en CLI, il faut s'assurer que la commande "php" soit bien disponible dans le terminal. Pour vérifier ça, on exécute généralement la commande php -v dans un terminal, ce qui a pour résultat d'afficher la version de PHP qu'utilises la CLI.
Voici un exemple :
Dans cet exemple, le terminal renvoi bien la version en cours de PHP (7.4.3), ce qui sous-entend que PHP est bien reconnu comme une commande disponible.
Si cela ne marche pas, il vous faudra définir la commande PHP dans vos variables d'environnements de votre terminal. La manip sera différente sur Windows (en passant par l'interface graphique "variables d'environnements") ou Mac/Linux (en exécutant des commandes du type EXPORT path... exemple ici).Une fois que vous avez vérifié que PHP est bien exécutable en ligne de commande, vous pourrez exécuter un script en CLI en exécutant la commande suivante dans un terminal : php monscriptCLI.php
Voici un exemple de script sandbox.php avec un affichage Hello World ultra poussé :
Fichier sandbox.php :
echo "Hello world : je suis un script php qui est exécuté en ligne de commande\n"; /*Notez le retour chariot : il n'y pas de <br> en ligne de commande */ echo "Nous sommes le ".date('d-m-Y')." et il est ".date('h:m:s')."\n"; /*La plupart des fonctionnalités classiques sont opérationnelles en CLI*/
Exécution du script en ligne de commande :
La première flèche rouge est l'appel du script, la deuxième c'est son résultat (output). Ici le script est appelé deux fois pour l'exemple.
Bien que ce ne soit pas la plus grosse partie d'une application web, les scripts PHP CLI sont très utilisés dans certains cas :
- tâches programmées via un cron (donc lancées généralement en ligne de commande : envoi d'email programmés, de SMS, de newsletters, etc...)
- tâches de maintenance (automatisées via un cron, ou pas : nettoyage de DB, calcul de stat pendant la nuit, etc...)
- lancement manuel d'un script pendant une phase de dev
- etc...
Pour plus d'informations, voici la doc officielle sur l'exécution de script PHP en CLI. -
Avant de voir les variables d'environnement en PHP, voir le cours générique sur les variables d'environnement. (pas encore écrit)
Dans cette section, nous verrons l'utilité des variables d’environnements obligatoire dans un programme lorsque vous travaillez dans différents environnements. Le cas classique, ce sont ces trois environnements :
- un environnement de développement
- un environnement de test
- un environnement de production
Dans ce mode de fonctionnement, il y a certaines choses qui vont changer en fonction de l'environnement dans lequel s'exécute votre script.
Voici quelques exemples :
- les codes d'accès à la base de données
- la gestion et l'affichage des erreurs
- une liste d'e-mails à contacter (ex : problème technique, service commercial, etc...)
- l'exécution de tâches automatiques (tests, etc...)
Toutes ces informations dépendent de votre type d'environnement (dev/test/prod). En développement, vous pourrez utiliser par exemple 'root 'root' pour vous connecter à votre base de données, mais en production, ce sera des identifiants différents.
Donc bien souvent, on va mettre en place un mécanisme qui permet à l'application de savoir si elles se trouvent en dev, en test, ou en prod, puis en fonction de ce paramètre, certains réglages peuvent changer. On stockera généralement toutes les données nécessaires au bon fonctionnement de l'application dans un fichier à part, que l'on prendra soin de ne pas versionner (car il contient des données sensibles).
Il y a plusieurs façons de gérer les variables d’environnement en PHP. Mais attention, ne confondez pas les variables d'environnement "système" (appartenant à l'OS), avec les variables d'environnements propres à votre application.
Via le .htaccess
Si vous utilisez Apache, cette méthode vous permet de stocker "en dur" des variables d’environnement directement dans votre fichier .htaccess. Pour cela, il faut que le module mod_env de Apache soit disponible et activé. Ensuite vous n'aurez qu'à utilisez la directive SetEnv du .htaccess, suivi du nom de la variable, puis de sa valeur.
Exemple de variables d'environnement définies dans le .htaccess :
SetEnv DB_USER julien
SetEnv DB_PASSWORD azertyCes variables (ou plutôt constantes), seront alors disponibles dans vos scripts PHP via l'utilisation de la super globale $_ENV. A mon avis, cette méthode est à éviter car elle entraîne certaines lourdeurs :
- problème si on utilise un autre serveur web (ex : NGinx)
- ça oblige à modifier la configuration
- PHP doit lire le fichier .htaccess (perte de performance)
- il y a des solutions mieux intégrées à PHP, donc plus propres
- on risque d'être limité sur des hébergement mutualisés (sur le mien, il préfixe le nom de ma variable avec "REDIRECT_")
Cette approche est aussi disponible avec NGinx, mais la façon de faire ne sera pas la même qu'avec Apache.
Via les fonctions putenv() et getenv()
Ce sont des fonctions natives de PHP qui permet de créer ou de lire des variables d'environnement. Il existe des fonctions dérivé apache_setenv() et apache_getenv(). Personnellement, je ne les ai jamais utilisé. Ces fonctions peuvent toucher à des variables d'environnements OS, et donc créer des problème ou des failles de sécurité.
Via un mécanisme maison
Mon préféré :) L'idée est assez simple : on stocke toutes les variables d'environnement, et leur valeurs, dans un fichier à part, par exemple env.php, ou bien env.ini (le format .ini permet de partager des informations avec d'autres programmes qui ne seraient pas en PHP). On prendra soin de ne pas versionner ce fichier, et de le mettre si possible en dehors de l'application (à un endroit protégé de l'OS, par exemple).
Ensuite, on chargera ce fichier dans notre application via une inclusion de fichier judicieusement positionnée. Par exemple, via un point d'entrée unique, tel que la page index.php le plus souvent. Une fois que votre mécanisme est prêt, les différentes variables seront accessibles dans votre application, tout en étant bien rangées et regroupées dans un seul fichier.
Frameworks
Cette problématique étant très répandue dans le développement d'application, les frameworks proposent en général une gestion poussée des différents environnement d'exécution. Par exemple avec CodeIgniter, vous allez pouvoir régler vos différentes configurations via des fichiers PHP stockés dans des dossiers "development", "testing" et "production". Il peut y a voir beaucoup de choses à modifier selon les environnements, donc autant être organiser, et bien séparer toutes les facettes de votre configuration dans des fichiers et dossiers distincts.
Exemple d'un projet avec CodeIgniter :