On appelle Common Gateway Interface, ou en abrégé CGI, une interface, utilisée par les serveurs HTTP, qui permet de générer la réponse du serveur par un programme, qui s’exécute sur le serveur. Le programme pourra, assez typiquement, générer du code HTML qui sera affiché par un navigateur côté client. L’interface CGI est indépendante du langage de programmation utilisée par le serveur, et n’utilise que les flux standards et les variables d’environnement.
…
Le PHP est un langage de programmation (ou langage de scripts) qui permet de générer et d’afficher des pages webs dynamiques, c’est à dire des pages dont le contenu dépend des actions de l’utilisateur ou de l’état, par exemple, d’une base de données. En fin de compte, le code affiché est toujours du code HTML. Ce code HTML est généré par le programme PHP via la commande echo. La protection des caractères spéciaux du HTML (comme les guillemets) et le mélange du code PHP et du code HTML rend souvent le code d’un script PHP. Nous verrons plus loin comment atténuer ce problème par une approche modulaire fondée sur la programmation objet.
Le script PHP est inséré à l’intérieur d’une balise <?php > qui peut s’insérer au sein du code HTML.
Ici, nous voyons une fonction PHP qui génère l’en-tête XHTML du document et son header. Cette fonction prend en paramètre le titre, le charset et l’url d’une feuille de style CSS à appliquer dans le header HTML. Le résultat est que lors de l’utilisation de la fonction, presque tout le code HTML disparait pour être remplacé par une seule ligne de code, ce qui en fin de compte allégera de beaucoup le code source PHP.Inclure un fichier PHP dans un autre
Évidemment, si le but des fonctions PHP est de cacher et de réutiliser une partie du code, il est commode de pouvoir écrire une fois pour toutes la fonction dans un seul fichier, puis d’utiliser la fonction dans tous nos scripts par la suite. Ici les fonctions outputEnTeteXHTML et outputFinFichierXHTML sont utilisées dans tous les scripts qui affichent du code HTML. (en effet, nous verrons plus loin que certains fichiers PHP sont de la pure programmation et n’affichent rien.)
En PHP, on ne déclare pas les types des variables ou des paramètres de fonctions. Celui-ci est défini lors de l’initialisation de la fonction. Des fonctions permettent cependant de tester le type ou d’accéder au nom du type d’une variable. Nous en verrons par la suite.
On crée un tableau avec la fonction array. On accéde à ses éléments (ici indexés par un int) en utilisant des crochets [ ]. La taille des tableaux peut être obtenue via la fonction sizeof.
Il existe en PHP une deuxième sorte de tableaux : les tableaux associatifs, ainsi nommés car ils associent une valeur à une clef qui est une chaîne de caractères. On peut tout de même parcourir l’ensemble du tableau en utilisant une boucle foreach.
Dans l’exemple suivant, le premier script passe deux paramètes au second : le titre de la page et le texte à afficher.
Nous transmettons ici les paramètres par la méthode GET, la méthode POST, qui a l’avan- tage de ne pas faire apparaître les paramètres dans l’URL, est similaire au niveau programma- tion et sera vue plus loin.
L’url du second script dans le navigateur est ici
… … …
Les exemples de classes présentées dans ce chapitre visent à expliquer les mé- canismes de base de la programmation objet en PHP. Ils ne sont pas forcément réalistes ou adaptés pour l’implémentation d’une application Web bien organisée. Nous invitons pour cela le lecteur à consulter les exemples présentés à partir du chapitre 4, partie 5.2, dans lequel nous présentons le Design Pattern POPO.php
La programmation objet permet, en développant une bonne fois pour toutes un ensemble de classes appelé framework, de simplifier grandement le travail de développement et de mainte- nance de logiciels complexes, de manière que ces logiciels soient facilement adaptables. Ainsi, une entreprise telle qu’une société de services, d’un client à l’autre, reprendra tel quel une grande partie de son code, sans même le retoucher. Ce code doit avoir une interface de déve- loppement, c’est à dire qu’il doit mettre à disposition des développeurs un ensemble de méthodes qui permettent de réaliser toutes les tâches de base dont le programmeur peut avoir besoin pour développer chaque application particulière.
Les caractéristiques d’un framework doivent être :
Par rapport à ces quatre objectifs, des outils sont à disposition des développeurs du frame- work :
Enfin, la conception objet permet de concevoir la structure (ou l’architecture) du logiciel indépendament du langage de programmation, par représentation en Unified Modeling Lan- guage (UML). Nous utiliserons dans ce cours des diagrammes de classes, des diagrammes de séquence, et des diagrammes de cas d’utilisation.
S’agissant du code source PHP, des standards concernant l’organisation du code ont été définis, qui visent à garantir l’interopérabilité des frameworks et de leurs plugins et, en général, des applications écrites en PHP.
L’organisme PHP-FIG (Framework Interoperability Group) définit de tels standards, appelés PSR, pour PHP Standard Recommendations. L’un des objectifs de ce cours est de présenter, dans la partie, les principes d’organisation d’une application suivant les recommandations du standards PSR-1 : Basic Coding Standard.
Ce standard impose de suivre une organisation d’auto-chargement des classes qui repose sur une organisation où les répertoires contenant du code source correspondent à des namespaces PHP, ou autrement dit, des modules, qui représentent des packages au niveau de la conception et représentation UML du logiciel. Pour cette raison, nous présentons dès les premiers chapitres une conception objet qui inclut un découpage en modules explicité par des namespaces.
Disons enfin que l’organisation des modules suit elle-même certains Design Patterns, telle que l’architecture trois tiers MVC (voir le chapitre) ou la couche d’accès aux données DAL
(voir le chapitre). Ces patrons de conception visent à garantir la modularité par le découplage des différentes parties d’une application, permettant de faciliter les évolutions (par exemple un changement de technologie pour l’interface homme-machine IHM ), du fait de l’indépendance logique des parties.
Un classe doit permettre de manipuler un certain type d’objets. La classe doit permettre de représenter les caractéristiques des objets, à travers un certain nombre d’attributs, qui sont les variables communes à chacun des objets de ce type. La classe doit aussi permettre à un développeur qui l’utilise de réaliser toutes les opération nécessaires sur ces objets, à traves des méthodes. Les méthodes d’une classe sont les fonctions qui opèrent en interne sur la classe. La manipulation des attributs se fait presque systématiquement à travers des méthodes, cet qui évite que l’utilisateur de la classe ne mette les attributs dans un état incohérent (exemple : variables NULL alors qu’elle n’est pas censée l’être, ce qui génère un bug). Pour celà, on met les attributs privés, c’est à dire que seules les méthodes de la classe peuvent accéder à ces attributs. Pour les autres classes, ces attributs ne sont pas visibles : elle ne peuvent pas y accéder directement mais uniquement à travers des méthodes.
Voici un premier exemple d’une classe appelée VueHtmlUtils qui définit deux méthodes statiques générant respectivement l’en-tête d’une fichier HTML5 et la fin d’un fichier HTML (fermeture des balises). Cette classe utilitaire sera utilisée dans la génération du code HTML dans les vues.
... ... ...
Les setters de la classe vont jouer un rôle important de filtrage des données. Le filtrage consiste à réaliser des tests sur les données entrées (généralement des données issues d’un utilisateur final), et à générer des erreurs en cas de données incorrectes, ou encore en remplaçant automa- tiquement des données incorrecte par des données, sinon correctes, au moins inoffensives.
En particulier, lorsque les données viendront de la saisie d’un formulaire, ces données de- vront être systématiquement filtrées car l’utilisateur, qui n’est pas toujours bienveillant, et peut mettre n’importe quoi dans les champs d’un formulaire. Le filtrage jouera donc un rôle très important pour la sécurité. Par exemple, on prendra soin de limiter la longueur des attributs de type String à la fois au niveau du filtrage, puis au niveau de la base de données (voir chapitres ultérieurs). On pourra aussi utiliser des expressions régulières lors du filtrage grâce aux fonc- tions preg_match_all ou preg_match (voir man regex(7) pour la formation des expressions régulières). Le gros avantage du PHP par rapport à d’autres langages comme javascript, est que PHP s’exécute côté serveur donc un pirate n’aura pas la possibilité d’analyser précisément ce que fait le filtrage.
Si une valeur invalide est détectée au niveau du filtrage, on générera une exception avec un message d’erreur. Cette exception pourra être gérée à un autre niveau dans l’application, ici au niveau du script de test qui affiche quelques employés. Certaines parties ultérieures de ce cours sont dédiées au filtrage précis des données et à garantir la sécurité du code grâce au filtrage. Dans cette partie, nous réalisons un filtrage sommaire, pour illustrer le mecanisme de gestion des erreurs par .
Nous voyons ici une classe Personne, suivant un peu le meme schéma de conception que la classe Adresse de la partie précédente. Cependant, au niiveau des setters, nous implémenterons un filtrage (minimal et peu réaliste pour le moment), rejetant une exception en cas de données incorrectes.
… …
Notons l’attribut categoriesEmployes, qui répertorie dans un tableau toutes les catégories d’employés possibles, et la méthode validCategorie, qui détermine si une chaine de catactères correspond à une catégorie d’employés. Cette donnée et cette méthode sont déclarées statiques. Il s’agit donc d’une variable de classe et d’une méthodes de classe.
Voici le script de test qui crée quelques employés. Lorsque’une exception est reçue, au lieu d’afficher l’employé, on affiche le message d’erreur. Nous verrons plus loin comment ce mécanisme de gestion des exceptions permet de renvoyer à l’utilisateur des informations sur les attributs invalides qu’il a saisi dans le formulaire.
… … …
Les formulaires HTML permettent de faire saisir des données par l’utilisateur via son naviga- teur. Ces données sont saisies dans des champs appelés inputs, qui sont définis avec la balise
<input>. Les données sont ensuite récupérées dans un script, ici un script PHP. Ces données doivent impérativement être testées et filtrées pour des raisons de sécurité.
Un formulaire est créé par une balise <form> qui contient la méthode de transmission des données (GET ou POST) et l’action, qui est l’URL du script (ici un script PHP) qui va récupérer les données du formulaire. Chaque input a son label, qui explique à l’utilisateur ce qu’il doit saisir dans ce champ. La correspondance entre les inputs et le labels se fait via l’attribut for du label qui doit correspondre à l’attribut id de l’input. L’attribut name de l’input servira lors de la récupération des données. Les attributs id et name de l’input peuvent être égaux si on veut simplifier.