# Programmation PHP/Version imprimable3

* Si vous imprimez cette page, choisissez « Aperçu avant impression » dans votre navigateur, ou cliquez sur le lien Version imprimable dans la boîte à outils, vous verrez cette page sans ce message, ni éléments de navigation sur la gauche ou en haut.
* Cliquez sur Rafraîchir cette page pour obtenir la dernière version du wikilivre.
* Pour plus d'informations sur les version imprimables, y compris la manière d'obtenir une version PDF, vous pouvez lire l'article Versions imprimables.
Une version à jour et éditable de ce livre est disponible sur Wikilivres, une bibliothèque de livres pédagogiques, à l'URL : https://fr.wikibooks.org/wiki/Programmation_PHP

# Exemples/Variables
## Utilisation de variables
### Explications

* Une variable en php commence par le symbole $. Ici nous utilisons une variable d'identificateur $i.
* Il n'y a pas de déclaration ni de typage fixe : une variable peut changer dynamiquement de type, ce qui est parfois vu comme un atout, parfois comme une faiblesse !
* Ce programme comporte une boucle for qui a sa sémantique habituelle. La variable $i va donc prendre successivement les valeurs 1,2,... jusqu'à 10.
* Dans cet exemple les chaînes de caractères sont entre apostrophes.
* La concaténation des chaînes de caractères s'effectue grâce à l'opérateur ..
* Remarque : si on veut qu'une chaîne de caractères contienne une apostrophe droite il faut écrire \' à l'intérieur de la chaîne.

### Les guillemets

Une chaîne de caractère entre guillemet est assez particulière : si elle contient $a alors $a est remplacé par la valeur de la variable $a. Il y a automatiquement substitution. Si on écrit \$ alors il n'y a plus substitution. De la même manière, pour afficher le caractère guillemet on écrit \".

### Explications

Dans ce programme la variable $a vaut 67+33 donc vaut 100. Dans la chaîne de caractères \$a affichera $a et le deuxième $a sera remplacé par la valeur 100. Il s'affichera donc : la variable $a vaut 100

# Exemples/Sommaire
## Un sommaire simple

Imaginons un site Web composé de 4 pages entre lesquelles on peut naviguer grâce à un sommaire. Notre sommaire est par exemple à gauche de l'écran et contient 4 liens hypertextes : page 1, page 2, page 3 et page 4. À droite de l'écran, le contenu principal de la page change en fonction de la page affichée. Par contre notre sommaire apparaît lui sur chacune des pages.

### Le programme en php

Fichier index.php
fichier page1.html
fichier page2.html
fichier page3.html
fichier page4.html

### Explications

* Dans ce programme, la page est découpée en 2 parties : à gauche une partie ayant comme id sommaire et à droite une page ayant comme id page.
* La partie « sommaire » utilise le style #sommaire de la feuille de style et la partie « page », le style #page.
* Le sommaire est constitué de 4 liens hypertextes appelant respectivement index.php?page=1, index.php?page=2, index.php?page=3 et index.php?page=4. Lorsqu'on met un point d'interrogation après l'URL d'une page, cela signifie qu'on donne une valeur à un paramètre et qu'on envoie cette information au serveur par la méthode GET. Lorsqu'on clique sur l'un des 4 liens hypertextes, on appelle à chaque fois la même page index.php mais à chaque fois la valeur du paramètre nommé page change : il vaut 1, 2, 3 ou 4 selon le lien cliqué.
* Dans la partie « page » de index.php, la valeur du paramètre page est récupérée de l'url cliquée en écrivant $_GET['page']. Ce paramètre peut très bien ne pas exister : ceci a lieu notamment la première fois qu'on appelle notre page index.php. Dans ce cas, la fonction isset permet de savoir si une variable existe. La ligne
       if (isset($_GET['page']))$numero=$_GET['page']; else $numero='1';
    récupère la valeur du paramètre page et la place dans la variable $numero. Si ce paramètre n'existe pas $numero vaut 1.
* La fonction require'nom_du_fichier'; permet d'insérer un fichier à cet endroit dans le code. Le server insère donc page1.html ou page2.html ou page3.html ou page4.html en fonction de la valeur du paramètre page (et de la variable numero).
* Notre sommaire est terminé.

# Exemples/Formulaire
## Interaction avec un formulaire
### Les principaux concepts

L'interaction entre une application en PHP et un utilisateur peut s'effectuer par des liens hypertextes ou par l'envoi d'un formulaire. C'est ce cas dernier que nous allons étudier ici.
Le formulaire comporte une balise form qui précise que la méthode utilisée pour envoyer le contenu du formulaire au programme en PHP est la méthode POST. Elle précise également l'action du formulaire, c'est-à-dire à quelle adresse envoyer le contenu du formulaire pour son traitement. Dans notre exemple, après un clic sur le bouton d'envoi, le formulaire déclenchera l'exécution du programme go.php. Le formulaire est composé de 3 éléments graphiques : 2 champs de type texte nommés respectivement nom et prénom et un bouton sur lequel il est écrit envoyer le formulaire. Le formulaire invite donc l'utilisateur à entrer un nom et un prénom et à cliquer sur le bouton « envoyer le formulaire ».
Le programme go.php doit récupérer les valeurs contenues dans le formulaire : pour récupérer la valeur du champ nom, il faut écrire $_POST['nom']. De la même manière, pour récupérer la valeur du champ prénom, il faut écrire $_POST['prenom']. Après un clic sur le bouton « envoyer le formulaire », une autre page s'affiche. Elle contient un message contenant "Bienvenue à" suivi du prénom et du nom définis dans le formulaire rempli. Le programme a bien récupéré la valeur des différents champs du formulaire.

### Le programme en php

Le fichier index.html :
Le fichier go.php :

### Captures d'écran
# Exemples/BD 1
## Afficher le résultat d'une requête
### Présentation

Dans cet exemple, on va créer une application qui extrait des données à partir d'une base de données et qui affiche le résultat à l'écran. Notre programme va afficher une liste d'employés d'une entreprise imaginaire : chaque employé est défini par un nom, un prénom et un salaire. La base de données utilisée sera une base mysql. Les données seront dans une table nommée employe. La table employé possède des champs NOM, PRENOM et SALAIRE. La table employé possède de plus un identifiant nommé ID qui est un entier (BIGINT) autoincrémenté et qui est une clé primaire de la table.
Nous étudierons une première version du programme et dans un second temps nous améliorerons le programme en utilisant la méthode GET lors d'une deuxième version.

### Descriptif du site

* La première page affiche 3 liens hypertextes :
** un lien pour afficher la liste complète des employés,
** un lien pour afficher la liste dans l'ordre alphabétique,
** un lien pour afficher par salaire décroissant.
* Sur chacune des pages, on affiche la liste et il y a un lien pour revenir à la première page.

### Création de la base

Les requêtes suivantes permettent la création et l'initialisation des données dans notre table :
Fichier BD.sql :
La table créée par ces requêtes est la suivante :
| ID | NOM | PRENOM | SALAIRE |
| 1 | Dupond | Marcel | 8000 |
| 2 | Martin | Xavier | 4000 |
| 3 | Gogol | Henri | 3000 |
| 4 | Hugo | Victor | 2000 |
| 5 | Gali | Daniel | 6000 |
| 6 | Martin | Georges | 9000 |

### Configuration de la base de données

La table employe appartient à la base de données toto. L'administrateur de cette base est root. Il n'a pas de mot de passe. Attention ceci est une configuration type utilisée par défaut pour la plateforme de développement EasyPHP : il est vivement recommandé de mettre un vrai mot de passe pour une plateforme en exploitation.

### Les requêtes utilisées

* Pour afficher la liste des employés, on utilisera la requête :
SELECT * FROM employe
* Pour afficher la liste des employés par ordre alphabétique, on utilisera la requête :
SELECT * FROM employe ORDER BY NOM, PRENOM
* Pour afficher la liste des employés par salaire décroissant, on utilisera la requête :
SELECT * FROM employe ORDER BY SALAIRE DESC

### Comment accéder en php à une base mysql

Les différentes étapes à respecter seront les suivantes :
* récupérer les informations suivantes :
** le nom de la machine qui héberge le serveur de la base de données (ici localhost)
** le nom de la base de données (ici toto)
** le nom de l'utilisateur de la base de données (ici root)
** le mot de passe de cet utilisateur (ici le mot de passe est vide).
* se connecter au serveur de base de données
* sélectionner la base de données (ici toto) sur ce serveur.
* créer la requête dans une chaîne de caractères
* envoyer la requête à la base de données et récupérer le résultat
* fermer la connexion avec le serveur de base de données
* transformer le résultat de la requête en HTML.

#### Étape 1 : les paramètres spécifiques au site

Pour réaliser la première étape nous allons créer un fichier params.php qui contient 4 variables $host (le nom de la machine qui héberge la base de données, $user (le nom de l'utilisateur de la base de données), $password (le mot de passe de cet utilisateur) et $base le nom de la base de données. Ces paramètres changent en fonction de la plateforme que vous utilisez. Il est intéressant d'isoler ces paramètres dans un fichier séparé, que ce soit au niveau de la sécurité ou pour porter l'application sur une autre plateforme. Il faut se renseigner au niveau de l'hébergeur sur les caractéristiques de la plateforme utilisée. Les paramètres suivants sont ceux par défaut si on utilise EasyPHP. On a juste créé une base de données appelée toto.
Pour récupérer, ces paramètres il suffit d'inclure ce fichier en utilisant le mot clé require. On écrira require'params.php' . Le fichier sera alors inclus dans le programme en php et le programmeur utilisera les 4 variables.

#### Étape 2 : connexion à la base de données

La fonction mysql_connect($host,$user,$password) permet de se connecter au serveur de base de données mysql situé sur la machine nommée $host en utilisant le nom d'utilisateur $user ayant comme mot de passe $password. Cette fonction renvoie le booléen true si la connexion est établie et false sinon.

#### Étape 3 : sélectionner la base de données

Un serveur de base de données peut héberger plusieurs bases de données (une base de données est un ensemble de tables). La fonction mysql_select_db($base) permet de sélectionner la base de données à laquelle on va envoyer les requêtes. Cette fonction renvoie true si tout s'est bien passé et false sinon.

#### Étape 4 : création de la requête

Il faut ensuite créer la requête dans une chaîne de caractères. Ici la requête va être simple, par exemple $query='SELECT * FROM employe'; : on met la requête dans la variable $query. Parfois, il faudra concaténer des chaînes de caractères pour construire la requête--.

#### Étape 5 : envoyer la requête et récupérer le résultat

Pour envoyer la requête au serveur, il faut utiliser la fonction $r=mysql_query($query); qui envoie la requête $query et récupère le résultat dans $r.

#### Étape 6 : fermer la connexion avec le serveur de base de données

Pour fermer la connexion avec le serveur de base de données, il suffit d'appeler la fonction mysql_close;.

#### Étape 7 : générer du HTML à partir du résultat de la requête

Supposons que le résultat d'une requête soit contenu dans la variable $r. Il est souvent intéressant de parcourir un à un tous les enregistrements contenus dans $r. L'appel de fonction $a=mysql_fetch_object($r) permet de récupérer un à un tous les enregistrements dans la variable $a. Lors du premier appel, on récupère le premier enregistrement dans $a, lors du second appel, on récupère le second enregistrement et ainsi de suite jusqu'au dernier enregistrement. Si on appelle alors une nouvelle fois cette fonction, elle va renvoyer le booléen false. Ceci permet donc de traiter un à un tous les enregistrements en écrivant
Lors de l'exécution de ce while $a va prendre toutes les valeurs des différents enregistrements contenus dans $r, du premier au dernier. À partir de l'objet $a, on pourra récupérer le champs NOM de cet enregistrement en écrivant $a->NOM. On peut ainsi récupérer la valeur de chaque champ d'un enregistrement. Il suffit donc maintennant de parcourir chaque enregistrement et d'afficher du HTML en utilisant la commande echo à partir des différents champs des enregistrements.

### Les pages du site (version 1)

Fichier index.html
Fichier params.php
Fichier liste1.php
Fichier liste2.php
Fichier liste3.php

### Les pages du site (version 2)

Lorsqu'on étudie les fichiers liste1.php, liste2.php et liste3.php, on s'aperçoit qu'ils sont extrêmement proches : on va donc réécrire l'application en écrivant un seul fichier liste.php et en le paramétrant grâce à la méthode GET.
Le nouveau fichier index.html devient donc :
On constate donc que les liens hypertextes, par exemple liste.php?l=1 appelle le même fichier liste.php en lui donnant un paramètre par la méthode GET, ici l=1, ce qui permet de paramétrer le fichier.
Remarque importante : lorsqu'on utilise ce genre de liens hypertextes, il faut toujours se poser la question : que se passe-t-il si l'utilisateur accède à la page liste.php sans passer de paramètres ou alors en écrivant liste.php?l=4 ? Le programmeur doit garantir que dans un tel cas, le site reste cohérent et que ceci n'engendre pas de failles de sécurité.
Le fichier liste.php devient :
Le programmeur teste en utilisant isset($_GET['l']) pour savoir si la variable l a été passée par la méthode GET et il récupère sa valeur dans la variable $l. Si ce paramètre n'existe pas, $l est fixé à la valeur 1. On construit ensuite la requête $query en fonction de la valeur de $l. Cette version du programme est plus simple mais îil faut toutefois faire très attention à la sécurité dans un tel cas.

# Exemples/Livre
## Créer le livre

Tout d'abord, il faut créer le livre d'or, c'est-à-dire une table où seront stockés les messages.
Voici un exemple de table, avec un identifiant auto-incrémenté qui sera la clé (pour pouvoir identifier de manière unique chaque message), puis un champ pour le nom, courriel, date, ... et bien sûr le message.

## Ajouter un message

Voici la requête SQL qui permet d'insérer les données dans la table:

### Saisie des données

Voici un exemple de formulaire servant à récupérer les données saisies par l'utilisateur pour les faire suivre vers 'ajout_message.php' qui les traitera. La méthode utilisée est POST, bien que GET marche aussi, mais POST possède l'avantage de ne pas rendre visible dans l'URL les paramètres passés, ce qui rend cette méthode plus « propre » et plus claire.
fichier formulaire.html

### Traitement des données

Le fichier « ajout_message.php » va récupérer et traiter les données saisies par l'utilisateur puis effectuer une insertion dans la base (c'est-à-dire ajouter le message dans le livre d'or). Ces données portent le nom qui leur a été donné dans le formulaire, précédé d'un '$' (représente une variable en PHP). Il est fortement conseillé d'effectuer des tests de saisie à ce niveau, pour vérifier que l'utilisateur a rempli correctement les champs (champs non vides, adresse email correcte,...).
fichier params.php
fichier ajout_message.php
La fonction htmlspecialchar permet de convertir les caractères spéciaux qui pourrait être interprétés comme du code HTML par un navigateur. Il existe d'autres fonctions, comme htmlentities, qui permet en plus de spécifier les caractères de remplacement, ou n12br qui permet de remplacer les retours chariots par le caractère HTML de retour à la ligne (br).

## Récupérer les messages et les faire afficher

Cette partie est beaucoup plus simple à réaliser que la partie précédente.
Voici la requête SQL qui permet de récupérer toutes les informations de la table dans la base de donées:
Les messages seront alors triés en fonction du champ `id`, et, par défaut, par ordre croissant, donc plus du plus ancien au plus récent. Pour les classer dans l'ordre décroissant, il faut rajouter l'instruction DESC, ce qui donne la requête suivante :
Après, il suffit d'afficher les informations obtenues grâce à la requête.
fichier affiche_message.php
Ceci n'est que le strict minimum pour faire un livre d'or. D'autres fonctionnalités, comme le nombre d'affichage par page, peuvent être ajoutées.

# Exemples/MiniForum
## Faire un mini forum de discussion

Bon nombre de forums sur internet ont repris des opensources et les ont customisé. Dans cet article, nous verrons comment simplement opposer de meilleures solutions, plus souples et personnelles. Ce chapitre traitera du programme à fournir pour cette solution sans proposer de sécurisation.

## Introduction

Voici un forum modulaire, universel, illimité, fonctionnel et très réactif mais à sécuriser avec MySQL en backend et HTML en frontend.

## Architecture

À bâtir en MVC, le forum est segmenté comme :
    ./index.php
    ./config.inc.php
// STATICAL MODULES
    ./Objects/
    ./Objects/frameset.inc.php // main frameset
    ./Objects/mainPage.inc.php // main pages content
// FUNCTIONNAL MODULES
    ./Libraries/

## Déploiement

La méthodologie processus unifié fonctionne par itérations successives et augmentation, amélioration du code. On obtient donc pour chaque module différentes itérations représentatives de l'état d'avancement de l'application. L'état 0 ou incrément 0 étant l'ébauche et incrément 1, la première itération de l'applicatif.
increment 0 : index.php
increment 1 : index.php
increment 2 : index.php

### Objects

increment 3 : frameset.inc.php
increment 0 : mainPage.inc.php
increment 1 : listener.inc.php
increment 1 : controler.inc.php
increment 1 : mainPage.inc.php
    À cette itération, l'authentification du user est fonctionnelle.
    Le snippet content['authorize'] change de mode.
increment 2 : mainPage.inc.php
    À cette itération, l'attribution des privilèges du user est fonctionnelle.
    Le snippet content['authorize'] affiche le statut user mode.
increment 3 : jsScript.inc.php
    intégration des javascripts
increment 3 : pages.inc.php
    contenus des pages
increment 4 : pages.inc.php
    contenus des pages complétés
increment 4 : controler.inc.php
    controler complété
    À ce stade on a une ébauche de layout pour notre forum :

#### Constatations

Après le login, on a :
    [1] admin
    [2] mod
    [3] user
[2] & [3] sont similaires, quelques indicateurs à basculer dans la base. Il reste donc deux cas.
L'admin aura sa propre IHM avec fonctions élevées sur le forum.

#### RUP - Rational Unified Process (ou comment coder ?)

La granularité de la solution s'effectuera par l'affinage des modules.
Il n'est pas intelligent de coder en procédurale ou suivant un développement linéaire dans ce cas. Chaque module ou addon s'interfacera par adjonction de classes et snippets. Ceux-ci étant bien définis quand aux (in/out)put, avec le type précis.
De cette manière l'applicatif sera modulaire et évolutif.

#### Module administratif

Le forum doit être dédié aux légumes. L'admin doit avoir le choix de créer ces différents sujets principaux.
Par exemple les sections :
* coups de cœur,
* espace détente,
* nouveauté & trouvailles,
* légumes.

### Bibliothèques

Nous aurons d'emblée besoin des deux utilitaires :
[classes]
    Les classes usuelles
* Connectivity
* Request
[functions]
    Les fonctionnalités usuelles
[classes]
[functions]
increment 2 : utils.fnc.php
increment 4 : utils.fnc.php
    add function

### Modélisation

La modélisation est fonction du métier et des affinités. En voici une fonctionnelle pour notre exemple :
un script d'installation pourrait être :

## Conclusion

Cette façon de coder n'est pas la plus élégante et ne vise pas l'excellence. Bien que l'approche modulaire accroisse la quantité de code, elle a cependant l'avantage d'être lisible pour les longs développements. L'approche itérative et incrémentale de la méthodologie RUP tire fortement parti du développement modulaire.
* une vue
* un frameset variable
* des sujets illimités
* des catégories illimités
* un système de classement
* un système d'administration
* un système d'authentification
* un espace myAccount
NICE TO HAVE :
* tout automatiser (censure / délation / ..)
* mailer
* BO admin

# Exemples/DomXml

Les documents au format XML ont des imbrications parfois complexes et il n'est pas rare de devoir avoir recours à plusieurs fonctions pour faire le travail de décapsulation du contenu.
À travers cet exemple pratique nous écrirons une fonction pour convertir tout document XML en tableau suivant l'approche du web2 qui tient en deux tags très galvaudés [meta] et [data].

## Objectif

* Élaborer une fonction permettant de convertir en tableaux tout XML bien formé.
* Créer une classe utilitaire domxml pour la recevoir avec ses petites sœurs.

## Écriture d'un XML complexe

* Écriture d'un document XML valide à imbrications multiples d'éléments hétéroclites comportant des attributs ou non...
* Sauvegarde de ce document.xml bien formé dans le même répertoire.

## Création de la fonction

On doit maintenant écrire une fonction, la plus optimale possible, pour charger document.xml dans un tableau...
Cette fonction doit :
* recevoir en entrée un flux xml/rss valide
* doit migrer les attributs et le contenu dans un tableau
On écrit la fonction récursive qui décapsulera chaque tag en deux sous-tableaux par tag ([meta] ou attributs ) et ([data] ou nœud texte)
Cette fonction doit :
* tester le type de nœud (texte ou tag)
* ? si tag >extraire tous ses attributs dans >[meta]
* ? si texte >extraire le texte dans >[data]
* comme la structure est imbriquée et non listée :
** les tags de débuts et de fins ne se suivent pas...
** la fonction sera donc récursive et s'appellera elle-même pour un output lifo. Elle devra donc se passer son propre résultat en paramètre
** par soucis du détail technique on fera une fonction getAttribute pour optimiser le code
Description :
* Pour chaque attribut, on place le contenu à une clé du tableau tab à retourner.
On s'attaque ensuite au plus gros du travail de notre convertisseur à savoir domxml2array :
Description :
* si le premier enfant existe,
* on test le type de nœud,
* on passe au nœud suivant.
La fonction utilitaire print_r_html disponible sur php.net permettra de déposer le contenu à l'écran :

## Création de la classe

On élabore une classe utilitaire pour php4 à implémenter au fur et à mesure :
* On la baptise DomTree.
* On y implémente les fonctions créées...
* On sauvegarde la classe dans DomTree.Class.php.

## Application

Dans un fichier test.php on instancie la classe et on l'exécute:

## Aperçu

On obtient un arbre structuré easy2use pour le web2

## En bref

On a une fonction fort utile à porter sur php5 ou à optimiser histoire de ne plus avoir d'incréments dans les données du tableau.

# Exemples/MVC

Historiquement, PHP est un langage glue, il peut être intégré avec le langage de balisage HTML. L'avantage est cette simplicité de mise-en-œuvre mais l'inconvénient est le mélange entre le traitement et l'affichage. Pour produire une application web claire et facile à entretenir, on peut séparer les différentes parties de l'application selon l'architecture Modèle-Vue-Contrôleur (ou MVC).
* Modélisation (Modèle : Partie métier spécifique à l'application)
* Visualisation (Vue : Partie visuelle de l'application)
* Contrôles (Contrôleur : Partie de gestion des événements de l'application)
De cette façon on peut implémenter son application en sous composantes ce qui augmente légèrement l'analyse de l'application mais fera gagner beaucoup de temps de développement par la suite. Cette architecture est déjà couramment employée dans les applications locales et les applications web l'utilise de plus en plus. On remarquera notamment que beaucoup de Cadriciel web sont basés sur ce principe.

## Développement

* Objectif : Faire un mini système de validation de données saisies.
Pour ce faire on a besoin :
* d'un formulaire HTML
* d'un module de validation
* d'un module de gestion homme-machine
* Pré-requis conseillés :
* html4
* php5

### Création de la vue

La vue comprendra un formulaire HTML pour la saisie des données utilisateur :

#### Spécialisation des composantes

Il est mieux de découper son application en sous composante. La vue par exemple pourrait contenir :
* le frameset de la page
* les containers à afficher
1. Le frameset (vueFrame.inc.php) :
2. Les formulaires deviendraient (vueFormulaire.inc.php) :

### Création du modèle

Cette bibliothèque utilitaire reprendra les traitements de validation
On a besoin des fonctions suivantes :
* check des string alphabétiques
* check d'un numéro VISA (4 groupes de 4 chiffres avec le premier groupe commençant par 4 pour simplifier)
! Ce modèle modeleValidation.inc.php par exemple comporte une nouvelle fonction isVisa remplaçant celle du 07.05.2006.

## Création du contrôleur

Le contrôleur regroupe les traitements de gestion de l'application, c'est à dire ici les événements déclenchés par l'utilisateur ou par le système. On parle souvent d'IHM, voilà un exemple.
On a besoin des contrôles suivants :
* validation de saisie
* affichage en fonction du statut de la saisie
! utilisation de $page['container']['main'] ne sert a rien ici car sera écrasé dans l'appel de la page principale.

## Gestion des containers

Chaque container ou div est ici considéré comme un flux à gérer. Ce qui permettra par la suite d'évoluer simplement vers l'ajax.
Pour bien construire sa page sans mauvaise surprise, il vaut mieux :
* charger les containers du plus petit enfant au plus grand parent
* ne faire l'output que du frameset
Par ex. :
! d'abord $page['container']['main'] et en dernier $page['container']['frameSet']
! $page['container']['main'] de Control/controlAffichage.inc.php sera jamais affiché car il se fait écraser systématiquement avant ./Vue/vueFrame.inc.php' qui passe à l'affichage à proprement parler. Que faire?

## Ajout de nouvelles fonctionnalités

On souhaiterait pouvoir gérer les communications dans plusieurs langues. Pour ce faire :
* on rajoute un modele messageList.inc.php
* on modifie un peu le contrôleur
* on crée ou modifie les composantes de la vue
1. messageList.inc.php
2. controlAffichage.inc.php devient
3. ici rien est à faire

## Application

L'application se construit ensuite par inclusion des composantes
! Il y a encore moyen d'optimiser la region[1] pour ne pas avoir à initialiser le container main avant l'inclusion et de faire de controlAffichage.inc.php un contrôleur ne comprenant aucun autre traitement que l'appel pour affichage.

## En bref

Cette façon de programmer permet de construire des applications plus souples et évolutives et ne demande pas plus de méthode que celle de choisir correctement ses variables lors de l'analyse. L'utilisation de classes permet d'optimiser plus encore le développement et faciliter l'ergonomie.
Il existe de nombreuses implémentations de MVC dans des cadriciels web écrit en PHP.

# Exemples/Webservice
## Introduction

Le langage XML se propage peu à peu dans le système d'information. Il est devenu nécessaire de connaître ce standard. Il permet de développer des applications sous plateforme JEE, .Net ou PHP et de s'affranchir des problèmes de portabilité. Les webservices sont basés sur XML, permettant de créer des composants logiciels distribués, de les utiliser indépendamment du langage d'implémentation. SOAP, WSDL, UDDI et WS-Inspection sont les technologies standard qui rendent possibles la construction et la publication de ces services.
Dans nos exemples, nous aborderons l'utilisation de SOAP. Zend propose dans son framework quelques utilitaires de la technique SOAP et REST.

### Qu'est-ce que SOAP (Simple Object Access Protocol) ?

Il s'agit d'un protocole d'échange permettant d'invoquer des applications sur différents types de réseaux, en faisant appel, à distance, à des méthodes. Il utilise différents protocoles de transport tel que HTTP mais aussi le protocole POP ou SMTP pour transmettre des données sous forme de messages.
SOAP repose sur une approche RPC (Remote Procedure Call), basée donc sur des messages dont le contenu est structuré en XML.

## Webservice PHP4
### Utilisation de la bibliothèque NuSOAP

Pour mettre en place un service web utilisant le protocole SOAP sous technologie PHP, il vous faut récupérer la bibliothèque NUSOAP sous licence GNU en PHP4. La bibliothèque a été développée par NuSphere et Dietrich Ayala. Elle permet de créer des services web basés sur SOAP 1.1, WSDL 1.1 et HTTP 1.0/1.1.
Vous pouvez la télécharger sur le site suivant: http://sourceforge.net/projects/nusoap/
L'utilisation de cette bibliothèque ne nécessite pas la mise en place d'extensions PHP spécifiques ce qui est un avantage pour la mise en place de ce système.

### Mise en place du webservice

Une fois la bibliothèque téléchargée et placée dans un sous répertoire où va se trouver votre fichier webservice, nous allons pouvoir commencer à voir comment créer votre webservice.
Vous devez créer un fichier pour votre webservice, nous allons le nommer par exemple webservice.php.
Votre webservice est créé, il vous faut maintenant ajouter des méthodes et le faire communiquer avec les différents clients.

### Création des méthodes

Nous allons voir ici comment ajouter des méthodes dans votre webservice en prenant un exemple simple. Nous allons créer une méthode qui prend en argument une chaîne de caractères et qui la renvoie.
Dans votre fichier webservice.php, à la suite du code déjà écrit, nous allons rajouter les lignes suivantes :
Nous avons vu dans cet exemple comment retourner une chaîne de caractère, un exemple assez simple. Il est aussi possible de renvoyer des tableaux grâce aux méthodes lorsqu'on souhaite extraire des éléments d'une base de données.

## Webservice PHP5

On utilise ici la bibliothèque SOAP.

### SERVER

Pour que soap soit actif, il faut décommenter extension=php_soap.dll dans php.ini

### Client
## Conclusion

Nous avons pu voir dans cet article comment développer un webservice en PHP. Comme pour les autres technologies dans lesquelles sont développés les webservices, il est possible de construire des méthodes plus complexes,avec accès aux bases de données et un véritable traitement de l'information.

## Références

* ↑ http://php.net/manual/fr/book.soap.php

# Exemples/Vérification RIO

Le relevé d'identité opérateur (en abrégé RIO) est un identifiant unique attribué à chaque contrat de téléphonie mobile en France.
Le fragment de code PHP ci-dessous permet de vérifier si celui-ci est correct.

### explications

* le champ coderio doit être renseigné avec le code RIO sans blanc.
* le champ mobile doit être renseigné avec un numéro de téléphone mobile, sans blanc.

### code
# Ajax/Sommaire
## Ajax : comment créer un sommaire
### Intérêt de l'utilisation d'Ajax

Lorsqu'on écrit un sommaire en PHP classique, à chaque fois qu'on clique sur un lien la totalité de la page est affichée. Sur un sommaire, cela crée un effet de clignotement indésirable et d'autant plus important que la page est lourde. De plus, comme il faut régénérer toute la page, la tendance est à surcharger le serveur avec des requêtes inutiles.
Avec la technologie AJAX, seule la partie qui est modifiée dans la page est rechargée. On diminue ainsi à la fois la charge du serveur, celle du réseau et l'effet de clignotement.
* Sans la technologie AJAX, on observe un effet de clignotement.
* Avec Ajax, plus de clignotement et un site plus rapide.
Remarque :
* ici on voit très peu la différence (quasiment pas d'ailleurs) car le site est super simple. Si le site était plus complexe notamment avec des accès à une base de données, la différence serait beaucoup plus nette !
* Regardez aussi la différence au niveau de l'utilisation des retours en arrière.

### Les fichiers
#### Le fichier page4.html
# Ajax/Date
## Démonstration

Le résultat est visible sur http://xavier.merrheim.free.fr/date.

## Les fichiers
### Le fichier ajax.php

Ce fichier peut contenir tout script php dont le résultat doit être mis à jour régulièrement.
Pour cet exemple :

# Exemples/MiniCMS

Les CMS ou Content Management Systems (système de gestion de contenu) sont répandus sur les toiles intra/extra(nets). Leur objectif étant d'assister la publication de contenu. L'article décrit comment en concevoir un, ajaxifié côté client et modulaire côté serveur (backend).
Définissons quelques fonctionnalités et appelons le package "myTinyCMS".
Aller au livre

# Exemples/MiniCMS/Faire un miniCMS
## Faire un miniCMS

Les CMS ou Content Management Systems sont répandus sur les toiles intra/extra(nets). Leur objectif étant d'assister la publication de contenu. L'article décrit comment en concevoir un, ajaxifié côté client et modulaire côté serveur (backend). Définissons quelques fonctionnalités et appelons le package "myTinyCMS".

### Les modules développés

Ne seront développés et intégrés que les modules nécessaires à la démonstration.
Ces modules peuvent s'organiser à desseins.
    Backend(s)manager
       Users
       Contents
       Customizations
    FrontEnds Manager
       Templates
       Controlers
    Front-Ends
       Templates

### Analyse

Les schémas suivants décrivent le déploiement des composants.
On a ici trois couches à distribuer en MVC.

### Déploiements

Les parties "clientes" et "administratives" sont séparées par simplicité. On prend un déploiement admins vs customers sur deux répertoires.
Les composantes back&front ends sont dans cette version des packages ou sous composantes. Les données étant distinctement séparées du backOffice.

### Technologies

* Les données : Xmlisation
* Le code : Php5 Object
* Dumping & archiving : mysql en soutien pour la recherche indexée et le harvesting

### Méthodologie

* RUP et patterns
* pas de frameworks (zend ou autre...) ou rapatriement total des snippets

# Exemples/MiniCMS/Développement
## Développement

* Les couches choisies
* Code de service vs Code métier
* Modélisation
* Implémentation
* Déploiement de la vue
* Ajaxification
* Intégration des gestionnaires dans un premier noyau
* Fournir les données
* Interface Homme - Machine

# Exemples/MiniCMS/Les couches choisies

* Couche de services
       Fonctionnalités
       Patterns
* Couche métier
       Orientations
       Modularités
* Couche d'accès aux données
       Connectiques
* Couche de présentation
       Modèles (Templates)
Il y aura peu de métier et beaucoup de service dans cette version, l'essentiel du travail reposant sur la modélisation, la sérialisation et la modularisation à faible granularité.
Avec l'expérience, en développant de manière modulaire, l'écriture du code se fait sans difficulté, hormis les problèmes liés aux limitations de la solution. Il faut s'efforcer de rester le moins limitatif possible (sauf développements business).

# Exemples/MiniCMS/Code de service vs Code métier

Le choix de l'orientation est déterminé par le fait de coder pour soi-même ou pour un client. À moins de devoir développer un code polyvalent au client, il est déconseillé de délivrer du code de service pour la simple et bonne raison, qu'il peut s'approprier le code et le faire devenir propriétaire.
En effet, le code de service, libéré des contraintes business, doit être "déposé et protégé", en particulier quand il propose un service considérable. Au mieux il doit être sous licence d'utilisation.

# Exemples/MiniCMS/Modélisation

La modélisation se veut simple et polyvalente.

#### Champs de données

[champs contenus]
Sous customer1/contents, les champs ou "espaces de données" sont organisés en paquets d'enregistrements. D'autres modèles sont possibles.
Distribués ou non, les paquets s'accèdent par du service pour ne pas dépendre d'un développement purement métier.
On peut opérer la distinction service / métier, en disant que le service est moins spécialisé.
La méthode d'accession aux données sera par exemple un :
* getCropById ou byScope (prendreChampParId ou parEtendue)
* getFieldNearSubject (prendreDonnéePrèsDuSujet)
L'id permettant une extraction directe de contenu.
[champs utilisateurs]
Même logique de service :
Mêmes accès que pour le modèle précédent.
[Champs page.xml]
L'indexation des pages pointeront sur des données data ou layout
[Champs templates]
La version suivante a une complétion par points d'ancrages. Cette version va orienter le projet.
L'autorisation de snippets php exécutables rendra possible l'intégration côté client (customer). L'adjonction du contenu à l'output se faisant par injection aux points d'ancrage {{inc:nomDeCle[idDeCle]}} par la méthode servant à compléter le flux avant sa sortie, comme :
* getFeedByTagName ou getPartByName ...
* incomes(header/content) à l'injection
Le contenu peut être sorti côté php ou ajaxifié comme ici par le javascript de fin de flux (frameset/content) feedContent.

# Exemples/MiniCMS/Implémentation

Nous avons besoin des fonctionnalités :
TODO
    [1] Complétion des données
       (none) Create
       (done) Read
       (done) Update
       (done) Delete
    [2] Gestion des users
    [3] Complétion du frameset via templates
       (done) injection point replacer
    [4] Un webService pour les inputs&query distants
       (none) common web services
    [5] Parser de snippet
       (do ) php snippet acter
          (none) class writer & executer
          (do ) single actions executer
    [6] Vue xhtml fonctionnelle ajaxifiée
       (done) xhtml template "nested"
NICE TO HAVE
    [1.1] Versionning sur données
       (todo) new crop creating passing current to old
Le but étant de fournir un maximum de code de service pour les héritages futur le métier n'est approché qu'en vue de personnaliser le CMS client.
Concernant l'approche modulaire :
La segmentation en composantes (classes ou scriptlets) permets un découpage net et précis des différentes parties du projets développable séparément les unes des autres. L'association au sein d'un IHM ou couche de présentation via contrôleur, venant :
* avant (pour orienter le développement)
* pendant (pour stabiliser le développement)
* après (pour finaliser le développement)
L'interface utilisatrice devant tirer parti des composantes et non l'inverse. La richesse des fonctionnalités est dégagée par le service et enclavé par un code orienté solution client. Il va donc de soi de privilégier proprement, pour enrichir ses propres librairies, de chercher le plus possible à développer ses classes et composantes plutôt que de perdre son temps en métier.
Concevoir du code de haute qualité signifie souvent d'optimiser le code vers une solution à logique 'customer' càd spécialisée, ce qui n'est pas recherché lorsque l'on doit se développer de l'expérience sur le terrain. Au possible, il faut adapté sa modularité et péricliter le service en business pour le client.
Concevoir du code modulaire permets de développer concrètement sans trop d'efforts d'analyse pour les développement XP et sur un grand délais. Il est utile d'avoir conscience de ces deux approches sur le terrain ou lorsque l'on décide d'ouvrir son code au monde. La majorité des développeur ne faisant trop souvent qu'intégrer pour l'argent ou la renommée chez le client le fruit du travail des autres.
'Classes & Fermes de fonctions' contre 'scriptlets'
Les premières sont :
* plus simple à coder,
* plus simple à utiliser,
* plus simple à entretenir,
* plus simple à spécialiser,
* plus facilement réutilisable,
* plus orienté objet,
* plus susceptible d'être récupéré.
Les secondes sont :
* plus cryptiques,
* plus optimisée pour le client,
* aisément traductible en classes et fermes,
* plus fonctionnelle,
* plus procédurales,
* plus chaotiques.
* ↑ produire un code obscure voir chaotique présente de nombreux avantages. D'autres analystes et collègues y perdront leur temps d'une part, les piping inhérents au code permettant l'implémentation, le hacking, le reroutage et la divergence fonctionnelle de script. Ce qui n'est pas sans avantages.

#### [1] Complétion des données

Pour disposer des fonctionnalités de gestion de données.
* On a besoin de Getter/Setter de données :
    - depuis la vue
    - depuis le webservice
    - depuis l'URL
* Pour les fichiers xml
Les fonctionnalités d'appels sont regroupées ci-dessous
On implémente ces fonctions utilitaires à utilities.class.php
On implémente la méthode getContentByData du dataManager
Un test du getContentByData nous rend nominal pour cette phase dans cette modélisation métier. Le refactoring du business en services serait apprécié...
    -> Sur l'input crop1.xml
    -> On a pour résultat :
Le deuxième test de get par l'id est également concluant
Son résultat étant :
On implémente à utilities.class.php les méthodes :
et à la classe dataManager.class.php
Le test suivant permet de valider la phase d'écriture :
avec le resultat

##### Liste des défauts

* searchContents / getContentByData est du code métier
    -> le transcrire en code de service
* pour la suppression, delete reste à implémenter correctement
    -> à dataManager

#### [2] Gestion des utilisateurs

La gestion des utilisateurs suivant le modèle ne demande que l'extraction de la ligne utilisateur pour recueillir ses infos.
Dans la classe utilities.class.php on rajoute ces deux méthodes :
Un test concluant de ces méthodes nous rend opérationnel pour cette phase
Résultat :

##### Liste des défauts

Cette gestion des utilisateurs ne prend actuellement que les attributs de nœuds...
    -> il serait utile de pourvoir des données supplémentaires dans le nœud user.

#### [3] Complétion du frameset

* Pour commencer nous déclarons une classe utilities.class.php qui reprendra toutes les fonctionnalités utiles pour notre solution
* La classe templateControler regroupe les fonctions sur les templates. Le contenu à publier est segmenté en flux.
* Son objectif est de :
    - reformater,
    - assembler,
    - publier.
Le test suivant permet de voir si on prend bien les ancres d'injection, par exemple, pour le nœud frameset/content
On implémente ces deux nouvelles fonctions à templateControler
Le test suivant permet de voir si on remplace bien l'ancre par son contenu :
Le contenu est bien localisé dans le template, par conséquent l'objectif de cette phase est atteint. On est opérationnel pour l'injection.
* La classe snippetActer regroupe les fonctions de computation des snippets.

##### Liste des défauts

* Les snippets actifs à la volée peuvent ralentir l'output
    -> l'ajaxification peut fournir le contenu en deux temps (données avant/après traitements)
* Cette classe reste à faire...

#### [4] Un webservice

Le [[../../webService|webService]] propose par défaut une synergie avec d'autres solutions, sites, applications. Des fonctionnalités distantes permettent l'interfaçage logicielle avec le serveur de données, option qui deviendra basique pour les systèmes orientés données.

##### Liste des défauts
# Exemples/MiniCMS/Déploiement de la vue
### Le frontOffice

Le front office est orienté ajax.

### Le backOffice

* Config.inc.php
* main.php
    point d'entrée back&front end
    un switch distingue les appels entrants avec et sans paramètres
* responder.inc.php
    appels entrant avec interrogation
* entry.inc.php
    appels entrant sans interrogation

# Exemples/MiniCMS/Ajaxification

L'ajaxification à implémenter côté serveur et client permet une plus grande souplesse d'interaction entre la vue et le backend. Le séquencement du contenu en flux offre une plus grande réactivité.
Pour ce faire :
Dans le template des owners, on implémente la couche AJAX suivante, "topScript" nourrit le début de document et "bottomScript" l'exécution de fin de document.
On teste sur un segment du body. Par convention, le container à nourrir porte l'id composé "id:idDuContainer".
Un test sur la page "standard" donne en output pour l'appel ajax :
=> le résultat suivant
On est nominal pour l'ajaxification de la complétion du contenu côté client.

#### Implémentation des contrôleurs côté serveur

* Common.inc.php :
* Responder.inc.php :

#### Auto complétion du layout

On implémente feedLayout pour auto compléter et chercher les fragments sur le template pour l'injecter sur les encres

#### Test de réactivité de la couche ajax

La fonction feedContent se charge de charger les flux sur la page en provenance du template et des champs de données.
Le template étant :
et le crop 1.xml :
On a pour rendu en sortie :

# Exemples/MiniCMS/Premier noyau

Nous préparons la première version de notre solution myTinyCMS. Comme nous sommes nominal pour les quatre phases, myTinyCMS permets :
    [1] De gérer les données
    [2] De gérer les utilisateurs
    [3] De gérer un frameset complexe
    [4] D'effectuer des mouvements par son webservice
La première intégration ou version 1 de notre noyau consistera en des contrôleurs de test préfigurant la première beta de myTinyCMS.
L'objectif de ce contrôleur est d'intégrer le frameset sur trois thèmes :
    [1] authentification
    [2] lecture / écriture contenu
    [3] navigation
    [4] gestion de contenu
Le contenu sera géré directement sur le frameset par défaut. Backoffice et Frontoffice étant distingué par le switch Mod!Adm vs Usr, déverrouillant les contrôles de gestion et d'encodage.
Fonctionnellement le noyau présente deux phase d'affichage :
    La première serveur vers client (output total du frameset)
    La seconde cliente appelant l'injection dans les containers

## Le Second noyau

MyTinyCMS est maintenant un mini content manager system orienté wiki. L'orientation du CMS génère le code métier suivant

### Classes

Classes/contentPane.class.php regroupe les flux d'entrée et sortie comme les menus. Il est spécialisé pour notre solution. Le code peut être amélioré.
Voici Classes/dataManager.class.php dans sa version finale. Il est orienté données.
Voici le Classes/templateControler.class.php orienté layout.
Classes/utilities.class.php dans sa version finale

### Functions

Functions/common.inc.php dans sa version finale

### Backend

Le backend est implémenter suivant quelques règles métier imposées par l'orientation du CMS également.
Objects/Backend/authorize.inc.php
Objects/Backend/responder.inc.php dans sa version finale
Objects/Backend/services.inc.php
Objects/Backend/webservices.inc.php

### FrontEnd

Deux points d'entrées : Objects/Frontend/admin.inc.php
Objects/Frontend/entry.inc.php dans sa version finale

## Le Troisieme noyau

MyTinyCMS est ici un CMS orienté données et frontEnd. Avec le frontOffice ajaxifié présenté dans la rubrique relatif à la vue, il permet la création de sites customer directement dans moyennant quelques connaissances en html.
L'applicabilité des modules ayant été démontrée. Cette solution est achevée ici mais peut être augmentée ou améliorée.
myTinyCMS est sous licence GNU copyLeft et utilisable. Si vous implémentez la solution, laissez votre copyright ou alias derrière le mien.
Le copy étant

## Télécharger

MyTinyCMS est nominal... Il peut être telechargé ici

# Exemples/MiniCMS/Fournir les données

Pour la vue, les données sont extraites des champs et ensuite injectées aux points d'ancrages désignés sur les templates. Un des objectifs étant de bien synchroniser l'injection serveur avec les sorties clientes en mini flux sur les containers de la vue xhtml. La complétion des données étant sélective.

# Exemples/MiniCMS/IHM

L'Interface Homme - Machine consistera à fournir à l'utilisateur des options d'encodage et d'identification dans la vue.
Le découpage modulaire dégage la solution des itérations avenir dans l'ajout de nouvelles fonctions.
Deux points d'entrées permettent de découpler
* Site web : http://localhost:888/miniCMS/main.php
* CMS : http://localhost:888/miniCMS/main.php?usr=log
Ce dernier proposant l'authentification.
L'intégrateur pourra créer une interface d'administration à loisir sur cette adresse ou modifier le point d'entrée, en supprimant ou modifiant les paramètres ou en passant les données par POST plutôt que dans l'URL...
Cette partie ne sera pas détaillée dans cet exemple, seule l'interaction avec l'encodeur sera vu.
Le point d'entrée du site devra faire la distinction entre les sous sites ou sous domaines.

# Exemples/MiniCMS/Rétrospective

Si l'envie vous prend d'intégrer ce CMS, c'est à dire de le coder localement chez vous ou de l'adapter à votre environnement ou solution. Je vous conseille de toujours travailler avec l'API approprié, c'est à dire ici : php.net. Cette solution est suffisamment légère pour pouvoir être traduite à loisir en Ruby, Java, Python ou autre.
L'inconvénient majeur actuel étant que l'utilisateur ou le webmaster qui l'utilisera devra avoir des notions d'HTML, la vue ajaxifiée étant ouverte pour une saisie directe au plus au niveau, càd la vue elle même offrant le rendu de ce qui va être encodé.
Les différentes couches ou composantes sous forme de scripts, snippets, classes, functions peuvent être revues, surchargés, améliorées ou étendues. Celles-ci devenant des incréments que vous jugerez utiles de placer à la suite dans ces pages.

# Exemples/MiniCMS/Conclusion

Développer un collectionneur et publicateur de données comme typo3 ou joomla est plus une affaire d'organisation modulaire que d'approche en terme de service à fournir. Ce dernier n'étant que la collecte et la diffusion, avec quelques options quant au versionning et la mise à jour du contenu. Les règles sont simples, mais à développer...