Vous êtes sur la page 1sur 47

 5/2009

 1/2011
Table des matières

www.phpsolmag.org 
1/2011

Le périodique phpsolutions est publié par


Table des matières
Software Press Sp. z o.o. SK
Bokserska 1, 02-682 Varsovie, Pologne
Tél. 0975180358, Fax. +48 22 244 24 59

VARIA
www.phpsolmag.org

Président de Software Press Sp. z o.o. SK : 7 Actualités


Paweł Marciniak Actualités du monde du développement.
Christophe Villeneuve
Directrice de la publication :
Ewa Łozowicka

Dépôt légal :
OUTILS
à parution 8 Comment réussir son projet CRM
ISSN : 1731-4593 Frédéric de ConseilsMarketing.fr
En mettant en place un logiciel de CRM, vous allez faire
Rédacteur en chef : la même chose que votre commerçant préféré, mais de
Łukasz Bartoszewicz
manière automatisée et structurée. Pour vous accom-
pagner dans cette démarche, nous allons vous présen-
Couverture : ter les 6 règles d’or pour réussir un projet de CRM, le
Sławomir Sobczyk
planning prévisionnel pour ne négliger aucune étape
DTP : clé et enfin les 17 erreurs à éviter pour que la mise en
Sławomir Sobczyk Studio2W@gmail.com
place de votre logiciel ne se transforme en cauchemar.
Composition :
Sławomir Sobczyk

Correction :
PROJETS
Valérie Viel, Thierry Borel, Barbara Bourdelles
16 Définition d’une base de données avec
l’ORM Doctrine dans un projet Symfony
Bêta-testeurs : Tlili Belgacem
Brice Favre, Valérie Viel, Cyril David,
Christophe Milhau, Alain Ribault, Stéphane Guedon, L’utilisation de la programmation Orientée Objet est
Eric Boulet, Mickael Puyfages, Christian Hernoux, une priorité pour un développeur, mais ce point n’est
Isabelle Lupi, Antoine Beluze, Timotée Neullas,
Yann Faure, Adrien Mogenet, Jean-François Montgaillard,
plus aussi exact qu’avec l’utilisation des frameworks de
Turmeau Nicolas, Jonathan Marois, Wilfried Ceron, mapping Objet / Relationnel (ORM). Depuis la sortie de
Wajih Letaief, François Van de Weerdt, Eric Vincent, PHP5, plusieurs frameworks ont été développés, per-
Franck Michaël Assi, Francis Hulin-Hubard,
Nicolas Dumas, David Michaud. mettant le développement des grandes applications en
respectant les normes de programmation Objet.
Les personnes intéressées par la coopération
sont priées de nous contacter :
editor@phpsolmag.org
DOSSIER
20 Acquérir de la vitesse avec
Publicité :
publicite@software.com.pl Zend Framework – part III
Stéphane Guédon
Après une interruption de quelques mois, Stéphane
Pour créer les diagrammes on a utilisé le programme
Guédon reprend le cours des articles visant à améliorer
l’usage que nous faisons des diffé-
rents composants du Zend Fra-
mework. Dans cet article il
AVERTISSEMENT vous présentera les com-
Les techniques présentées dans les articles
ne peuvent être utilisées qu’au sein des réseaux posants Zen_Cache ma-
internes. La rédaction du magazine n’est pas is aussi, plus largement,
responsable de l’utilisation incorrecte des techniques
présentées. L’utilisation des techniques présentées peut la notion de politique de
provoquer la perte des données ! cache.

 1/2011
Extension ZIP pour PHP

Table des matières

1 9/2010
Table des matières

PRATIQUE
26 Développer un centre d’appel avec
Asterisk et VtigerCRM – deuxième partie
Randriamifidy Bezama Marolahy
Dans ce second article de notre série, nous allons par-
ler du VtigerCRM. En premier lieu, vTiger CRM est
une application intégrée de gestion de la relation client
(CRM), aisément utilisable en Intranet ou depuis Inter-
net grâce à un simple navigateur. Intégralement distri-
buée sous licence libre (LGPL depuis la version 5), la
solution vTiger CRM est principalement destinée aux
PME/PMI opérant en mode BtoB.

FICHE TECHNIQUE
30 Guide de conception de formulaires
en HTML avec traitement PHP, ergonomie,
accessibilité
Matthieu Lacroix
Le formulaire est un moyen de faire interagir le visiteur
sur votre site. Moteur de recherche, espace de contact
ou encore forum de discussion, nombreuses sont ses
applications. Vous verrez comment les concevoir et les
traiter.

POUR LES DÉBUTANTS


36 SQL : extraire des données
Cilia Mauro, Magali Contensin
Les bases de données sont très utilisées dans les ap-
plications Web. La création, l’interrogation et la manipu-
lation des données de la base sont réalisées en SQL.
Dans cet article, vous apprendrez à extraire des don-
nées d’une table et à les trier avec SQL.

41 SQL : les jointures


Cilia Mauro, Magali Contensin
Dans les articles précédents vous avez appris les ba-
ses du langage SQL. Vous êtes capables de réaliser
des bases de données simples, d’y insérer des don-
nées et de les interroger. Dans l’article précédent, vous
avez vu comment extraire des données d’une table.
Cet article explique comment interroger plusieurs tab-
les en même temps.

 1/2011
Actualités

Informations autour Calendrier de l’avent 2010

de PHP 5.2.x
Chris Shiflett publie le calendrier de
l’Avent PHP, avec des astuces d’experts
PHP pour tout le monde. Chaque jour,
Ce mois de décembre est un mois important pour PHP et aussi un nouveau du 1er décembre jusqu’au 24, vous
tournant pour ce langage, c’est à dire : découvrirez une nouvelle astuce.
Le 1er point concerne la mise à disposition de la nouvelle version PHP http://phpadvent.org/2010
5.2.16 qui remplace la version 5.2.15, sortie quelques jours avant. Cette PHP 5.3.4
version corrige une régression dans la mise en oeuvre de la fonction open_ La nouvelle version de PHP 5.3.4 vient
basedir introduite avec la version précédente. Par ailleurs, un correctif im- de sortie. Elle n’apporte pas de nouvel-
les fonctions, mais seulement quelques
portant pour PDO::pgsql a été ajouté. évolutions de certaines fonctionnalités
Le 2ème point concerne la fin du support de la branche PHP 5.2. Ainsi vous comme le choix de l’encodage pour
n’aurez plus de nouvelles versions mineures corrigeant de nouveaux bugs get_html_translation_table.
Bien sur, certains correctifs ont été en
éventuels.
même temps déployés. C’est pourquoi
Le 3ème point est par conséquent la suite logique des 2 premiers points il est important d’effectuer la migration.
présentés ci-dessus, et conseillés par la Team de PHP. Il s’agit de la migra- http://www.php.net
tion de PHP 5.2 vers PHP 5.3. Xdebug Togger
Pour effectuer la migration vers PHP 5.3, un guide détaillé est disponible sur xDebug Togger est une nouvelle bar-
le site de PHP.net (http://php.net/migration53) pour vous permettre de réali- re pour le navigateur Safari. Celle-ci
ser l’opération. Ce guide parle de nombreux sujets qui vont vous intéresser va vous aider à déboguer vos appli-
cations PHP, comme cela existe pour
pour exploiter au mieux celle-ci, qui comprend : les nouvelles fonctionnali- les autres navigateurs. Bien entendu,
tés, les nouveaux paramètres, les nouveaux filtres, les nouvelles méthodes, vous bénéficiez des fonctionnalités
les expressions retirées, les nouvelles classes, etc... Xdebug..
http://www.php.net https://github.com/benmatselby/xde-
bug-toggler

phpPgAdmin
WePloy
WePloy est un outil de déploiement,
utilisé par la société WePlay. Celui-ci
phpPgAdmin est une ap- est réalisé en PHP et publié par Ra-
plication web réalisée en smus Lerdorf. Cet outil peut être utilisé
langage PHP destinée pour déployer n’importe quel type de
projet PHP.
à faciliter la gestion du Un communiqué est disponible pour
SGDB PostgreSQL. montrer son installation et sa configu-
La version 5.0 vient de ration.
sortir et il s’agit d’une http://dev.wepay.com/blog/2010/11/30/
weploy-wepays-deployment-tool/
version majeure et com-
Posh 3.0
patible pour PHP 5.0 et La nouvelle version de Posh 3.0 vient
plus, pour PostgreSQL de sortir. Elle propose de nouveaux
7.4 minimum. connecteurs pour vous permettre
d’obtenir plus d’informations à partir
Elle propose de nombreux correctifs de bugs et de nouvelles fonctionnalités, de CMS (Typo 3), de Forum (phpBB),
comme : mais aussi de sites actualités (Google
• La compatibilité avec les versions de PostgreSQL 8.4 et 9.x. News).
• Nouveau schéma de l'export. En plus, d’autres points importants
ont été incorporés : compatilité avec
• Amélioration de l'interface. les smarphones, refonte de l’interfa-
• Application graphique amélioree. ce, apparition d’un menu intelligent,
• Ajout de nouveaux thèmes. etc ...
• De nombreuses traductions disponibles (comme le Français). http://www.portaneo.org/portal/index.
php#tab/1
• Prise en charge multi-domaine FK.
• Etc. Magix cjquery
Magix cjquery vient de publier la no-
uvelle version. Cette librairie est ma-
Par ailleurs, de nouvelles langues ont été ajoutés (Tchèque, Grec, Brésilien intenant compatible avec PHP 5.3. Par
Portugais, Galicien) ailleurs, celle-ci apporte aussi quelqu-
http://www.postgresql.org es correctifs et une évolution de la
documentation. Cette version est plus
souple, plus simple et la récupération
Rédaction des actualités : des erreurs est plus précise.
Christophe Villeneuve http://magix-cjquery.com

www.phpsolmag.org 
Outils

Comment
réussir son projet CRM
Pour agir efficacement sur ces 3 facteurs il est incontournable
de mettre en place une solution de CRM. Si cet acronyme anglais
pour Customer Relationship Management (ou Gestion de
la Relation Client) fait encore peur à de nombreuses entreprises,
et pour certains reste synonyme d’usine à gaz, le principe est
pourtant simple.

Cet article explique : Ce qu’il faut savoir :


• Cet article sur le CRM va vous donner toutes les clés pour réus- • Aucun prérequis.
sir la mise en place de votre solution de CRM.
• Nous allons nous concentrer sur les principes fondamentaux :
• Vos clients car c’est grâce à eux qui nait votre chiffre d’affaires,
le carburant qui fait tourner votre entreprise.
• Vos prospects, car en période de crise plus que jamais vous ne
pouvez plus vous permettre de laisser passer une affaire.

D
’ailleurs votre boucher du coin de la rue fait tous quelque soit l'éditeur de logiciel sélectionné. La mise
les jours du CRM sans le savoir lorsque vous en place d’une solution CRM est souvent initiée par
passer le voir : une volonté d’améliorer un des éléments de la relation
clients d’une entreprise :
• il vous reconnaît et vous appelle par votre nom,
• il vous propose votre plat préféré, ses fameuses cô- • Assurer un meilleur suivi du travail de ses commer-
tes d'agneaux bien fines comme d’habitude, ciaux.
• il vous demande comment vont les enfants, • Simplifier les processus et traitements internes.
• il vous rajoute quelque grammes de viande en • Faciliter le partage d'informations et la communica-
plus car vous êtes un bon client (avec un petit clin tion.
d'œil), • Faire de la prise de commandes directement chez
• il vous propose de goûter son pâté en croute fait les clients.
maison car il est sûr qu'il va vous plaire, • Proposer un extranet client pour gérer les deman-
• … des SAV.
• Mettre en place des chaînes de fidélisation sur sa
En mettant en place un logiciel de CRM, vous allez base clients.
faire la même chose que votre commerçant préféré, • Obtenir une meilleure gestion de son SAV.
mais de manière automatisée et structurée. Pour vous
accompagner dans cette démarche, nous allons vous Dès lors, naît le projet CRM.
présenter les 6 règles d'or pour réussir un projet de Pourtant, très vite le chef d’entreprise, le responsable
CRM, le planning prévisionnel pour ne négliger aucune commercial, le responsable information… à l’origine du
étape clé et enfin les 17 erreurs à éviter pour que la projet se rend compte que pour appliquer cette nouvel-
mise en place de votre logiciel ne se transforme pas le stratégie, il faudra repenser l’organisation actuelle et
en cauchemar. parfois, revoir profondément la façon de travailler des
Nous resterons volontairement totalement agnostique collaborateurs.
sur la solution de CRM à adapter, car la méthodologie Or, toucher à l’organisation commerciale ou techni-
de mise en place du logiciel de CRM restera identique que de l’entreprise, c’est toucher à un élément sensible

 1/2011
CRM

et crucial de son activité, ce qui va plus loin que la simple Pourtant, ce n’est pas aussi si simple que cela en
mise en place d’un logiciel. La mise en place du CRM a l’air : comme nous l’avons précisé en introduction,
changera des habitudes qui sont parfois solidement an- un projet de CRM touche les processus de l’entrepri-
crées… Nous verrons d’ailleurs dans ce dossier que la se et modifie la manière de travailler des utilisateurs.
résistance au changement est l’un des défis majeurs des De plus, les populations touchées sont souvent les
projets de CRM. commerciaux et le service technique qui sont, par
Pourtant, lorsqu’un projet CRM se concrétise, il se nature, des „électrons libres” peu habitués à la rigu-
transforme souvent en un véritable outil de création eur et qui appliquent une organisation qui leur est
de valeur ajoutée en offrant de nouveaux services aux propre.
clients, en donnant plus de productivité aux commer- En effet, au contraire des comptables, des person-
ciaux, en améliorant la satisfaction clients… nes de la production… il est parfois difficile d’obliger
Au niveau de la mise en place d’une solution de CRM, un commercial à utiliser un logiciel dont il ne voit pas
il existe deux grandes typologies de projets. Le projet immédiatement les bénéfices et l’intérêt. La gestion
de CRM Simple, qui se retrouve dans les petites struc- du changement et l’adhésion des équipes est donc
tures, avec peu de personnels à équiper et peu d’inte- le défi majeur à relever dans la mise en place d’une
ractions entre les différents services (ex : pourvoir une solution de CRM. Pour le relever avec succès, il est
petite équipe commerciale de 2 ou 3 personnes séden- indispensable de suivre les 6 règles d’or décrites ci-
taires). Dans ce cas, le projet touche relativement peu dessous.
de personnes, l’enjeu majeur sera de comprendre les
besoins de cette équipe et d’y adapter l’outil tout en op- Intégrer le projet de CRM dans la stratégie
timisant leur activité. de l’entreprise
Le projet CRM Evolué, qui se retrouve dans les plus Le CRM est l’outil qui permettra d’appliquer la stratégie
grandes entreprises et dans le cas où la solution de de l’entreprise : il est le bras armé de la stratégie. C’est
CRM influe plusieurs services de l’entreprise (ex : mi- pourquoi, avant de choisir le bon outil, il faut d’abord
se en place d’un logiciel pour une équipe commerciale savoir où vous voulez aller et ce que vous souhaitez
nomade et sédentaire avec liaison à l’ERP avec, en faire.
plus, l’installation d’un outil pour structurer l’activité du Pour cela, il faut faire un diagnostic:
Service SAV). Dans ce cas, le projet de CRM sera bien
plus délicat à gérer et nécessitera un suivi précis et ri- • Quel est mon métier ? Quels secteurs ou services
goureux. En effet, non seulement il faudra prendre en je veux développer ? Où est-ce que je souhaite dé-
compte la dimension technique, mais en plus (et sur- velopper mon activité ? Comment évoluera mon
tout !) il ne faudra pas négliger la dimension humaine. secteur d’activité ? Que dois-je faire pour me diffé-
Cela passera, entre autres, par la prise en compte des rencier de mes concurrents …
besoins réels des opérationnels, la vérification que • Comment vais-je réussir à atteindre ces objectifs ?
l’outil pourra gérer correctement ces besoins métier Que doivent faire mes salariés pour atteindre mes
et le suivi de la mise en place de la nouvelle organi- objectifs ? Quels seront leurs futurs besoins ? Est-
sation. C’est pourquoi nous vous présenterons ici les ce que je suis équipé, dans ce but, en hommes, en
6 règles d’or à respecter pour réussir son projet CRM, matériel… ?
qu’il soit simple ou évolué ainsi que les 17 erreurs à ne
pas commettre, puis un planning prévisionnel avec les C’est uniquement après avoir fait ce diagnostic que le
grandes étapes à respecter. projet CRM peut démarrer. En effet, mettre en place
Au niveau opérationnel, la distinction entre un Projet un CRM doit être le bras armé de la stratégie, et non
Simple et Evolué se fera par une plus grande souples- le contraire. Le CRM n’est qu’un outil qui doit répon-
se et moins de formalisme, mais il n’en demeurera pas dre à un besoin. C’est lors de cette étape que la di-
moins indispensable de suivre toutes les 6 règles d’or rection validera le projet et le contenu du projet de
car même un petit projet de CRM risque d’échouer en CRM.
cas de sous-estimation du travail technique et humain De plus, en ayant défini où nous voulons aller, il sera
à accomplir. bien plus facile de définir le périmètre du CRM, ce qu’il
doit faire en priorité et ce qu’il n’est pas nécessaire qu’il
Les 6 règles d’or à respecter pour qu’un projet fasse dans un premier temps. Un document de cadrage
de CRM soit un succès ! doit absolument être rédigé. Le formalisme et l’écriture
Pour tous ceux qui ont déjà installé un logiciel de comp- des informations sont indispensables à la réussite d’un
tabilité ou de gestion, ou un nouvel OS, mettre en place projet de CRM car, d’une part, cela permet de valider
un logiciel de CRM semble probablement très simple : ce qui doit être fait (évitant ainsi les malentendus) et,
il suffit d’installer le logiciel, de former les employés, d’autre part, cela engage les personnes sur ce qui doit
et c’est fini… être fait.

www.phpsolmag.org 
Outils

Ce document de cadrage : Vous devez donc définir clairement à tous les acteurs
concernés par le CRM les buts et objectifs de ce pro-
• Définira le périmètre de l’application : utilisation uni- jet pour éviter les incompréhensions et mettre en avant
quement par les commerciaux ou aussi par d’autres les bénéfices et les avantages apportés par cette solu-
services (marketing, SAV, comptabilité…). tion. La rengaine On fait comme ça depuis toujours, et
• Structurera le projet : qui, quoi, où, pourquoi, com- ça marche…, On a toujours eu l’habitude de faire cela
ment (planification, répartition claire des rôles de comme ça…, encore une usine à gaz qui va nous em-
chacun et attribution d’un budget). pêcher de travailler… sont les réactions typiques aux-
• Proposera (éventuellement) une stratégie de dé- quelles vous faites face quand vous proposez un chan-
ploiement en phases pour une conduite du chan- gement en entreprise.
gement optimale (ne pas tout changer radicalement Attendez-vous donc à devoir passer quasiment
et d’un seul coup !). autant de temps à convaincre de l’intérêt du CRM
• Intègrera des actions de communication fortes pour qu’à mettre en place l’application ! Vous vous ren-
faire adopter le changement : réunions de lance- drez vite compte que changer des habitudes néces-
ment, mise en avant des avantages pour les sala- site patience et capacité à convaincre. En effet, la
riés. résistance au changement est l’écueil majeur des
projets CRM : la mauvaise appréciation et la sous-
Important : ce document n’est pas figé dans le temps. estimation des changements entraînés par le logi-
Il est encore une fois indispensable de le faire vivre ciel de CRM est la première cause d’échec. Car il ne
et évoluer au cours du projet et de le mettre à dispo- faut pas s’y tromper : un logiciel de CRM imposera
sition de tous les acteurs du projet à chaque nouvelle une plus grande rigueur et changera la vie des utili-
version. Le document de cadrage doit être la Bible du sateurs.
projet et comprendre de manière exhaustive ce qui doit Avec le CRM, les collaborateurs devront appren-
être mis en place. Ce document doit être présenté au dre à privilégier l’écrit à l’oral, ce qui requerra une
prestataire information, et il servira de base pour définir amélioration qualitative et quantitative de saisie des
par écrit ce qui sera exactement réalisé. Ce document données … afin qu’en contrepartie, ces informations
ne devra pas laisser de place au doute ou aux approxi- soient utilisables par tous les services de l’entreprise.
mations : il devra précisément indiquer ce que veut l’en- Au niveau opérationnel, vous vous rendrez compte
treprise (une fonction ne doit pas être expliquée par une que les changements susceptibles de vous sembler
simple phrase, mais avec une description détaillée et il- mineurs peuvent entraîner une résistance importante
lustrée). au changement … Par exemple, imposer l’enregis-
Il ne faut surtout pas oublier, dans cette réflexion, que trement dans le logiciel de tous les appels entrants,
le CRM nécessitera sans doute une évolution de l’en- les rendez-vous… ennuiera plus d’un commercial qui
treprise au niveau : trouvera toutes les excuses du monde pour ne pas
le faire !
• Culturel (évolution des mentalités) : il ne s’agit plus C’est pourquoi, pour obtenir l’adoption du projet CRM,
de travailler seul dans son coin mais avec le CRM, il faut toujours mettre en avant au moins un bénéfice
les informations seront échangées entre collègues concret pour les utilisateurs :
et services (il faut donc définir ce qui sera écrit,
les „normes” d’écriture…), l’informatique sera utili- • pour un commercial, avoir des alertes pour relan-
sé pour automatiser certaines tâches (il faut donc cer automatiquement les clients dont la décision
voir ce qui peut être automatisé dans les proces- d’achat est proche, identifier les clients inactifs de-
sus, remettre en cause ce qui se faisait aupara- puis X jours, personnaliser les e-mailings de l’entre-
vant…). prise avec leurs coordonnées, obtenir des fiches de
• Organisationnel : revoir des manières de penser prospection avec des coordonnées automatique-
et de travailler parfois archaïques, remplacer les ment pré-saisies ou pré-qualifiées grâce à un for-
processus écrits et les validations par des traite- mulaire rempli sur internet…
ments informatiques… • Pour le marketing, c’est pouvoir vérifier l’efficacité
des actions marketing, obtenir des remontées ter-
Lutter contre la résistance au changement rains plus rapides et plus concrètes (obtenir des
C’est l’ennemi N°1 de tout projet de CRM… Trop sou- photos des produits concurrents…), communiquer
vent, l’outil de CRM est perçu comme le nouveau „jou- plus rapidement vers les commerciaux (fiches pro-
jou” de la direction pour contrôler l’activité des salariés duits, publicités…).
ou obtenir des tableaux de bord… et non comme une • Pour le service technique, c’est avoir une base de
aide dans l’atteinte des objectifs des autres salariés de connaissances utilisable en interne, mais aussi en
l’entreprise. externe (FAQ)…

10 1/2011
CRM

En plus des bénéfices apportés par l’outil CRM, il est res. En effet, la récupération des données est rarement
souvent important d'apporter un plus aux populations intégrale, et il faut savoir accepter une perte minimale
qui utiliseront l’application : d’informations (ex : pas d’historique des visites de plus
de 2 ans…).
• Offrir un nouvel ordinateur pour utiliser le logiciel. Plus vous souhaitez récupérer des informations, plus
• Donner un nouveau Smartphone avec GPS qui per- le coût sera élevé (et ce n’est pas proportionnel : les
met en plus de consulter le CRM. 20% restant de l’information à récupérer peuvent faire
• Mettre en place une prime qualitative sur la saisie gonfler de 80% le coût de la récupération des données
d'informations dans le CRM. à cause d’une saisie semi-automatique et manuelle).
C’est pourquoi si vous possédez un logiciel de comp-
Analyser la situation actuelle et analyser ta / gestion, il ne faudra pas hésiter à contacter votre
son évolution avec la solution de CRM éditeur pour savoir quels sont les ponts proposés avec
La solution de CRM ne doit pas être considérée comme les logiciels de CRM du marché, ou éventuellement s’il
une brique de plus du système d’information, mais com- n’en propose pas.
me un ciment qui relie toutes les informations conte- Rappelez-vous aussi du principe Garbage In / Gar-
nues dans les différents logiciels de l’entreprise. Pour bage Out, c’est-à-dire que si les données à l’origine
que l’intégration se passe au mieux, il faut préférer le sont mauvaises, alors les données que vous obtiendrez
bien au mieux : c’est-à-dire commencer en douceur dans le CRM seront mauvaises…
en mettant en place le logiciel de CRM là où il est le C’est pourquoi, souvent un projet de CRM passe par
plus utile (ex: pour gérer le SAV), et ensuite intégrer une phase d’analyse des données existantes, avec un
les autres pans de l’activité de l’entreprise, une fois que choix de remettre à plat les données ou d’une reprise
cette première intégration sera digérée et assimilée. partielle, voire d’une re-qualification des informations
Il faut que le CRM donne le plus rapidement des résul- pour repartir d’une base saine.
tats concrets et tangibles incitant les utilisateurs à pen- Il est important de s’assurer que le CRM utilise une
ser que cette application est bien conçue pour leur faire base de données saine afin de ne pas remettre en
gagner du temps. Il y a lieu d’identifier en priorité où l’or- question non pas l’outil, mais ce qu’il produit comme
ganisation est perfectible et montrer que le CRM per- information.
met d’améliorer la situation. Dans le même ordre d’idée, Enfin, pour réduire les coûts de votre projet, choi-
la tentation est de demander aux opérationnels d’entrer sissez absolument une solution qui est en standard
plus d’informations, car en théorie, tout peut être fait proche de vos besoins. Évitez un maximum la person-
avec un CRM. nalisation et le développement sur mesure. C’est non
Or, si trop d’informations tuent l’information, trop d’in- seulement un coût supplémentaire, mais surtout des
formations tuent à coup sûr un projet CRM. Donc, lors évolutions difficiles à prévoir dans les années suivan-
de la phase de mise en place, il faut absolument de- tes (évolution des besoins, des systèmes…).
mander aux opérationnels de remplir le minimum de
données dans le système, et d’enrichir au fur et à me- Donner des informations utiles
sure les fiches afin de s’assurer que seules les informa- aux utilisateurs
tions strictement nécessaires sont entrées. Cela peut sembler une évidence, mais de nombreux
Vouloir imposer un changement radical dans toute projets CRM sont mis en place par la direction sans
l’entreprise du jour au lendemain est le plus grand fac- donner la parole aux véritables utilisateurs de la solu-
teur d’échec. C’est pourquoi dans cette phase, il est im- tion…
portant d’identifier où les informations sont disponibles Il faut donc faire une étude des besoins auprès des
ou créées, pour savoir ensuite comment / où / par qui commerciaux, techniciens, équipes marketing… et sa-
elles seront intégrées, et comment les processus peu- voir ce dont ils ont vraiment besoin, ce qu’il faudrait
vent être simplifiés ou automatisés. améliorer. Néanmoins, faites attention au syndrome
Suite à ce premier audit de l’organisation, il faut alors j’aimerais bien qu’il fasse aussi… qui apporte des fonc-
passer à l’analyse de ce qui peut être récupéré dans la tions qui ne seront au final pas forcément utilisées et qui
solution de CRM. Par exemple, les données comptables sont plus du domaine du rêve…
sont dans le logiciel de gestion, les plannings peuvent Un bon début est d’analyser l’utilisation du logiciel
être gérés dans MS Outlook, les informations techni- actuel et de ses limites (par une observation sur le ter-
ques dans une base de connaissances sous MS Excel, rain), et son inadéquation avec la stratégie de l’entre-
les fiches de visites dans des fiches papier… Tout ces prise.
silos d’informations doivent être inter-connectés par le Pour cela, vous devez impliquer les opérationnels
logiciel de CRM. dans la réflexion. Un des clés de votre succès sera d’in-
Ceci fait, vous devez distinguer les informations in- clure dans le projet les employés qui sont connus et re-
dispensables à l’entreprise de celles qui sont accessoi- connus dans la structure (les anciens ou ceux qui ont

www.phpsolmag.org 11
Outils

une très bonne connaissance des processus formels se, qui aura occupé plusieurs fonctions, qui est res-
et informels de l’entreprise). pecté… et qui est favorable au projet ! A défaut, le
Il est essentiel de prendre le temps de la réflexion et de responsable commercial ou marketing mais évitez,
l’analyse des besoins. Avant de commencer à consul- dans la mesure du possible, le responsable infor-
ter les éditeurs de logiciels, il faut réfléchir à son projet, matique qui a une vue technologique et moins «be-
analyser l’existant, les améliorations à apporter. Tout le soins utilisateurs». Le chef de projet sera le lien
temps passé à réfléchir en amont, c’est au minimum 2 à entre l’entreprise et le prestataire. Vous devrez lui
3 fois plus de temps économisé lors de la mise en place confier un «ordre de mission» écrit avec le cadre du
du projet (et donc des coûts en moins). projet, le budget, le planning prévisionnel… le tout
Pour l’analyse de la situation de l’entreprise, vous devant être négocié avant le début du projet.
pouvez vous inspirer de la Méthode Lean initiée chez • un groupe de réflexion : ce comité rassemble des
les constructeurs automobiles Japonais comme Toyo- opérationnels (pas forcément des managers, bien
ta (voir http://fr.wikipedia.org/wiki/Lean). Les principes au contraire !) qui seront impliqués dans le projet de
fondateurs de la méthode Lean sont la recherche de CRM et qui feront en sorte que le projet convienne
la performance par l’amélioration continue, l’élimination bien à la réalité du terrain.
des gaspillages et l’optimisation des processus inutiles • un membre du comité de direction qui pourra pren-
qui alourdissent l’entreprise. Cette méthode passe par dre les décisions, faire avancer le projet en cas de
une impulsion des opérationnels, et non pas celle de la blocage et montrer l’implication de la direction dans
direction. le projet (NB : le projet devra être lancé officielle-
Une fois que vous savez où vous devez aller, il faut ment et annoncé comme un des objectifs prioritai-
lister les nouvelles données et les nouveaux processus res de l’année sans que son importance puisse être
à mettre en place et vous assurer qu’ils seront accep- remise en cause).
tés. En particulier, ces changements ne doivent pas en-
traver et alourdir le travail de vos salariés, ou alors ap- Tous doivent être responsables de la mise en place du
porter un bénéfice concret qu’il faudra expliquer. projet, être clairement nommés et obtenir du temps
N’oubliez pas que les effets liés au logiciel de CRM dans leur agenda pour traiter ce projet.
n’entraîneront pas forcément des gains immédiats vi- Des réunions et points doivent être programmés en
sibles pour tout le monde… Pour éviter la désaffection avance (par exemple, toutes les 2 semaines) et il fau-
et le faible taux d’adoption, il faudra communiquer, re- dra faire la chasse à l’absentéisme. Toutes les réunions
communiquer et encore re-re-communiquer sur l’inté- auront un objectif et un ordre du jour, avec une liste
rêt du projet… et surtout, formaliser les nouveaux pro- des tâches à effectuer par personne et des dates limites
cessus via un cahier des procédures qui deviendra la pour accomplir le travail. Le chef de projet veillera à la
référence. Encore une fois, il faudra privilégier l’écrit bonne réalisation du travail par un point (physique, par
à l’oral. téléphone ou par émail) sur l’avancement des tâches
entre les réunions car, d’expérience, ce n’est souvent
Formaliser le projet CRM dans l’entreprise qu’à l’approche de la date limite que les collaborateurs
et assurer le suivi commencent à réfléchir au travail à effectuer.
Pour qu’un projet de CRM soit un succès, il faut lui don- Pour assurer le succès du projet de CRM, le budget
ner de la visibilité et ne pas en faire un projet secret ou alloué et les objectifs à atteindre seront clairement dé-
un Serpent de Mer. Il faut communiquer en interne sur finis. L’équipe gardera le moral et verra sa motivation
le projet de CRM afin que les utilisateurs se l’appro- maintenue car chaque petite victoire sera fêtée (une
prient, et sentent qu’ils sont partie prenante au projet. coupe de champagne…) durant l’avancement du projet,
Pour cela, n’hésitez pas à mettre en place une réunion que cela soit pour le lancement du projet, pour la réa-
officielle de lancement interne, à donner des informa- lisation de la première bêta… Le projet de CRM sera
tions sur l’avancement dans la newsletter interne de plus facilement adopté si un nom lui est donné.
l’entreprise ou par un e-mail information…
Ayez toujours en tête que 50% de la réussite d’un pro- Contrôler que la solution est adoptée et qu’el-
jet de CRM vient non pas de l’outil informatique utilisé le répond aux besoins
mais de la mise en place du projet CRM et de la person- Une fois la solution de CRM mise en place, il est in-
nalité de la personne qui est en charge du projet. Pour dispensable de valider son adéquation par rapport aux
cela, il faut créer dès le départ un comité de pilotage objectifs initiaux, mais également faire en sorte qu’elle
CRM qui sera l’élément moteur dans la mise en place réponde aux besoins des utilisateurs.
du projet de CRM : La formation initiale aux utilisateurs est essentiel-
le : elle peut être effectuée par un prestataire pour les
• un chef de projet (le sponsor) : si possible, désigner utilisateurs pilote, puis déléguée aux salariés qui ont
un opérationnel aguerri aux habitudes de l’entrepri- été formés en premier, mais il est essentiel que tous

12 1/2011
CRM

sachent bien utiliser le produit et en voient les impli- 6 – Choix de la solution à retenir, avec définition d’un
cations. planning de mise en place par le prestataire.
Il faut aussi prévoir une piqûre de rappel 1 à 2 mois 7 – Test par un échantillon d’utilisateurs (les bêta tes-
après la mise en place de l’application pour répondre teurs)
aux nouvelles questions et attentes car, dans la plupart 8 – Information sur l’avancement du projet à la struc-
des cas après la mise en place du système et une uti- ture (comité de direction et collaborateurs).
lisation quotidienne, de petits ajustements sont indis- 9 – Finalisation du projet par le prestataire.
pensables. Généralement, il faut prévoir 5 à 10% du 10 – Présentation du projet aux employés de l’entre-
montant du projet total pour ces ajustements post mise prise.
en production. 11 – Formation des utilisateurs.
En parallèle, vous devez faire un suivi de l’atteinte 12 – Mise en place de la solution de CRM et ajuste-
des objectifs du projet. Avant la mise en place du projet, ments opérationnels.
vous définissez les indicateurs clés liés au succès du 13 – Bilan du projet 1 mois après.
logiciel de CRM : des fiches avec des adresses e-mail, 14 – Optimisation de la solution.
un taux de NPAI plus faible, un taux diminué d’affaires 15 – Formation de perfectionnement (1 à 2 mois après
perdues, une augmentation du CA de N%… Ainsi, vous la mise en place du projet).
savez où vous en êtes et, éventuellement, identifiez des 16 – Optimisation continue de la solution avec évolu-
points de blocage et améliorez la situation et, surtout, tion des besoins de l’entreprise et de l’environnement
montrez les bénéfices concrets de la mise en place du économique.
CRM.
Bien entendu, avant de mettre en place l’application,
Le planning de mise en place d’un logiciel il faut l’avoir bien testé pour éviter les lancements en
de CRM fanfare qui se transforment en Bérérézina (surtout, véri-
Les délais de mise en place d’une solution de CRM sont fier que l’intégration des données se passe bien avec le
très variables d’une entreprise à l’autre. système d’information de l’entreprise).
Par exemple, une petite entreprise de 3 ou 4 person- Il faut aussi bien préparer les supports de cours, les
nes mettra en place une solution de CRM Simple en guides de procédures… pour une acceptation plus ra-
environ 1 à 2 jours, mais une entreprise qui a un projet pide par les utilisateurs. Penser à nommer des experts
de CRM Evolué organisera un planning sur plusieurs dans chaque service qui seront les interlocuteurs de ni-
mois. veau 1 sur les problèmes les plus simples (générale-
D’une manière générale, les projets de CRM Evolués ment, les membres du comité CRM).
durent entre 5 mois et 1,5 an entre le début de la ré- Dans les premiers jours, il conviendra de maintenir
flexion et la mise en place réelle. en parallèle les 2 systèmes en permettant, si nécessai-
Pour vous guider, voici les 17 étapes principales re, une bascule entre les deux systèmes, mais il faudra
à prendre en compte pour la mise en place d’une solu- passer le plus rapidement possible au nouveau sys-
tion de CRM. tème et ne surtout pas laisser perdurer une cohabita-
tion.
0 - Analyse de la situation actuelle dans l’entreprise
(problématique, logiciels existants…). 17 erreurs qui font échouer les projets de CRM
1 – Définition des objectifs du projet de CRM par les La mise en place d’une solution de CRM est souvent
responsables de l’entreprise. Définition du périmètre une première dans une entreprise et, généralement, le
exact du projet, pour éviter les malentendus en cours ou responsable n’a pas l’expérience dans la mise en place
en clôture de projet. Cet ordre de mission sera obliga- de ce genre d’applications. C’est pourquoi, sans une
toirement écrit et désignera des responsables du projet. préparation sérieuse et une anticipation, le projet risque
Ce document de cadrage officialise la nomination des facilement de glisser dans le temps, voire être remis
membres du groupe de travail et du chef de projet. en question par les collaborateurs de l’entreprise. Pour
2 – Étude des besoins auprès des opérationnels. éviter cela, voici une liste des erreurs à ne surtout pas
3 – Analyse des logiciels disponibles du marché commettre dans la mise en place d’un projet CRM :
et premier choix d’une courte liste de solutions (3 ou 4
au maximum). 0 – Négliger la résistance au changement dans l’en-
4 – Réception des propositions suite aux demandes treprise.
de devis / appels d’offres auprès des éditeurs de logi- 1 – Acheter une solution sans avoir au préalable ana-
ciels de CRM ou du prestataire informatique habituel. lysé ses besoins, l’évolution de son entreprise et sa
5 – Re-formulation des besoins de l’entreprise pour stratégie, la récupération des données existantes…
s’assurer qu’ils correspondent effectivement aux ob- 2 – Imposer le logiciel de CRM dans son entreprise
jectifs. sans communication, ni concertation, ni pédagogie.

www.phpsolmag.org 13
Outils

3 – Utiliser tout son budget pour l’achat de la solution tions par e-mail ou avec un cahier des charges d’une
de CRM sans penser à la récupération des données, à la page, mais le rencontrer et définir ensemble un cahier
personnalisation et à la formation des salariés. des charges le plus complet possible.
4 – Ne pas nommer un responsable du projet de CRM Parfois, l’échec d’un projet CRM vient aussi des uti-
dans l’entreprise, ou nommer une personne non influente lisateurs eux-même… Un exemple typique est celui du
ou qui dénigrera le projet ou une personne qui pense- jeune commercial qui arrive dans l’entreprise et qui,
ra à la technologie avant de penser aux hommes… à force de persuasion, finit par convaincre son patron
5 – Ne pas avoir un soutien visible et continu de la d’acheter «la solution miracle CRM» qu’il a utilisée
direction. à l’école… En effet, notre jeune cadre dynamique utili-
6 – Vouloir tout automatiser tout de suite, sans transi- sera d’abord le logiciel dans son coin, puis le diffusera
tion ni phase progressives de mise en place… et ajou- à ses collègues sans avoir un plan d’ensemble, sans
ter en même temps des nouvelles technologies qui vont prendre en compte la globalité de l’organisation de l’en-
révolutionner les habitudes des utilisateurs. treprise (ou en voulant tout révolutionner) ni l’intégration
7 – Ne pas établir un planning avec des responsables au système d’information de l’entreprise ou les relations
et ne pas vérifier que les jalons sont bien suivis. inter-service (éviter les doubles saisies, permettre un
8- Ne pas mettre en avant les bénéfices concrets partage des données...), ce qui conduira à un rejet en
et pratiques pour les utilisateurs. bloc de la solution de CRM.
9 – Voir trop grand et mettre en place un système trop
complet… Il faut toujours commencer par le minimum Pour conclure
d’informations et enrichir sur demandes lors des pha- La mise en place d’une solution de CRM dans une en-
ses de tests et d’utilisation. treprise est indispensable dans notre environnement
10 – Ne pas prendre en compte les remontées des économique incertain, mais auparavant il faut mener un
utilisateurs, ou ne pas expliquer pourquoi il n’est pas travail de réflexion important.
possible de le faire pour l’instant. En effet, au contraire d’une solution de bureautique,
11 – Laisser les anciens outils aux utilisateurs, ce qui d’un logiciel de comptabilité… qui sont finalement très
freinera l’adoption du nouveau logiciel. normés et standardisés, le CRM lui ne s’installe pas
12 – Ne pas lier le CRM avec les autres logiciels de sans une analyse et de la communication avec toutes
l’entreprise, ce qui laisse encore des doubles saisies les personnes impliquées.
et des informations partielles. Son impact sur la manière de travailler des collabo-
13 – Ne compter que sur soi-même pour personnali- rateurs, sur les processus internes et l’image de l’en-
ser le logiciel et assurer la formation des utilisateurs. treprise est telle qu’il est indispensable de cadrer son
14 – Faire appel à un prestataire qui ne connaît pas projet et de réfléchir à la globalité, mais également aux
les applications de CRM. détails.
15 – Ne pas réaliser avec son prestataire un docu- Les deux éléments majeurs à surveiller pour réussir
ment de cadrage définissant avec précision les élé- son projet CRM sont :
ments à réaliser. Le cadrage initial du projet, qu’il faudra faire évoluer
16 – Rester flou dans ses demandes à son prestatai- au fur et à mesure de l’avancement. Ce document sera
re, en espérant qu’il comprendra le but recherché. obligatoirement formalisé et validé.
17 – Traiter son prestataire comme un exécutant, L’adoption par les utilisateurs, par une analyse concrè-
et non pas comme un partenaire. te des besoins, mais aussi par une communication en
interne pour convaincre du bien-fondé de la mise en
L’étude menée par Sage en 2005 révèle que les pre- place de l’outil.
mières difficultés des projets CRM sont la récupération En conclusion, il faut retenir que la mise en place
des données et la résistance au changement. d’une solution de CRM est finalement un projet à la fois
Dans un projet de CRM, il est essentiel de travailler technique et humain qu’il faut mener à bien en tenant
avec son prestataire informatique en partenariat et en compte des spécificités de l’organisation de l’entrepri-
toute transparence. En effet, contrairement au logiciel se. Et comme chaque entreprise est différente, à cha-
de Comptabilité où les tâches sont normées et les pro- que fois il faut s’adapter à ses particularités via la mé-
cessus clairement standardisés, avec une application thodologie que vous venons de vous présenter.
de CRM, c’est la manière dont l’entreprise fonctionne
qui est touchée.
En effet, ici, il n’y a pas de norme à suivre, c’est l’appli- Frédéric de ConseilsMarketing.fr
cation qui doit s’adapter au mieux à l’entreprise et non ConseilsMarketing.fr est un des premiers sites sur le Marketing en
l’inverse. France, il donne toutes les semaines des conseils concrets et pra-
C’est pourquoi, pour travailler efficacement avec son tiques pour trouver des prospects, fidéliser ses clients et gagner du
revendeur, il ne faudra pas lui demander 3 ou 4 fonc- temps.

14 1/2011
Rejoignez le Club .PRO CRM
Pour plus de renseignement : editor@phpsolmag.org

Pour les débutants


Ston¿eld Inworld

Rejoignez le Club .PRO


Stoneld Inworld propose aux entreprises des solutions globale d’intègration d’Internet et des Univers
Virtuels dans leur stratégie de développement. Au-delà de ses services, la société consacre 30% de
ses ressources à des travaux de R&D sur le e-Commerce et le e-Learning dans les Mondes Virtuels.

Pour plus de renseignement : editor@phpsolmag.org


COGNIX Systems
Ston¿conception
Conseil, eld Inworld
et développement d’applications évoluées pour les systèmes d’informations Internet/
intranet/extranet.
Stoneld Inworld Alliant
proposelesaux
compétences
entreprisesd’une SSII et d’une
des solutions Webd’intègration
globale Agency, Cognix Systems
d’Internet conçoit
et des des
Univers
applicatifs et portails
Virtuels dans web à l’ergonomie
leur stratégie travaillée Au-delà
de développement. et des sites
de Internet à forte la
ses services, valeur ajoutée.
société consacre 30% de
ses ressources à des travaux de R&D sur le e-Commerce et le e-Learning dans les Mondes Virtuels.
http://www.cognix-systems.com

Anaska
COGNIXFormation
Systems
Anaska
Conseil, est le spécialiste
conception des formations
et développement sur les technologies
d’applications évoluéesOpenSource. En partenariat
pour les systèmes avecInternet/
d’informations MySQL
AB, Mandriva, Zend
intranet/extranet. et d'autres
Alliant acteurs ded’une
les compétences la communauté,
SSII et d’uneAnaska vous propose
Web Agency, Cognixun catalogue
Systems de plus
conçoit des
de 50 formations
applicatifs dédiés
et portails webaux technologies
à l’ergonomie du Libre.
travaillée et des sites Internet à forte valeur ajoutée.
http://www.cognix-systems.com
http://www.anaska.com

Anaska Formation
WEB82
Anaska
Créationestet lehébergements
spécialiste desde
formations surpour
sites web les technologies
particuliers, OpenSource.
associations,En partenariat e-commerce.
entreprises, avec MySQL
AB, Mandriva, Zend
Développement et d'autres
entierement acteurs
aux de la
normes W3C communauté,
(www.w3.org)Anaska vous web
de sites propose un catalogue
de qualité, de plus
au graphisme
de 50 formations
soigné et employantdédiés aux technologies
les dernieres du Libre.
technologies du web (PHP5, MySQL5, Ajax, XHTML, CSS2).
http://www.anaska.com
http://www.web82.net

WEB82
Core-Techs
Création et hébergements de sites web pour particuliers, associations, entreprises, e-commerce.
Expert des solutions
Développement de gestion
entierement et de communication
aux normes d’entreprise
W3C (www.w3.org) de sites en Open
web Source,auCore-Techs
de qualité, graphisme
conçoit,et integre,
soigné déploie
employant et maintient
les dernieres des systemes
technologies de Gestion
du web (PHP5, MySQL5,de Ajax,
Contenu Web,
XHTML, de Gestion
CSS2).
Documentaire, de Gestion de la Relation Client (CRM), d’ecommerce et de travail ollaboratif.
http://www.web82.net
http://www.core-techs.fr

Core-Techs
POP des
Expert FACTORY
solutions de gestion et de communication d’entreprise en Open Source, Core-Techs
conçoit,
PoP integre, déploie
Factory,SSII et maintient
spécialisée des systemes
Web. Développement de de Gestion
solutions de Contenu
applicatives Web,
spéci quesde; offre
Gestion
de
Documentaire,
solutions de Gestion
packagées de la numérique,
: catalogue Relation Client (CRM), d’ecommerce
e-commerce, livre/magazineet numérique,
de travail ollaboratif.
envoi SMS. Nous
http://www.core-techs.fr
accompagnons nos clients tout au long de leur projet : audit, conseil, développement, suivi et gestion.
http://www.popfactory.com / info@popfactory.fr

POP FACTORY
Blue
PoP Note Systems
Factory,SSII
solutions
spécialisée Web. Développement de solutions applicatives spéciques ; offre de
Spécialistes en CRM Open Source, nouse-commerce,
packagées : catalogue numérique, proposons unelivre/magazine numérique,
offre complète envoi SMS.sur
de prestations Nous
la
accompagnons nos clients tout au long de leur projet : audit, conseil, développement, suivi et gestion.
solution SugarCRM. Notre valeur ajoutée réside dans une expertise réactive et une expérience des
http://www.popfactory.com / info@popfactory.fr
problématiques de la GRC. Nous vous aidons à tirer le meilleur parti de votre solution CRM.
http://www.bluenote-systems.com

Blue Note Systems


Spécialistes en CRM Open Source, nous proposons une offre complète de prestations sur la
Intelligence
solution SugarCRM. Power
Notre valeur ajoutée réside dans une expertise réactive et une expérience des
Conseil, Expertises,
problématiques de laFormations
GRC. Nouset Projets
vous E-business
aidons centrés parti
à tirer le meilleur au tour
de du cĞur
votre de métier
solution : la Business
CRM.
Intelligence. Intelligence Power vous propose des solutions innovantes pour aligner la technologie sur
http://www.bluenote-systems.com
la stratégie de votre entreprise.
http://www.intelligencepower.com
Intelligence Power
Conseil, Expertises, Formations et Projets E-business centrés au tour du cĞur de métier : la Business
Web Alliance
Intelligence. Intelligence Power vous propose des solutions innovantes pour aligner la technologie sur
la stratégie
Vous de votre
souhaitez être entreprise.
en première page des moteurs de recherche ? Rejoignez-nous, 100% des clients
http://www.intelligencepower.com
Web Alliance sont en 1ère page de Google. Web Alliance, société de conseil spécialisée dans le
référencement internet, vous propose son expertise (référencement, liens sponsorisés, web-marketing).
www.web-alliance.fr
Web Alliance

Club .PRO
Vous souhaitez être en première page des moteurs de recherche ? Rejoignez-nous, 100% des clients
Web Alliance sont en 1ère page de Google. Web Alliance, société de conseil spécialisée dans le
référencement internet, vous propose son expertise (référencement, liens sponsorisés, web-marketing).
www.web-alliance.fr

49
50 5/2010
www.phpsolmag.org 15
Projets

Définition
d’une base de données avec l’ORM
Doctrine dans un projet Symfony
La plupart des services informatiques d’aujourd’hui sont devenus
des applications web. Ces applications sont caractérisées par
un degré de complexité très élevé, en effet, le travail
du développeur est devenu plus complexe, étant donné
l’évolution des langages de développement, des bases
de données et des différentes plateformes de développement.

Cet article explique : Ce qu’il faut savoir :


• Définition d’une base de données sous l’ORM Doctrine. • Le lecteur devra connaître les principes de programmation
• Relations un à plusieurs. orientée objet en PHP5, néanmoins des notions concernant le
• Relations plusieurs à plusieurs. framework Symfony et l’orm Doctrine.
• Bonnes pratiques.
• Commandes Symfony Doctrine.

L
’utilisation de la programmation Orientée Objet est Symfony propose une couche de mapping objet-
une priorité pour un développeur, mais ce point relationnel (ORM) et une couche d’abstraction de
n’est plus exact à 100% qu’avec l’utilisation des fra- données, depuis la version 1.2, les développeurs de
meworks de mapping Objet / Relationnel (ORM). Depuis Sensio ont choisi Doctrine comme étant l’ORM par
la sortie de PHP5, plusieurs frameworks ont été dévelop- défaut et ainsi remplacer l’ancien Propel.
pés, permettant le développement des grandes applica- L’utilisation de la ligne de commande de Symfony
tions en respectant les normes de programmation Objet. permet la génération des classes modèles, classes for-
Toutefois, il y a nombres de frameworks de map- mulaires et classes filtres ainsi la génération du code
ping Objet / Relationnel (ORM) visant à ce que l’utilisa- SQL de la base de données. Alors comment Doctrine
teur puisse manipuler ses tables de données comme si comprend-il notre schéma conceptuel ? Comment con-
c’étaient des objets. nait-il les tables et les contraintes d’intégrité ?
Doctrine est l’un des ORM les plus connus qui exi-
stent actuellement. Il est utilisé dans des frameworks Dans un projet Symfony
très connus (Symfony, Zend Framework), et est aussi Pour décrire le schéma de notre base de données dans
simple à prendre en main que puissant. Doctrine est un projet Symfony on doit utiliser un fichier de configu-
basé sur le noyau du framework Hibernate (java). Nous ration spécifique, c’est le fichier schema.yml situé dans
allons voir ensemble l’utilisation de cet ORM dans un NomProjet\config\doctrine\. La plupart des fichiers de
projet PHP développé sous le framework Symfony. configuration de symfony sont au format YAML. Selon
le site officiel, YAML est un standard de sérialisation de
Symfony données compréhensibles par un humain, quel que soit
Symfony est un framework PHP, développé par Sensio le langage de programmation.
labs en octobre 2005 en PHP5 (version 5.2.4). YAML est un langage simple qui décrit les données.
Au départ de chaque projet Symfony, vous devriez Comme PHP, il a une syntaxe pour les types simples
préparer votre base de données : une étape de spéci- comme les chaînes, les booléens, les décimaux ou les
fication des besoins et de la conception de la base de entiers.
données du projet est nécessaire. Il y a une chose importante dont vous devez vous so-
Après la validation du schéma conceptuel, on passe uvenir lorsque vous utilisez l’indentation dans un fichier
à la création de la base réelle avec le langage relation- YAML : une indentation doit être faite avec un ou plu-
nel SQL. sieurs espaces, mais jamais avec les tabulations.

16 1/2011
Symfony et Doctrine

Vous pouvez inclure des mappings dans des séries On doit spécifier pour chaque champ le type de don-
si vous le souhaitez ou vous pouvez inclure des séries nées tel que : string, boolean, integer, date, datetime...
dans des mappings comme ceci : On ajoute la taille du champ puis on spécifie d'autres
propriétés optionnelles comme notnull, default, primary,
Chapitre 1: autoincrement …
Introduction
Types
Chapitre 2’: Relations un à plusieurs
Introduction La spécification des cardinalités lors de l’étape de con-
Helpers
I18n
ception a fixé le type des relations entre les tables ; en
Javascript fait, dans ce premier exemple on a une relation de type
un à plusieurs, donc une voiture peut être louée par un
et un seul utilisateur et ce dernier peut louer plusieurs
Voici le schéma sur lequel nous allons travailler dans voitures à la fois. Donc on doit ajouter id_utilisateur
cet article : comme clé étrangère dans la table Voiture puis on doit
schema.yml créer la relation entre les deux entités comme suit :

Voiture: relations:
columns: Locataire: {class: Utilisateur, local : id_utilisateur , foreign : id_
id_voiture : { type : integer , notnull : true , primary : true } utilisateur }
marque: { type : string(30) , notnull : truen }
puissance : { type : integer , notnull : true }
etat : { type : boolean , notnull : true }
Utilisateur :
columns: La description des relations est la partie le plus im-
id_utilisateur: { type : integer , notnull : true , primary : true } portante dans l’élaboration du schéma YAML, car ils se-
nom: { type : string(20) , notnull : true }
prenom : { type : string(20) , notnull : true } ront utilisés après, dans les classes modèles et formu-
laires pour récupérer un Objet ou une liste des objets B
à partir d’un Objet A.
C’est un schéma conceptuel simplifié pour une agen- Comme pour les colonnes, une relation doit avoir un
ce de location de voitures où on a deux tables Voiture nom, pour cela deux cas possibles :
et Utilisateur et où on veut enregistrer les opérations de
location de chaque voiture. • Choisir le même nom, celle de la deuxième table
qui participe dans la relation.
Détaillons la structure YAML de la Classe • Choisir un nom significatif (tel est notre cas), ma-
(table aussi) Voiture is on doit obligatoirement ajouter la propriété class
En premier lieu on doit spécifier le nom de la Classe parmi la liste des propriétés qu’on doit définir pour
(qui sera aussi le nom de la table). la relation (dans le premier cas cette propriété n’est
Ensuite, en commence à décrire la liste des colon- plus obligatoire car Doctrine comprend qu’il doit avo-
nes de la table (qui seront les attributs de la classe ir une autre table avec le même nom de la relation).
modèle qui va être générée avec Doctrine), pour cela le
mot clé columns doit être utilisé. Après la génération de la classe associée, on aura là deux
nouvelles méthodes, dites magiques (getter et setter):
Voiture: 1. getLocataire() : retourne l’utilisateur qui a loué la
columns: voiture actuelle.
id_voiture : { type : integer , notnull : true , primary : true }
marque: { type : string(30) , notnull : truen } Exemple : B = new Voiture () ;
puissance : { type : integer , notnull : true } B. getLocataire () ; // retourne l’utilisa-
etat : { type : boolean , notnull : true }
id_utilisateur { type : integer , notnull : true }
teur qui a loué B.
relations: 2. setLocataire(Objet de type Utilisateur) :
Locataire: { class: Utilisateur, local : id_utilisateur , foreign : id_ pour louer la voiture actuelle à un utilisateur passé
utilisateur , foreignAlias : Voitures }
Utilisateur : en paramètres.
columns: Exemple : A = new Utilisateur () ;
id_utilisateur: { type : integer , notnull : true , primary : true }
nom: { type : string(20) , notnull : true } B. setLocataire(A) ; // location de la vo-
prenom : { type : string(20) , notnull : true } iture B par l’utilisateur A

[local : id_utilisateur] : sert à fixer la colonne


Puis, pour chaque colonne on doit spécifier une li- de la table Voiture (où on a déclaré la relation), utili-
ste des options qui ressemblent à l la description des sé pour établir la liaison avec la table Utilisateur (la clé
champs dans SQL. étrangère).

www.phpsolmag.org 17
Projets

[foreign : id_utilisateur]  c’est le champ qui Dans ce cas, la définition de la relation est un peu spéci-
fait référence à la clé étrangère dans la table Utilisa- fique : on doit spécifier les deux tables et ainsi l’associa-
teur. tion qui va les relier..
[foreignAlias : Voitures] : c’est une propriété
très importante ; comme on a fixé le nom de la relation relations:
(Locataire) dans la table Voiture on doit aussi donner Locataires: { class: Utilisateur, local : id_voiture , foreign : id_
utilisateur , foreignAlias : Voitures , refClass:
le nom de la même relation mais cette fois dans la ta- Location }
ble Utilisateur. Au lieu de redéfinir la totalité de la rela-
tion dans la table Utilisateur on utilise foreignAlias pour
donner seulement le nom de la relation et Doctrine joue • On a la même chose pour le nom des relations (Lo-
son rôle. cataires) ainsi que pour [foreignAlias : Voitures].
Pour des raisons sémantiques il est préférable de
La classe Utilisateur générée avec Doctrine va mettre les noms au pluriel, puisque on travaille plu-
contenir deux fonctions comme pour la classe Voiture, sieurs à plusieurs.
mais le type de retour est un peu différent puisque c’est • [ refClass : Location] : c’est là où se situe la
une relation un à plusieurs. différence entre les types de relations, ici on doit
spécifier le nom de l’association entre les deux enti-
tés.
1. getVoitures() : retourne la liste des voitures (Do-
ctrine Collections) louées par l’utilisateur actuel. Ainsi vous avez une idée plus ou moins complète de
2. setVoitures  (Doctrine Collections of Voiture) : po- la définition de votre schéma YAML. Une fois terminé,
ur affecter une collection de voitures à un Utilisa- vous pouvez générer les classes modèles et les clas-
teur. ses formulaires où vous pouvez constater que, dans le
cas d’une relation un à plusieurs Doctrine présente le
Autres options : champ id_utilisateur par une liste de choix simple (un
seul choix) ; par contre dans le cas de relations plu-
• Dans le cas actuel Doctrine comprend bien que sieurs à plusieurs vous aurez dans les deux formula-
c’est une relation un à plusieurs mais on peut spéci- ires une liste de choix multiple des objets.
fier les options type (one ou many) ou foreigntype
(le type de relation coté entité). Bonne pratique
Doctrine propose pas mal de best practice pour simpli-
Relations plusieurs à plusieurs fier le schéma de la base de données et pour rendre
Ce type de relation nécessite une association entre les plusieurs taches automatiques :
deux tables, puisqu’un utilisateur peut louer plusieurs
voitures et une voiture peut être louée par plusieurs uti- 1. La clé primaire : doctrine peut s’occuper de ce
lisateurs, donc notre schéma sera comme suit : champ. Si vous n’avez pas spécifié la propriété
[primary :true] à l’une des colonnes, Doctrine
Voiture: ajoute une colonne et lui donne le nom id, son ty-
columns: pe sera integer et en autoincrement. Cela pour sim-
id_voiture : { type : integer , notnull : true , primary : true }
marque: { type : string(30) , notnull : truen } plifier notre schéma. Ensuite, si vous utilisez le
puissance : { type : integer , notnull : true } champ de la clé primaire dans une relation vous po-
etat : { type : boolean , notnull : true }
relations:
uvez utiliser le nom id bien sûr.
Locataires: { class: Utilisateur, local : id_voiture , foreign : id_ Dans le cas où vous utilisez Oracle comme SGBD,
utilisateur , foreignAlias : Voitures , refClass: Location } lors de la génération de la base réelle Doctrine va
Utilisateur :
columns: créer une séquence pour le champ id.
id_utilisateur: { type : integer , notnull : true , primary : true } 2. L’enregistrement de la date d’ajout et de modifi-
nom: { type : string(20) , notnull : true }
prenom : { type : string(20) , notnull : true } cation des données d’une table est parfois ob-
Location: ligatoire ; tel est le cas d’une table d’inscription
columns:
id_voiture: { type : integer , notnull : true , primary
à titre d’exemple, on veut connaître la date d’in-
: true } scription et la date de modification d’inscription.
id_utilisateur : { type : integer , notnull : true , primary : Doctrine offre la possibilité de gérer ces informa-
true }
tions et leurs mises à jour automatique sans inte-
rvention du développeur (dans la partie Métier) ;
pour cela on doit ajouter la ligne suivante au
Une troisième table (appelée aussi association), début de chaque table où l’on veut avoir ces in-
est ajoutée pour gérer la relation plusieurs à plusieurs. formations.

18 1/2011
Prenons l’exemple de la table Voiture :

Voiture:
actAs: { Timestampable: ~ }
columns:
marque: { type : string(30) , notnull : truen }
puissance : { type : integer , notnull : true }
etat : { type : boolean , notnull : true }

• [actAs: { Timestampable: ~ } ] : au
même niveau que columns, cette propriété permet
à Doctrine d’ajouter deux champs nommés respec-
tivement created_at et updated_at à notre table Vo-
iture et sa classe associée. Lors de l’ajout d’une vo-
iture à la base de données le champ created_at
prendra la valeur de la date système, et dans le cas
d’une modification d’une voiture qui existe déjà, Do-
ctrine, met à jour seulement le champ updated_at.

Commandes Symfony Doctrine


Voici une liste des commandes Symfony (version 1.4)
utilisées lors de générations du code :

• [symfony doctrine:build-model] : génération


des classes modèles seulement.
• [symfony doctrine:build-forms] : génération
des classes formulaires seulement.
• [symfony doctrine:build-filters] : génération
des classes filtres seulement.
• [symfony doctrine:build-sql] : génération du
code SQL de la base de données.
• [symfony doctrine:build-db] : création de la
base de données à partir des classes modèles exi-
stants.
• [symfony doctrine:build --all --no-
confirmation] : permet d’exécuter toutes les com-
mandes précédentes à la fois et sans demande de
confirmation car Doctrine va écraser la base et en
créer une nouvelle.
• [symfony doctrine:build-schema] : génération
du schéma YAML à partir d’une base de données
déjà existante, mais cette fois on aura des relations
avec des noms non significatifs, c’est pour cela que
l’utilisation de cette commande n’est pas recom-
mandée.

Belgacem TLILI
Belgacem TLILI, Ingénieur analyste développeur PHP5/Symfony
chez Owliance Tunisie, je me suis spécialisé dans le développement
web depuis 4 ans.

www.phpsolmag.org 19
Dossier

Acquérir
de la vitesse avec Zend Framework – part III
Après une longue interruption, je reprends le cours
des articles visant à améliorer l'usage que nous faisons
des différents composants du Zend Framework. Dans cet article
je souhaite vous présenter les composants Zend_Cache mais
aussi, plus largement, la notion de politique de cache.

Cet article explique : Ce qu'il faut savoir :


• Ce qu'est une politique de cache et comment la définir. • Rien à part connaître PHP.
• Comment l'implémenter en utilisant le Zend Framework.

A
vant de rentrer dans le vif du sujet et voir com- ches à partir de données conservées en base de don-
ment utiliser les différents éléments du, ou de- nées. Des systèmes de cache voudront conserver en
vrais-je dire, des différents éléments qui com- mémoire les résultats de requête http, les résultat de
posent le système de cache proposé par le Zend calcul réalisé par le serveur ou les résultat sde requête
Framework, j'aimerais faire un petit détour par les prin- en base. Et ce, pour éviter d'avoir à les recalculer à cha-
cipes et techniques sous-jacents aux systèmes de ca- que fois.
che. Voici une description rapide, Au delà de la définition
A la différence de nombreux autres Framework, ce- de la politique de cache, je vais entrer dans le détail des
lui de Zend ouvre grand la boite de Pandore du cache différents outils dont nous disposons.
et offre une palette extrêmement vaste de possibilités.
Ceci étant à la fois un avantage et une source de pro- La politique de cache
blème. Mais c'est toute l'histoire de ce framework ! Offrir A quoi sert une politique de cache ? Son objectif ma-
pléthore de possibilités nécessite une bonne prépara- jeur est de définir quels seront les éléments qui néces-
tion et une bonne analyse en amont du développement. siteront du cache et comment nous le réaliserons. Jus-
J'espère que cet article vous apportera les outils et ficel- que là, cela semble simple. J'ai déjà entendu maintes
les nécessaires à un bon usage des objets de cache de fois des développeurs me dire : le cache, oh moi, je
Zend_Framework. Voyons déjà ce qu'est le cache. développe sans, et j'en mets ensuite là ou cela coince !
Non, mille fois non ! C'est une très mauvaise pratique
Le cache c'est quoi ? et ce, même si la souplesse du système de cache de
C'est beaucoup de chose différentes mais d'une ma- zend le permet ! En effet, cela peut avoir de lourdes
nière générale le principe est toujours le même : mettre conséquences sur les structures du contrôleur ou des
des données dans un élément de stockage rapide pour templates et impliquer un refactoring important. Mieux
pouvoir les récupérer rapidement. Plus rapidement que vaut, en fonction de son architecture d'hébergement,
par la méthode classique. Il y a de la mémoire cache de ses usages, du contenu du site, choisir ses techno-
dans tous les ordinateurs pour stocker des données logies de stockage en cache, les éléments à y stocker
temporaires. Et oui les données que l'on met dans un et les durée de conservation. Le codage en sera plus
cache ont une durée de vie elle ne sont pas éternelles. efficace.
Dans le monde du web, le moyen normal est basé Quels sont les différents type de cache dont nous
sur des requêtes http qui transitent sur un réseau pour disposons ? Il y a quatre grandes famille de cache
demander à un serveur d'application de réaliser des tâ- à mon sens :

20 1/2011
Zend Framework

Figure 1. Le focntionnement du cache Browser

Figure 2. Le cache réseau

• Le cache du navigateur : celui de votre navigateur à recalculer tout ou partie d'une vue ou d'une action.
web va stocker des images, des fichiers javaScript En bref diminuer la charge CPU de votre serveur.
ou CSS, voire même des pages entières ! Tout ce- • Les caches métier/modèle : ces caches qui agis-
la se gère avec des balises Méta dans le header sent aussi au niveau de votre applicatif, permet-
et évite de faire des requêtes sur le réseau. tent de stocker des données brutes issues d'une
• Le cache réseau : je range dans ce terme (qui n'est base ou travaillées par des classes métier et donc
pas très orthodoxe je vous l'accorde) l'ensemble des d'éviter de recalculer les éléments permettant de
systèmes de cache que l'on va trouver entre le navi- construire des vues. Là encore l'objectif est de di-
gateur et notre serveur d'application : se sont des minuer la charge de vos serveurs d'application
serveurs mandataires ou des cache proxy comme et de base de données.
Squid ou Varnish.
• Les caches de vues : qui agissent au niveau de vo- Seules les deux dernières familles sont traitées par le
tre applicatif et dont l'objectif est de ne pas avoir système de cache Zend_cache.

www.phpsolmag.org 21
Dossier

Partant de là, quelles sont les questions à se po-


Listing 1. Exemples de Zend_Frontend_Cache_Core
ser ? Elles sont différentes selon les couches de cache
<?php concernées. Je vous propose de voir rapidement les
// nous avons déjà instancier l'objet cache avec le
frontend Core dans $cache deux premières et, par l'étude des deux secondes de
$id = 'myBigLoop'; // id de cache de « ce que l'on
voir comment Zend_cache pourra nous aider.
veut cacher »

if (!($data = $cache->load($id))) {
Le cache du navigateur
// si cache absent Attention ce cache est un petit filou ! Les navigateurs
$data ='';
for ($i=0;$i < 10000; $i++) { sont bien fait et pour nous éviter de longs moments
$dat = $data.$i; d'attente, ils gèrent un cache local dont l'objectif est de
}
$cache->save($data); limiter au maximum les données échangées avec les
} serveurs Web. La Figure 1 montre un appel http vers
?>
un fichier index.php. Cette appel va retourner une page
Listing 2. Extrait de la classe Zend_Cache_Core du package HTML. Si cette page n'est pas clairement définie com-
Zend_Cache.
me à ne pas cacher via le meta Cache-Control du hea-
….. der, lors des prochains appels, le navigateur ne fera
/**
* Last used cache id que vérifier si cette page n'a pas expirée et la réaffiche-
*
* @var string $ _ lastId
ra sans la moindre requête. Il en est de même pour les
*/ éléments qui la constitue comme les fichiers javascript,
private $ _ lastId = null;
….. CSS ou les images. C'est très pratique mais si notre fi-
/** chier javascript est généré dynamiquement sans chan-
* Test if a cache is available for the given id
and (if yes) return it (false else) ger son nom, il ne sera pas rechargé par le navigateur
* et les données seront périmées.
* @param string $id Cache id
* @param boolean $doNotTestCacheValidity If set
to true, the cache validity won't be tested
* @param boolean $doNotUnserialize Do not Bonne pratique n°1 : systématiquement mettre les pa-
serialize (even if automatic _ serialization is true) => ges html dynamiques (donc générées par votre framework)
for internal use
en no-cache dans le header de votre layout par exemple
* @return mixed|false Cached datas
*/ (Cache-Control:no-cache) et mettre des dates d'expiration
public function load($id, $doNotTestCacheValidity = sur les fichiers javascript à l'aide du Meta : Expires. Pour les
false, $doNotUnserialize = false) fichiers javascript dynamiques, le mieux, est de les appeler
{
if (!$this-> _ options['caching']) { avec une query string dans leur URL, comme par exemple
return false; <script src='/scripts/monBeau.js?Id=2'/>.
}
$id = $this-> _ id($id); // cache id may need
prefix
$this-> _ lastId = $id; Pour mettre dans le Header d'une page ces informa-
…..... tions, il existe plusieurs solutions. Pour moi la plus sim-
ple, c'est, dans le layout, d'ajouter la balise <META HTTP-
/**
* Save some data in a cache EQUIV=»CACHE-CONTROL» CONTENT=»NO-CACHE»>.
*
* @param mixed $data Data to put in
Ainsi tous les templates basés sur ce layout seront en
cache (can be another type than string if automatic _ no-cache. Ensuite plus finement au sein du controleur
serialization is on)
* @param string $id Cache id (if not
le framework Zend propose une fonction de l'objet ré-
set, the last cache id will be used) ponse $this->getResponse->setHeader('Cache-
* @param array $tags Cache tags
* @param int $specificLifetime If != false, set a Control','no-cache', true). Mais cela me pose un
specific lifetime for this cache record (null => infinite problème dans le sens ou cela casse le MVC (Modèle
lifetime)
* @param int $priority integer between Vue Contrôleur – sujet déjà abordé dans de précédent
0 (very low priority) and 10 (maximum priority) used by numéro de PHP Solution) puisque dans le Contrôleur
some particular backends
* @throws Zend _ Cache _ Exception (plus exactement l'action) on définit un paramètre de
* @return boolean True if no problem la vue !
*/
public function save($data, $id = null, $tags =
array(), $specificLifetime = false, $priority = 8)
{
Les caches réseaux
if (!$this-> _ options['caching']) { Sous cette appellation, je range donc tous les systèmes
return true;
}
de cache placés entre le client et notre serveur Web.
if ($id === null) { Comme montré dans la Figure 2 Les plus connus étant
$id = $this-> _ lastId;
} else { Squid et Varnish mais il y en a certainement d'autres.
$id = $this-> _ id($id); Un serveur Squid ou Varnish est un serveur manda-
}
…... taire (proxy) capable d'utiliser les protocoles FTP, HTTP
et HTTPS. Il est utilisé pour filtrer des URL et comme

22 1/2011
Zend Framework

cache. Son rôle est de cacher des éléments statiques.


Listing 3. Exemples de Zend_Cache::factory
Pour cela, il enregistre les URL les plus utilisées pour
les mettre en cache. Oui mais voilà et si on veut pas ! <?php …
$frontendOptions = array (
La page est forcément dynamique ! Alors il ne faut pas 'lifetime' => '7200' // durée de conservation
lui permettre de mettre en cache certains type d'url ou en cache en s
'automatic _ serialisation' => true);
d'extension. C'est de la conf du proxy.
Le choix entre ces deux serveurs relève plus de vo- $backendOptions = array (
//repertoire où stocker les fichiers de cache-
tre hébergeur alors je ne l'aborderai pas. Vous trouve- CONTROL
rez sur le net des comparatifs très instructifs avec un 'cahce _ dir' => './tmp/');

avantage pour Varnish. //créer un objet Zend _ Cache _ Core


$cache = Zend _ Cache::factory( 'Core',
Retenez que ce type de serveur peut mettre en ca- 'File',
che des fichiers javascript ou CSS minifiés, des images, $frontendOptions,
$backendOptions);
en bref des contenus statiques offrants ainsi des répon- ?>
ses plus rapides aux navigateurs de vos clients.

Les Caches applicatifs


Les frontends Voyons maintenant comment bien utiliser les fron-
On va enfin parler du framework Zend. Je range dans tends de cache, pour cela, il faut se poser quelques
ce chapitre les deux familles de caches applicatifs ci- questions pour chacun des éléments de notre page.
tées dans l'introduction. Je fais ce choix car la structure Selon leurs réponses, les méthodes à mettre en œuvre
de la librairie Zend_cache mélange les deux. D'autres sont différentes.
frameworks (Symfony ou Cake PHP) ont une approche La méthode à appliquer est simple : prendre chaque
découpée en vues et données. La librairie Zend est, page de votre site les unes après les autres et se poser
quant à elle, décomposée en frontend et backend (dé- les questions suivantes en en respectant l'ordre :
cidément ces termes sont mis à toutes les sauces) qui
permettent de configurer les deux éléments nécessai- 1. Est-il possible de cacher la page entière ? Si la ré-
res à la Zend_cache_factory qui aura la tâche de fabri- ponse est oui (c'est en général assez rare et réservé à vo-
quer l'objet cache Zend. tre page d'accueil associée à la racine de votre site) alors
C'est un peu embrouillé ? C'est effectivement pas le frontend Zend_Cache_Frontend_Page vous permettra
très simple comme approche, mais avec un peu d'ex- de mettre en cache une page entière. Personnellement,
plication les choses vont se clarifier. La partie frontend, je le trouve très complexe à utiliser car il faut (d'après la
permet de définir quel type de contenu vous voulez doc) désactiver le buffeur de sortie utilisé par le Dispat-
mettre en cache. Requête, résultat de fonction, objet, cher ($front->setParam('disableoutputBuffering', true). Je
composants de vue, page ou éléments statiques (celui ne l'utilise pas (ou plus exactement je ne l'ai pas utilisé)
là c'est un sacré morceau que l'on déléguera surement lui préférant Zend_Cache_frontend_output. qui fait quasi-
à un cache proxy). La partie backend permettant de dé- ment la même chose en plaçant entre une balise start()
finir comment vous allez (physiquement) réaliser le ca- et une balise end() le code que vous voulez mettre en ca-
che, file system, base de données, ram, disques. che. Avec Zend_Cache_Frontend_Page une seule bali-
Il ne vous restera qu'à passer les configuration de se start() est nécessaire. Mais cela implique de pouvoir
votre frontend et de votre backend à une fabrique pour appliquer une gestion différente à la page d'accueil par
créer un objet cache que vous pourrez utiliser dans rapport aux suivantes or ,jusqu'à maintenant, mon layout
votre code … C'est simple non ! Pardon, certains se sert aussi bien à cette page qu'aux suivantes !
demandent ce qu'est une fabrique. C'est un Design 2. Je ne peux pas mettre en cache toute la page
Pattern, motif de conception en français. C'est un en- mais est-ce que certains éléments peuvent l'être ? Je
semble de classes et de méthodes prédéfinies qui per- pense à un menu, un header, un footer, … en bref des
mettent d'instancier des objets complexes. C'est un parties de la page qui sont soi statiques soit faiblements
constructeur intelligent. On l'utilise quand on sait que dynamiques. Pour ce genre de problème, vous l'aurez
nous aurons des objets à consruire tou en partageant compris, Zend_Cache_frontend_output est la solution.
des définitions. L'exemple le plus fréquent est celui d'un Attention ce frontend est l'exemple type de la fonction
jeu ou on construit des unités (genre Civilisation ou Age php qui résout tous les problèmes et rend le code tota-
of Empire). On a le choix d'appeler les constructeurs lement incompréhensible. Il ne doit pas vous affranchir
de chaques unités (ce qui implique de coder des défi- d'un découpage de votre page en utilisant les compo-
nitions de classe, les relations entre chaque objet les sants de vue que je vous ai présentés lors du précédem-
utilisant, etc … à chaque nouvelle unité) ou d'avoir une ment article.
fabrique qui se chargera à partir d'un patron de fabri- 3. Ma page ressemble à un gruyère avec des élé-
quer des unités. ments en cache et d'autres non ! Allons plus loin car

www.phpsolmag.org 23
Dossier

tout élément (ou presque ; mais ceux-ci doivent rester portant c'est la durée de vie de votre enregistrement.
des exceptions) peut être mis en cache même quel- Lifetime en anglais. Celui-ci est défini en option lors de
ques secondes. Si la vue ne peut être mise en cache la création de votre objet de cache mais peut être fixé
peut être que des éléments métier ou model le peu- spécifiquement à chaque objet.
vent ? C'est à dire des objets, des résultats de fonction Ma pratique sur ce sujet … Je l'initialise à 0 ( ce qui
ou des résultats de requêtes. Là encore Le framework correspond à une durée de cache infinie) et soit j'uti-
nous propose respectivement les frontends Zend_Ca- lise des Id calculés avec un timestamp (laissant le bac-
che_Frontend_class, Zend_Cache_Frontend_function kend faire lui même le nettoyage mais attention tous
et Zend_Cache_Frontend_core. La question qui se ne le font pas automatiquement) soit alors je spécifie
pose, en générale, avec ces caches est : quelle durée une durée lors de l'appel de la fonction d'enregistre-
dois-je utiliser ? Il est très difficile (voire impossible) de ment save().
la définir sans perdre en cohérence ou en réactivité. Il Je disais donc l'Id est important et pour son unicité.
faut donc préférer des durées infinies et utiliser un sys- Elle est indispensable et un Id du genre 'myBigLoop'
tème de clé (d'Id) qui se modifiera à chaque modifica- a toute les chances de ne pas l'être.
tion des sources de données. En utilisant par exemple Ma méthode ? Je construis des Id basés sur le sché-
un timestamp associé à la date des dernières mises ma suivant :
à jour dans la clé qui identifiera notre enregistrement
précisément. 2 initiales pour l'application + le nom du contrôleur
4. Ce n'est pas un élément de page mais un fi- + le nom de l'action + le nom du composant de vue
chier généré comme un pdf que je souhaite mettre + un chiffress'il y a plusieurs enregistrements dans
en cache ? Là c'est Zend_Cache_Frontend_Capture le même composant + un timestamp correspondant
qui fera votre affaire. à la donnée de dernière mise à jour si cela est ap-
5. Ce n'est rien de tout cela ? Un fichier de confi- plicable sinon rien. Ce qui peut donner BC/Game-
guration peut être ? Vous créer un objet Zend_Config Board/index/1 par exemple. Après, libre à vous de
à partir d'un fichier xml alors Zend_Cache_Frontend_ trouver une autre règle dès l'instant que l'unicité est
File vous permettra de l'enregistrer et de pouvoir le réu- assurée.
tiliser sans avoir à le régénérer. Pourquoi s'appelle-t-il
File et pourquoi ne pas utiliser Zend_Cache_Frontend_ Pour en finir avec le code la classe Zend_Cache_
Class ? Tout simplement parce que cette classe va lier Core offre les méthodes suivantes :
l'enregistrement au fichier source et donc invalider le
cache si ce fichier est modifié. Pratique non ! • un constructeur qui sera utilisé par la fabrique du
cache,
J'en vois déjà quelques uns se plaindre et dire : il est où • une fonction setConfig() qui permet de configurer
le code ! Et bien en voici un tout petit peu. Je ne vais pas le frontend de cache (juste au cas où vous auriez
parcourir tous les objets car la documentation Zend me besoin de changer la conf définie dans la fabrique)
semble très précise sauf sur un point. La définition de cela utilise un objet Zend_Config que nous avons
l'ID quand on enregistre une donnée. Prenons le Listing vu dans les articles précédents,
1 issu de la documentation ZEND. Ce listing décrit la • setBackend() toujours au cas ou vous voudriez
méthode la plus simple pour gérer un enregistrement, changer le backend à la volée …
en cache, d'une données calculées. La première fois • getBackend () le nom de la fonction parle de lui
que je l'ai lu je me suis demandé mais comment l'Id même,
'myBigLoop' est-il affecté à l'enregistrement ! D'après • setOption () pour changer une option de la
vous ? … et bien regardons le Listing 2 qui est un extrait config,
de la classe Zend_Cache_Core qui sert de socle com- • getOption () sans commentaires,
mun à toutes les classes de cache frontend. Alors vous • load () que nous avons déjà vu et qui permet de
avez compris ? Et oui le $cache->load($id) à stocker charger un élément placé en cache via son Id,
dans la variable privé $lastId 'myBigLoop' et sans Id • test() qui ne fait que vérifier si l'enregistrement as-
précisé dans la fonction $cache->save() c'est celui-ci socié à un Id existe,
qui est utilisé. Impossible (ou presque) de le deviner • save() que nous avons déjà vu et qui enregistre un
sans regarder la classe. Et bien à mon avis cette prati- document,
que est très mauvaise et je vous invite à systématique- • remove() qui permet de retirer un enregistrement
ment remettre l'Id lors de l'appel à la fonction save() du cache,
afin que votre code soit facilement lisible sans recher- • clean() qui permet de nettoyer le cache soit en
cher 10, 20, 100 lignes plus avant le dernier Id utilisé ! fonction d'un tag, d'un timestamp (enlève ce qui est
Par cette petite étude du code, vous aurez compris plus vieux) ou tout ! Attention c'est la valeur par dé-
que l'Id est important mais il y a un autre élément im- faut !

24 1/2011
Zend Framework

• Un certain nombre de fonctions liées à la gestion des de stocker des données en RAM. Enfin seul memca-
tags (promis on en reparle après) : getIdsNotMat- ched permet de partager des données entre plusieurs
chingTags, getIdsMatchingAnyTags, getTags. frontaux.
• Vous avez besoin de récupérer les Id alors getIds 4. Vous vous dites qu'un savant mélange de ces
est fait pour vous. deux solutions vous permettrait d'avoir des données
mouvantes en cache rapide et d'autres plus stables
Cette classe est surchargée pour tout les types de en cache disque. Et bien Zend a penser à vous avec
frontend spécifiques présentés ci avant et qui offrent Zend_Cache_Backend_TwoLevels qui en fonction de
au moins ces interfaces plus quelques fonctions dé- la priorité (si si c'est aussi un des paramètre de la fonc-
diées. tion save() du Listing 2) affectée à l'enregistrement et
de la place libre en cache rapide distribuera entre les
La Factory deux backends votre enregistrement. Memcached per-
J'ai déjà abordé ce sujet et je pense que vous l'aurez met de faire ses opérations aussi par sa propre confi-
compris, on n'instancie pas directement les objets de guration.
cache mais on utilise une factory. Le Listing 3 donne
un extrait de la doc Zend pour illustrer l'usage de cette Voilà, nous avons fait un voyage dans le monde du ca-
factory. C'est très simple, on définit des options pour le che Zend ! J'espère que cette carte routière vous facili-
frontend et le backend et on les passe à l'objet static tera l'accès à ces éléments.
Zend_Cache::factory.
Le frontend Core je vous en ai déjà parlé mais qu'est- Conclusion
ce que ce backend File … voyons cela en détail. Nous venons de voir comment étudier sa politique de
cache et comment l'implémenter du coté applicatif avec
Les backends le Zend Framework.
Voyons maintenant la notion de backend. Comme je Je souhaite attirer votre attention sur le fait que la
vous l'ai dit précédemment elle correspond aux moyens grande ouverture, le nombre important de classes dis-
physiques de réaliser la mise en cache, l'enregistre- ponibles peuvent rendre la relecture du code difficile et
ment. Comment choisir ? Voici quelques points : donc, centraliser sa gestion de cache me semble une
bonne pratique qui rend le code plus lisible.
1. Votre application tourne sur une Zend plateforme
alors je pense (mais je n'ai jamais testé désolé) que
le backend Zend_Cache_Backend_ZendPlatform qui
a l'avantage de pouvoir gérer des tags est fait pour
vous. Mais c'est quoi, un tag ? Si vous avez bien lu l'ex-
trait de la classe du Listing 2, il est possible de spécifier
un tag lors de l'enregistrement. Ce tag permet alors de
gérer de l'invalidation ou plus exactement le nettoyage
de vos enregistrements en se basant sur un tag donné.
Cette fonctionnalité n'est pas disponible avec tous les
backends.
2. Votre application est sur un serveur mutualisé
avec de l'espace disque et sans que vous ayez la main
sur l'architecture alors vous voudrez sans doute enre-
gistrer le cache en système de fichier, Pour cela deux
backends sont disponibles Zend_Cache_Backend_File
et Zend_Cache_Backend_Sqlite. Le seul inconvénient
est que ce type de cache n'est pas très rapide et que
donc il ne faudra pas faire trop d'enregistrement (un peu
plus avec Sqlite) sinon la fourniture de l'enregistrement Stéphane Guédon
deviendra aussi longue que le calcul et vous n'aurez fait L’auteur travaille au sein de Bestofmedia Group qui est l’un des trois
que déplacer le problème. plus grands groupes média internet high-tech au monde, et plus lar-
3. Vous maîtrisez votre architecture ou vous avez un gement au sein de sociétés de développement d’applications infor-
serveur avec beaucoup de RAM alors vous pouvez uti- matiques et ce depuis une vingtaine d’années. Tour à tour responsa-
liser des caches plus rapides qui stockent en RAM. Le ble de développement, consultant pour une grande société de servi-
Framework Zend en gère 3 : APC, Memcached et Xca- ces d’un groupe international et responsable de la Direction Techni-
che. Premier point : aucun d'entre eux ne gère les tags. que Nationale PHP je me suis passionné pour le framework Zend
Second point il peut devenir riche (au prix de la RAM) et souhaite partager mes découvertes.

www.phpsolmag.org 25
Pratique

Développer
un centre d’appel avec Asterisk
et vtigerCRM
Asterisk est un PBX (Private Branch eXchange ou
autocommutateur telephonique Privé) open source destiné
auxentreprises et vtigerCRM est l’un des meilleurs CRM
(Customer Relationship Management ou Gestion de rélation
client), en OpenSource. Ils sont utilisés par des nombreux projets
Open Source pour les centres d’appel comme ELASTIX.

Cet article explique : Ce qu’il faut savoir :


• Le fonctionnement du système de téléphonie Asterisk. • Vous devez connaître les bases du langage PHP, l'extension so-
• Le fonctionnement du CRM vtigerCRM. cket de PHP, l'extension CURL de PHP, du bash, des notions sur
• Comment installer et configurer Asterisk. les protocoles SIP, UDP, TCP et les entrées sorties standard de
• Comment créer un dialplan Asterisk. LINUX.
• Comment interfacer Asterisk avec le langage PHP.

D
ans ce second article de notre série, nous allons ou depuis Internet grâce à un simple navigateur. Inté-
parler du VtigerCRM. En premier lieu, vTiger gralement distribuée sous licence libre (LGPL depuis la
CRM est une application intégrée de gestion de version 5), la solution vTiger CRM est principalement
la relation client (CRM), aisément utilisable en Intranet destinée aux PME/PMI opérant en mode BtoB, même

Figure 1. Page d’installation de vitgerCRM 

26 1/2011
Asterisk et vtigerCRM

Figure 2. Page d’accueil de vitgerCRM 

si elle satisfait également les besoins des organisations Listing 1. Décompression et copie des fichiers vers la racine d’apache
non-commerciales et des associations ainsi que des
cd /home/
départements ou filiales de grandes entreprises. tar -xvzf vtigercrm.5.2.1.tar.gz
Au cours de cettarticle, nous verrons : cp -Rvf vtigercrm /var/www

Listing 2. Installation des dépendance


• quel sont les modules principaux de VtigerCRM,
apt-get install php5-imap
• comment installer VtigerCRM, apt-get install php5-gd
• comment configurer VtigerCRM pour interagir avec apt-get install unzip
apt-get install php5-mysql
Asterisk.
Listing 3. Modification de php.ini
Le CRM a pour but de créer et entretenir une relation max _ execution _ time = 600
mutuellement bénéfique entre une entreprise et ses output _ buffering = On
post _ max _ size = 18M
clients. Dans ce mode de relations commerciales, l’en- upload _ max _ filesize = 10M
treprise s’attache à la fidélité du client en lui offrant allow _ call _ time _ pass _ reference = On
une qualité de service qu’il ne trouverait pas ailleurs.
Listing 4. Création de fichier de vtigercrm
L’image souvent employée pour illustrer ce concept est
celle de la relation entre un petit commerçant et ses cd /var/www/vtigercrm
chmod 777 config.inc.php
clients. La fidélité de ces derniers est récompensée chmod 777 tabdata.php
car le commerçant connaît leurs attentes et est capa- chmod 777 install.php
chmod 777 parent _ tabdata.php
ble d’y répondre et de les anticiper. Le CRM recouvre chmod 777 -Rf cache/
une partie des concepts plus anciens de SFA pour Sa- chmod 777 -Rf storage/
chmod 777 -Rf install/
les Force Automation (automatisation de la force de chmod 777 -Rf user _ privilieges/
vente). chmod 777 -Rf Smarty/cache/
chmod 777 -Rf Smarty/templates _ c/
Le SFA (Automatisation des Forces de Vente) est la chmod 777 -Rf modules/Emails/templates/
chmod 777 -Rf modules/
Gestion des prospects, comptes clients, contact et affaire. chmod 777 -Rf cron/modules/
Il peut importer des données depuis une source externe chmod 777 -Rf test/vtlib/
chmod 777 -Rf backup/
comme un telechargement Web, un forum, une conféren- chmod 777 -Rf Smarty/templates/modules/
ce ou directement d’un email. Il peut exporter des données chmod 777 -Rf test/wordtemplatedownload/
chmod 777 -Rf test/
vers un tableur que Microsoft® Excel®, OpenOffice® Calc chmod 777 -Rf logs
et d’autres logiciels pour analyser le suivi des ventes et/ou

www.phpsolmag.org 27
Pratique

Figure 3. Page d’accueil de vitgerCRM 

Figure 4. Page de configuration d’asterisk

identifier rapidement les éventuelles surcharges. Il permet Le SAV (Service d’Assistance Utilisateur) est le rou-
un partage d’informations liées aux clients entre collabo- tage des réquetes clients. C’est à dire qu’il gère la ges-
rateurs. Il est aussi possible de joindre des documents tion des tickets d’incident,la notification du statut du tic-
aux fiches clients. ket au client, l’historique complet d’un ticket, la base de

28 1/2011
Asterisk et vtigerCRM

connaissance, et Foires Aux Questions, l’intégration


d’un portail de service d’aide au client et Analyse statis-
tique des tickets d’incident pour une meilleure gestion
des services d’assistance.
La Gestion des stocks contrôle la cycle de vie des
produits, la differenciation des tarifications produits en
fonction des segments de marché, la liste des produits
sélectionnés par vos vendeurs et le cycle de gestion
des ventes avec traitement intégré des devis, des com-
mandes, et des facturations.
L’integration des emails et l’affectation des emails
entrants aux contact, la gestion des listes d’envoi
(mailing-lists) et l’envoi d’emailings au format HTML ou
en masse à vos contact et à ‘autres utilisateurs.
Les rapports et tableaux de bord sont l entièrement
personnalisables dans tous les modules, analyses Figure 5. Page de configuration d’asterisk
du cycle de vente par stade (sales tunnel), analyses
de ventes mensuelles, analyses par prescripteur, ta- Avant de faire l’installation à partir du web, il faut
bleaux de bord par stade de vente et par opportunité d’abord installer les dépendances. Ensuite modifier le
d’affaire. fichier php.ini dans /etc/php5/apache2/php.ini. Après on
La gestion de sécurité est la gestion des profils uti- va créer les fichiers de configuration du vtigercrm.
lisateurs et droits d’accès, création des rôles d’equipe Passons maitenant à l’installation via web. L’instal-
selon votre organisation interne, gestion de l’accès aux lation web de vtigerCRM est très intuitive, il faut juste
modules selon les rôles, journal d’accès de chaque uti- suivre les indications dans l’interface. Après avoir fter-
lisateur. miné l’installation, on accède à la page d’accueil de
La personnalisation du Produit est la possibilité vtigerCRM.
d’ajout de champs personnalisés dans tous les modules Après avoir entré le login et le mot de passe. On
(texte, nombres, devises, listes de sélection et autres entre dans l’interface principale de vtigerCRM. Nous al-
en fonction des besoins de gestion), la personnalisa- lons faire un tour dans la configuration pour activer l’in-
tion des onglets selon vos besoins en utilisant la fonc- teraction par défaut avec asterisk pour le click to dial.
tion glisser/déposer afin de masquer les modules qui ne Nous allons completer l’adresse IP du serveur Aste-
sont pas directement liés à vos processus de vente et la risk par 127.0.0.1 s’ils sont dans la même machine, le
personnalisation de l’interface utilisateur. port d’asterisk par 5038, le login Asterisk par le nom de
Le plugin-in vTiger pour Outlook® est la synchro- la section d’asterisk et le mot de passe dans manager.
nisation des emails entre Microsoft Outlook et vTiger conf d’asterisk. Dans le prochaine tutoriel, nous allons
CRM, la synchronisation des contacts entre Microsoft développer un module de vtiger pour la remontée de fi-
Outlook et vTiger CRM et la synchronisation des tâ- che client lors d’un appel entrant par le biais de vtlib.
ches et évènements entre Microsoft Outlook et vTiger Dans le prochain tutoriel nous allons créer un nou-
CRM.Le plug-in vTiger pour Office® et la création de veau module de vtiger-CRM et le faire interagir avec
modèles de publipostage directement depuis Micro- Asterisk. Nous verrons ensuite comment le faire intera-
soft Word à partir de la base de données client de gir via le webmanager d’asterisk en utilisant l’extension
vTiger CRM, Création à la demande vos documents CURL de PHP.
de publipostage vers vos prescripteurs, vos rendez-
vous et vos clients et vos contacts à partir de vTiger
CRM.
Avec l’extension vTiger pour Thunderbird, on peut
ajouter vos emails entrants de votre messagerie Mozilla
Thunderbird vers vTiger CRM, Importer vos contacts de Randriamifidy Bezama Marolahy
vTiger CRM vers Mozilla Thunderbird et Exporter vos L’auteur travaille en tant que consultant ntic (Nouvelles Techno-
adresses clients de Mozilla Thunderbird vers vTiger- logies de l’Information et de la Communication) au sein de Team-
CRM. Well Système un SSII spécialisé dans le développement web et appli-
Pour installer vTigerCRM, allez dans le site de www. cations sur la ToIP (Téléphonie over Internet Protocol). Il réalise plu-
vtigercrm.com ou dans www.sourceforge.net pour té- sieurs applications web et applications internet riches. Passionné
lécharger la derniere version du code source de vTi- de nouvelles technologies, il cherche toujours à améliorer ses com-
gerCRM et décompressez le dans votre racine web du pétences en tant que développeur et administrateur système.
serveur. Pour le contacter veuillez envoyer un mail à marolahy@gmail.com.

www.phpsolmag.org 29
Fiche technique

Guide de conception
de formulaires en HTML avec traitement
PHP, ergonomie, accessibilité
Le formulaire est un moyen de faire interagir le visiteur
avec votre site. Moteur de recherche, espace de contact
ou encore forum de discussion, nombreuses sont
ses applications. Comment les concevoir et les traiter ?

Cet article explique : Ce qu'il faut savoir :


• Comment écrire un formulaire en HTML avec des notions de • Écrire une page HTML, en doctype HTML ou XHTML (cet article se-
sémantique, ergonomie et accessibilité. ra basé sur l’HTML Strict, mais le principe est le même en XHTML).
• Une méthode de traitement via le langage PHP. • Débugger un script PHP et raisonner pas à pas.
• Des moyens de sécuriser des formulaires. • Quelques configurations serveur (droits d’écriture, configura-
tion PHP) pour les téléchargements de fichiers.
• Des notions de méthodes de conception (p.ex. MVC) non
abordées ici afin de l’optimiser pour votre site.

U
n formulaire se traite en deux parties sur un Tour d’horizon des principales
site Web : une partie affichage écrite en lan- balises HTML utilisées
gage HTML qui invite l’utilisateur à interagir Dans sa norme, l’HTML propose un vaste choix de ba-
avec le site, et toutes ses données sont ensuite en- lises pour construire un formulaire. En utilisant à bon
voyées à un programme PHP sur le serveur qui va escient ces balises, il est possible de rendre ergono-
effectuer le traitement du formulaire. Ce principe est mique le formulaire, c’est-à-dire plus intuitif à la mani-
régi par l’architecture client/serveur d’Apache, où le pulation.
serveur envoie les données et le client (représenté Le formulaire s’ouvre par une balise <form>
par la machine de l’utilisateur final), en bout de chaî- et se ferme par une balise </form> . Ces balises en
ne, qui les reçoit. contiennent d’autres, divisées en plusieurs catégo-
ries :
Construction du formulaire : première étape
Pour construire un formulaire en HTML, nous allons ré- • Les balises de division représentées par les jeux de
fléchir à sa conception. La première étape est de re- champs (fieldset).
grouper les données de même nature. Il est plus logi- • Les balises de saisie, représentées par les zones
que de demander nom, prénom, code postal, ville que de texte (textarea, input).
nom, couleur des cheveux, choix de voiture, code pos- • Les balises de choix (menus déroulants, cases, ra-
tal, film préféré, ville. dios).
Une fois cette première étape faite, il faut ordonnan- • Les balises d’action, représentées par les boutons
cer la saisie des données. Saisir le code postal avant (valider, …).
le nom, si la ville est en fin de formulaire, peut paraître
illogique. Bien entendu, chaque balise peut avoir quelques spéci-
Enfin, une fois que ces deux points sont traités, pen- ficités, nous y reviendrons après.
ser à diviser – si applicable – le formulaire en sections,
très utile dans le cas d’un sondage par exemple, pour Balises d’ouverture
présenter une suite de X pages plutôt qu’une page uni- Il s’agit des balises <form> et </form>. Ces balises
que de mille lignes. sont obligatoires.

30 1/2011
Formulaire en HTML

La balise <form> accepte plusieurs attributs :

• Un attribut id permettant de l’identifier de manière


unique dans la page HTML.
• Un attribut action qui est l’adresse de la ressource
où sera envoyé le formulaire. Dans le cadre de cet
article, nous mettrons une page PHP.
• Un attribut method qui peut prendre deux valeurs,
POST ou GET.
• GET passe les données du formulaire en texte dans
l’adresse du navigateur.
• POST les passe en caché ; c’est donc plus esthéti-
que. POST permet également d’envoyer un fichier.
• Un attribut enctype pour l’encodage des données
du formulaire, qui peut être omis dans le cas de Figure 1. Regroupement logique des champs de formulaire en
textes simples mais qui devient obligatoire dès l’at- différents fieldset
tachement d’un fichier, pour spécifier que le conte-
nu que le formulaire envoi est de plusieurs natu-
res.

Remarque : en écriture XHTML Strict, les attributs sont


écrits en minuscules et leurs valeurs sont entourées de
guillemets doubles.

Balises de division visuelle


La principale balise pour regrouper visuellement des
champs est la balise <fieldset>. Graphiquement, el-
le produit sur le navigateur une bordure (dont les pro-
priétés sont ajustables via CSS) qui entoure tous les
champs qu’elle contient. Cette balise est doublée d’une
balise <legend> pour donner un titre à cette zone de Figure 2. Classement hiérarchique des options d’un menu Select
champs (cf. Figure 1).
signer quelqu’un. Et de la même façon, utiliser un type
Balises de saisie de texte checkbox pour demander plusieurs informations sur un
Ces balises servent àę envoyer des données fournies même thème (films préférés …).
par le visiteur. Il y a également la balise <select> qui permet de
Le <textarea> permet d’envoyer un texte multiligne créer un menu déroulant. Cette balise se couple à deux
tandis que le <input type="texte"> permet d’envoyer autres sous-balises :
une ligne simple.
On trouve également le <input type="hidden"> • Les balises <option> qui sont les items du menu
qui permet d’envoyer un contenu textuel caché (utile déroulant.
pour passer du contenu qui n’a pas besoin d’être sé- • Les balises <optgroup> qui permettent de hiérar-
curisé de page en page par exemple). Sans oublier le chiser visuellement les <option> (Cf. Figure 2).
<input type="file"> qui permet l’envoi d’un fichier.
Balises d’action
Balises de choix Encore une fois, la balise <input> est retrouvée dans
Nous y retrouvons le <input> avec deux types parti- cette catégorie :
culiers :
• <input type="button"> pour créer un bouton gé-
• La checkbox, case à cocher, pour proposer un nérique,
choix à réponses multiples. • <input type="reset"> pour créer un bouton qui
• Le type radio pour proposer une réponse unique réinitialise le formulaire (aux valeurs par défaut des
parmi un choix multiple. champs),
• <input type="submit"> pour exécuter le formu-
Il est tout à fait logique d’utiliser un type radio pour la laire, c’est-à-dire envoyer au paramètre action les
civilité : Monsieur, Madame ou Mademoiselle pour dé- données collectées.

www.phpsolmag.org 31
Fiche technique

L’attribut name des balises est une suite de caractè-


Listing 1. Écriture d’un textarea
res qui répond aux règles suivantes :
<textarea name="MaZoneDeTexte">le texte par défaut
ici</textarea>
• Il doit commencer par une lettre ou un underscore.
Listing 2. Insertion d’attribut TabIndex dans un champ de • Il ne peut pas contenir d’espaces, de signe de
formulaire ponctuation ou autre caractères que les lettres non
<input type="text" name="nom" tabindex="1"> <input accentuées et chiffres.
type="text" name="prenom" tabindex="2"> • Il est sensible à la casse (prenom sera différent de
Listing 3. Une erreur à éviter Prenom).

<p>Votre nom ici : <input type="text" name="nom"


tabindex="1"></p>
Partie HTML : ergonomie et accessibilité
Si vous avez suivi cet article depuis le début, des as-
Listing 4. La balise <label> permet de lier logiquement le tuces ergonomiques ont été diffusées dans les bali-
champ à sa légende
ses : optgroup pour les menus déroulants, fieldset/
<p><label>Votre nom ici : <input type="text" legend pour démarquer les zones.
name="nom" tabindex="1"></label></p>
Afin d’apporter un peu plus de confort à votre visi-
Listing 5. Label englobant la légende d’un champ et le reliant teur, d’autres astuces peuvent être utilisées :
à ce dernier, avec champ positionné ailleurs dans la page
<table> 1. L’utilisation des tabindex qui sont des attributs
<tr> à valeurs numérique. Le tabindex permet de définir une
<td><label for="champNom">Votre nom ici :</label></
td> suite de champs qui seront activés lorsque l’utilisateur
<td><input type="text" name="nom" tabindex="1" pressera le bouton tabulation (Cf. Listing 2).
id="champNom"></td>
</tr> Quel que soit l’ordre de ces balises dans le code
</table> source, ou même leur position dans la page HTML,
Listing 6. Récupération de variables : checkboxes le prénom sera toujours activé après le nom, premier
champ du formulaire activé.
$ _ POST['nameBleu'] => on
$ _ POST['nameVert'] => on
2. L’utilisation d’étiquettes : par défaut, un champ
de formulaire est un objet (au sens programmation du
Informations communes à toutes les balises terme) et lorsque vous créez un <input type="text"
Chaque balise peut présenter une valeur par défaut name="nom" tabindex="1"> vous créez en réalité un
avec le paramètre value=’’votre valeur par défaut ici’’. objet contenant du texte. Mais sans lire le nom, on ne
Dans un textarea, la value ne pouvant pas contenir sait pas nativement à quoi ce champ sert. Bien sûr, vous
(ou restituer) plusieurs lignes, cet attribut n’est pas dis- serez vite tenté d’écrire ce qu’il y a dans le Listing 3.
ponible. Le textarea a donc une balise fermante pour Ce qui n’est pas faux visuellement, mais qui présen-
délimiter le texte  (cf. Listing 1). te tout de même une lacune sémantiquement parlant.
Pour les boutons, la value est le texte affiché visuel- En effet, bien que le champ et le texte qui le précède
lement. soient dans le même paragraphe, ils ne sont pas reliés
Pour les menus déroulants, l’attribut value doit se pour autant. Pour les relier, vous devez mettre une éti-
placer dans chaque <option>. Des attributs disabled quette qui englobera le tout (Listing 4).
ou readonly permettent respectivement de désactiver Vous pouvez aussi utiliser un ID sur l’input et le dé-
ce champ ou de le mettre en lecture seule. La donnée clarer dans le label si vous devez séparer les deux élé-
ne sera alors pas envoyée au traitement. ments (cas d’un tableau par exemple). Voir Listing 5.
Vous remarquerez que l’input a maintenant un attri-
Nommage des balises but ID qui correspond au for du label.
Le but du formulaire est de le traiter. Pour cela, il faut Maintenant le texte Votre nom ici et l’input sont sé-
pouvoir récupérer le contenu de chaque item envoyé mantiquement reliés !
au serveur. C’est là qu’intervient le nommage des ba- Pour le confort de l’utilisateur, il pourra cliquer sur la
lises. légende du champ (Votre nom ici) et son curseur sera
Chaque balise présente un attribut name qui est le directement dans le bon champ !
nom de la future variable que le serveur va créer pour
stocker le contenu envoyé. 3. L’utilisation d’attributs Javascript : cette méthode
Par exemple <input type="text" name="prenom"> permet de mettre une classe CSS particulière lorsque
créera une variable nommée prenom sur le serveur l’utilisateur clique sur le champ (couleur de fond dif-
et cette variable contiendra le prénom saisi par l’utili- férente par exemple) et une autre couleur lorsqu’il le
sateur ! quitte.

32 1/2011
Formulaire en HTML

Figure 3. Injection SQL : le fait d’avoir mis en commentaire une partie de la requête simplifie la connexion

Ainsi chaque balise de formulaire peut se voir do-


tée de l’attribut onfocus (focus sur le champ, champ
activé) et onblur (champ désactivé). Le menu dérou-
lant <select> a en plus un attribut onchange qui per-
met d’exécuter une action Javascript quand l’utilisa- Figure 4. Injection d’emails : voici le résultat du mail envoyé. La
teur change d’item choisi. victime recevra le mail, mais elle ne sera pas la seule

L’accessibilité est une méthode de conception vi- PHP. Par exemple, supposons 3 cases à cocher : bleu,
sant à permettre l’accès aux informations selon rouge, vert avec pour name respectifs : nameBleu,
plusieurs chemins, pour des personnes handica- nameRouge, nameVert. Si le visiteur choisit bleu
pées moteur, malvoyantes, ou aveugles. Un formu- et vert, alors on aura (Listing 6).
laire présentant des label lors d’une lecture par un (mais $_POST['nameRouge'] n’existera pas)
synthétiseur vocal permettra de lire à voix haute le
contenu du label dès que la personne a le focus sur 2. Sécurisation des variables
le champ. Cette étape est très importante. Elle permet de
s’assurer que les variables ne contiennent pas un
Partie PHP contenu qui pourrait occasionner des dégâts (cf. §sé-
Une fois votre formulaire HTML écrit, affiché chez le vi- curité).
siteur, il faut maintenant le traiter, c’est-à-dire exécuter Plein de méthodes existent pour sécuriser des va-
l’action que vous avez prévue. riables : le transtypage (intval, abs, sprintf) ou les re-
Le traitement de formulaire en PHP peut se décou- quêtes préparées ou encore l’échappement complet
per en plusieurs phases : des caractères (mysql_escape_strings, mysql_
real_escape_strings), ou encore les expressions ra-
1. Récupération des variables du formulaire. tionnelles (regexp) sont les solutions les plus commu-
2. Sécurisation des variables. nément utilisées. Une variable non sécurisée est une
3. Exécution du traitement proprement dit. potentielle faille de sécurité ! Toutes les variables doi-
4. Message récapitulatif envoyé en HTML si besoin. vent être sécurisées côté serveur (PHP). Il n’y a aucu-
ne sécurité en Javascript, celui-ci pouvant être désac-
Ces étapes ne sont pas une méthode particulière, mais tivé sur le client.
un simple moyen de résumer (arbitrairement) la chrono-
logie des étapes. 3. Exécution du traitement proprement dit
Cette partie permet de faire ce que vous attendez
1. Récupération des variables réellement de votre formulaire : inscrire un nouvel
A chaque chargement de page, PHP crée (entre abonné (requêtes SQL), envoyer un email, effectuer
autre) des variables (super globales) que sont $_POST, une recherche dans un fichier ou une base de don-
$_GET et $_FILES. Ce sont des tableaux associatifs nées…
(liste de clés paires => valeur).
Si votre formulaire a pour méthode method="get" 4. Message récapitulatif
alors c'est $_GET qui sera rempli. Autrement, c’est Votre email nous est bien parvenu, aucune répon-
$_POST. se n’a été trouvée pour l’article que vous avez deman-
$_FILES est rempli lorsque vous avez mis un champ dé… sont autant d’indications pour indiquer au visiteur
<input type=’’file’’> (téléchargement de fichier). que sa demande est finie, réussie, ou tout autre point
Enfin, chaque clé du tableau associatif porte le nom d’avancement. Cette étape peut ne pas exister dans le
(name) du champ de formulaire. Par exemple si en cadre de formulaires plus complexes (sondage multi-
HTML on a : pages, etc.).
<input type="text" name="prenom">. Avec un
formulaire passé en method="post", on aura $_ Formulaire et sécurité
POST['prenom'] qui contiendra ce que le visiteur a sai- Comme dit précédemment, la sécurité est primordia-
si. Pour un formulaire passé en get, on aurait utilisé le. La notion la plus importante est de retenir que
$_GET['prenom']. toute donnée venant d’un visiteur est potentielle-
Attention aux checkbox qui renvoient soit on comme ment vérolée. Il faut tout revérifier au niveau du trai-
valeur si la case est cochée, soit qui n’existent pas en tement.

www.phpsolmag.org 33
Fiche technique

Figure 5. Un exemple d’avatar en .JPG d’un hackeur, l’entête du fichier contient les informations .JPG et le reste, par du code malicieux,
donne des informations

Il n’y a aucune sécurité en HTML ou en Javascript : leur est ensuite mise dans les headers du mail. Si un visi-
ce sont des langages s’exécutant sur le navigateur Web teur injecte un Cc ou un Bcc (Carbon Copy ou Blind Car-
du visiteur et celui-ci a tout pouvoir dessus. 15% des in- bon Copy) votre formulaire peut devenir un nid à spam
ternautes naviguent d’ailleurs sans Javascript ! (cf. Figure 4).
N’oubliez pas que le Javascript ne doit pas être in-
trusif mais une aide pratique pour faire des vérifications L’exécution de code source
qui, de toute façon, seront refaites dans le traitement du Vous proposez de télécharger, pour un CV par exemple,
formulaire. la photo du candidat. Une image non vérifiée peut, si les
Enfin, les tableaux POST/GET étant créés par envoi droits sur le serveur ne sont pas bons, donner lieu à une
de données, il faut vérifier ce que vous recevez. exécution de code source malicieux (cf. Figure 5).
Voici quelques failles de sécurité bien connues.

L’injection SQL
Consiste à utiliser une variable pour y placer du code
SQL. Sans protection, la requête modifiée peut s’avérer
destructrice…

L’injection d’emails
Cas typique des pages de formulaire de contact. Un
champ type texte demande l’email du visiteur et cette va- Matthieu LACROIX
L’auteur est ingénieur systèmes et réseaux dans une PME parisien-
Sur Internet ne, en charge d’un parc de cent cinquante machines sous Windows
(XP, 7), Linux (Red Hat, Debian) ainsi que des serveurs Windows 2008,
• http://www.phpsecure.info/ – Tutoriaux en ligne pour sé- HyperV, SAN.
curiser des scripts PHP, Il développe également des solutions back-office/intranet en tant
• http://www.alsacreations.com/ – Aide HTML, CSS. qu’entrepreneur depuis quatre ans (http://www.newslettux.fr/ pré-
senté dans un précédent numéro de PHP Solutions).

34 1/2011
Formulaire en HTML

www.phpsolmag.org 35
Pour les débutants

SQL :
extraire des données
Les bases de données sont très utilisées dans les applications
Web. La création, l’interrogation et la manipulation
des données de la base sont réalisées en SQL. Dans
cet article, vous apprendrez à extraire des données
d’une table et à les trier avec SQL.

Cet article explique : Ce qu’il faut savoir :


• Comment extraire et trier des données. • Aucun prérequis.

D
ans l’article précédent sur le langage de mani- Trier les données
pulation des données, vous avez appris à in- Par défaut, les lignes extraites sont affichées dans l’or-
sérer, modifier et supprimer des données d’une dre d’insertion. La clause ORDER BY suivie d'une ou plu-
base. Dans ce numéro, vous allez apprendre à extraire sieurs colonnes permet de faire un tri sur ces colonnes.
un sous-ensemble d’informations des tables. Par défaut, elle trie par ordre croissant (ASC), mais la
Pour appliquer les notions présentées, vous devez condition DESC permet un tri décroissant. La clause OR-
utiliser un serveur de bases de données MySQL, de DER BY est toujours placée en fin d’instruction.
préférence la version 5, un serveur web avec PHP ver-
sion 5 et le client graphique phpMyAdmin. Les distribu- SELECT * FROM nom _ table ORDER BY col1 [ASC |
tions XAMPP (Windows, Linux, Mac OS), WAMP (Win- DESC][, col2 [ASC | DESC], …];
dows), EasyPHP (Windows) ou MAMP (Mac OS) vous
fourniront l’environnement de travail nécessaire. L’instruction suivante trie les informations de la table
Les requêtes présentées peuvent être testées via une auteur par ordre alphabétique sur la colonne nom :
console SQL ou en mode graphique dans phpMyAdmin.
Dans cet article, nous allons utiliser l’exemple d’une SELECT * FROM auteur ORDER BY nom;
bibliothèque privée dont le schéma a été présenté dans
un article paru dans le magazine précédent (N°11/2010 - Si plusieurs colonnes sont citées après la clause ORDER
SQL : langage de manipulation des données). Les don- BY, le tri sera d’abord effectué sur la première colon-
nées insérées dans les tables auteur et livre sont celles ne renseignée, puis sur la deuxième, etc. Par exemple
figurant dans les tableaux 1 et 2. pour trier la table auteur suivant leurs noms dans l’or-
dre croissant, puis suivant leurs prénoms dans l’ordre
Sélectionner les données décroissant, il faut utiliser la commande :
La commande SQL SELECT suivie du caractère * permet
d’extraire toutes les données d’une table : SELECT * FROM auteur ORDER BY nom ASC, prenom
DESC;
SELECT * FROM nom _ table;
Par exemple, pour afficher toutes les lignes de toutes les Sélectionner un sous-ensemble de colonnes
colonnes de la table auteur (tableau 1), il faut utiliser la Il est possible d’afficher un sous-ensemble de colonnes
requête suivante : d’une table en effectuant une projection. Celle-ci est ob-
tenue en indiquant une liste de colonnes devant la clau-
SELECT * FROM auteur; se FROM, en les séparant par des virgules. Derrière

36 1/2011
SQL Select

le FROM sera indiquée la table concernée. Le résultat


d’une projection est une table comportant uniquement
les colonnes indiquées. Afin d'éviter l'affichage des dou-
blons, il faut utiliser le mot-clé DISTINCT.

SELECT [DISTINCT] col1[, col2, …] FROM nom _


table;

L’affichage de tous les livres insérés dans la base, ainsi


que leur genre et leur date de parution, triés par ordre
de parution (tableau 3), est possible grâce à l’instruction
suivante :

SELECT titre, genre, date _ parution FROM Figure 1. Extraire des données depuis phpMyAdmin
livre ORDER BY date _ parution;
SELECT titre, date _ parution FROM livre
Pour afficher les genres présents dans la base, on peut WHERE date _ parution >= 1950 AND date _
utiliser la requête : parution <= 1980;

SELECT genre FROM livre; La requête précédente peut également être écrite grâce
à l’expression nb BETWEEN min AND max qui retourne
Cette requête renvoie les genres pour chaque livre insé- vrai si le nombre nb est compris entre les bornes min
ré dans la base. Il apparaîtra donc plusieurs fois ‘roman’ et max :
et ‘theatre’. Pour afficher une liste ne comprenant qu’une
unique fois chaque genre, il faut utiliser DISTINCT : SELECT titre, date _ parution FROM livre WHERE
date _ parution BETWEEN 1950 AND 1980;
SELECT DISTINCT genre FROM livre;
Par contre, pour comparer les champs d’une colonne
Sélectionner un sous-ensemble de lignes à une liste, il faut utiliser l’expression nb IN (val1[,
La clause WHERE permet de définir une condition afin val2, …]) qui retourne vrai si nb appartient à une des
de sélectionner un sous-ensemble de lignes d'une ta- valeurs indiquées.
ble. Celle-ci est une expression comportant un ou plu- L’instruction suivante permet d’afficher seulement
sieurs opérateurs (tableau 4) dont les opérandes sont les livres parus en 2008 ou en 2010 :
des noms de colonnes, des fonctions ou des constan-
tes. MySQL propose un grand nombre de fonctions sur SELECT titre, date _ parution FROM livre WHERE
les dates, les nombres et les chaînes de caractères. La date _ parution IN (2008,2010);
restriction affichera toutes les lignes de la table qui ré-
pondent à la condition. Chaînes de caractères
La restriction peut porter sur des chaînes de caractères.
SELECT col1[, col2, ...] FROM nom _ table WHERE Par exemple, pour afficher tous les romans :
condition;
SELECT titre, genre FROM livre WHERE genre =
Nombres 'roman';
Pour indiquer une condition quant à une colonne numé-
rique, il est possible d’utiliser des opérateurs relation- L’expression ch IN (val1[, val2, …]) fonctionne
nels, logiques, ainsi que les opérateurs BETWEEN ou IN. aussi pour les chaînes. Ainsi, l’instruction suivante per-
L’instruction suivante affiche les livres parus après met d’afficher les romans et les livres historiques :
1950, triés par date de parution :
SELECT titre, genre FROM livre WHERE genre IN
SELECT titre, date _ parution FROM livre ('roman','historique');
WHERE date _ parution > 1950 ORDER BY date _
parution; Il est également possible d’effectuer des comparaisons
sur des chaînes en utilisant l’opérateur LIKE. L’expres-
Les opérateurs logiques permettent de combiner des sion chaine LIKE motif retourne vrai si la chaîne in-
conditions. Par exemple, pour afficher les livres parus diquée correspond au motif spécifié. Le motif peut être
entre 1950 et 1980 : composé de lettres et/ou de symboles : le % représente

www.phpsolmag.org 37
Pour les débutants

Tableau 1. Contenu de la table AUTEUR


id_auteur nom prenom date_naissance
1 Follett Ken 1949-06-05
2 Dickens Charles 1812-06-09
3 Tolkien J. R. R. 1892-01-03
4 Molière Jean Baptiste 1622-01-15
5 Herbouiller Sophie NULL
6 Massonaud Christophe NULL

Tableau 2. Contenu de la table LIVRE


isbn titre genre date_parution langue nb_pages preface code_zone
128-5-56985-5 Fall of giants historique 2010 anglais 255 oui c20
952-5-15632-0 Un bunker à la Baule roman 2008 francais 226 non c10
320-2-02365-5 Le bourgeois gentilhomme theatre 1670 francais 152 NULL NULL
152-5-55695-2 Le seigneur des anneaux fantastique 1954 francais 832 non c8
523-5-65472-9 David Copperfield roman 1850 anglais 458 oui s8
320-2-02225-6 Amphitryon theatre 1668 francais 120 oui c18

Tableau 3. Sélection et tri d’un sous-ensemble de colonnes.


titre genre date_parution
Amphitryon theatre 1668
Le bourgeois gentilhomme theatre 1670
David Copperfield roman 1850
Le seigneur des anneaux fantastique 1954
Un bunker à la Baule roman 2008
Fall of giants historique 2010

Tableau 4. Opérateurs
Opérateurs SQL
Opérateurs arithmétiques
+ Addition
- Soustraction
* Multiplication
/ Division
Opérateurs logiques
AND Et (x AND y vrai uniquement si x vrai et y vrai)
OR Ou (x OR y faux uniquement si x faux et y faux)
NOT Non
Opérateurs relationnels
= Egal à
<> Différent de
< Inférieur à
<= Inférieur ou égal à
> Supérieur à
>= Supérieur ou égal à
Autres opérateurs
chaine LIKE motif Vrai si la chaine suit le motif
exp IN (val1, val2, ...) Vrai si l’expression appartient à une des valeurs
exp BETWEEN min AND max Vrai si l’expression est comprise entre les deux bornes
exp IS NULL Vrai si l’expression a la valeur NULL
exp IS NOT NULL Vrai si l’expression n’a pas la valeur NULL

38 1/2011
SQL Select

n’importe quelle chaîne et le _ représente un unique ca- Tableau 5. Colonne dérivée et tri
ractère quelconque. titre YEAR(NOW())-da-
L’instruction suivante affiche tous les livres dont le te_parution
code zone commence par un ‘C’ suivi de deux caractè- Amphitryon 343
res quelconques (dans le tableau 2, les livres qui ont les David Copperfield 161
codes zone : c10, c18 et c20) :
Fall of giants 1

SELECT titre FROM livre WHERE code _ zone LIKE Le bourgeois gentilhomme 341
'c _ _ '; Le seigneur des anneaux 57
Un bunker à la Baule 3
Par contre, la requête suivante renvoie tous les livres
dont le code zone commence par un ‘C’, quel que soit le Tableau 6. Colonne dérivée avec alias et tri
nombre de caractères (les livres dont le code zone est titre anciennete
c10, c18, c20 ou c8) : Fall of giants 1
Un bunker à la Baule 3
SELECT titre FROM livre WHERE code _ zone LIKE
Le seigneur des anneaux 57
'c%';
David Copperfield 161

Il est possible de définir des conditions sur des co- Le bourgeois gentilhomme 341
lonnes de type numérique et alphanumérique dans Amphitryon 343
une même requête. Pour afficher les romans parus
Tableau 7. Regroupement de données
après 1950, il faut exécuter :
ecrivain annee
SELECT titre FROM livre WHERE genre = 'roman' K. Follett 1949
AND date _ parution > 1950; C. Dickens 1812
J. Tolkien 1892
Dates
J. Molière 1622
La restriction peut porter sur des colonnes de type da-
S. Herbouiller NULL
te. Par exemple, pour afficher tous les auteurs nés au
XIXème siècle : C. Massonaud NULL

SELECT nom FROM auteur WHERE Créer des colonnes dérivées


YEAR(date _ naissance) BETWEEN 1800 AND 1899; Il est également possible d’extraire des informations
de manière personnalisée en créant des colonnes
La fonction MySQL YEAR retourne l’année de la date pas- qui ne sont pas présentes dans la base. Ces co-
sée en argument. La fonction MONTH retourne un numé- lonnes peuvent prendre des valeurs retournées par
ro entre 1 et 12 correspondant au mois. Pour lister les des fonctions ou des calculs. Ces colonnes ne sont
auteurs nés en juin : pas ajoutées dans la base de données, elles appa-
raissent uniquement lors de l'affichage du résultat
SELECT nom FROM auteur WHERE de la requête. Par exemple, on peut vouloir extraire
MONTH(date _ naissance) = 6; l’ancienneté d’un livre (tableau 5). Pour ce faire, il
suffit de retrancher la date de parution à la date du
NULL jour :
L’opérateur IS NULL permet de sélectionner les lignes
dont les champs ne sont pas renseignés. Pour extraire SELECT titre, YEAR(NOW())-date _ parution FROM
les lignes dont le code zone n’a pas été défini : livre ORDER BY titre;

SELECT titre FROM livre WHERE code _ zone IS La requête retourne un tableau de deux colon-
NULL; nes dont la première est intitulée ‘titre’ et l’autre
‘YEAR(NOW())-date_parution’. Pour renommer cet-
L’opérateur inverse serait IS NOT NULL. La requête sui- te colonne (tableau 6), il faut utiliser un alias (AS).. Il
vante extrait tous les livres dont le code zone est ren- est aussi possible de faire un tri sur cette nouvelle
seigné : colonne :

SELECT titre FROM livre WHERE code _ zone IS SELECT titre, (YEAR(NOW())-date _ parution) AS
NOT NULL; anciennete FROM livre ORDER BY anciennete;

www.phpsolmag.org 39
Pour les débutants

Tableau 8. Quelques fonctions MySQL prédéfinies


Fonctions MySQL
Fonctions sur les dates
DATEDIFF(date1, date2) Retourne le nombre de jour entre date1 et date2
MONTH(date) Retourne le mois de la date
NOW() Retourne la date courante
YEAR(date) Retourne l’année de la date
Fonctions sur les chaînes de caractères
CONCAT(ch1, ch2, ...) Retourne la concaténation des chaînes ch1, ch2, ...
LENGTH(ch) Retourne la longueur de la chaîne ch
SUBSTRING(ch, pos, lg) Retourne la sous-chaîne de ch débutant à l’indice pos et de taille lg
TRIM(ch) Retourne la chaîne ch sans les espaces ni à droite ni à gauche
Fonctions mathématiques
MOD(nb1,nb2) Retourne le reste de la division de nb1 par nb2 (modulo)
SQRT(nb) Retourne la racine carrée de nb
TRUNCATE(nb,dec) Retourne nb tronqué en fonction de la decimale dec

La requête suivante crée une colonne 'ecrivain' qui Cependant, cette interface ne permet pas actuellement
contient la liste des auteurs comprenant seulement la de faire de conditions multiples sur un champ. Il est no-
première lettre de leur prénom suivi d’un point et de tamment impossible de donner deux bornes à une date
leur nom (format : ‘C. Dickens’) ainsi qu’une colonne de parution.
contenant leur année de naissance, comme dans le
tableau 7 : Conclusion
Vous avez appris dans cet article à extraire et trier des
SELECT CONCAT(SUBSTRING(prenom,1,1),'. ',nom) données provenant d’une table. Grâce aux connais-
AS ecrivain, YEAR(date _ naissance) AS annee sances acquises dans cette série d’articles, vous êtes
FROM auteur; à présent à même de réaliser des bases de données
simples, d’y insérer des données et de les interroger.
Extraire des données L’article sur les jointures vous permettra d’interroger
avec phpMyAdmin plusieurs tables simultanément à la suite de quoi vous
L’interface Web phpMyAdmin permet d’extraire des don- verrez comment vous connecter à la base via PHP
nées via l’utilisation d’un formulaire. Une fois la base sé- avec PDO.
lectionnée sur la page d’accueil, il faut choisir la table
concernée dans le cadre de gauche. Un clic sur l’icô-
ne Rechercher dans le menu du cadre de droite per-
met d’afficher le formulaire d’extraction (figure 1). Il est
proposé une liste de conditions spécifiques à chaque
champ. Sous le bouton Options, une liste à choix mul-
tiples permet de réaliser une projection en choisissant
quelles colonnes devront s’afficher. La soumission du
formulaire génère automatiquement la requête, l’affiche
et l’envoie à MySQL. Sur la figure 1, il a été rempli pour
répondre à la requête :
Cilia Mauro, Magali Contensin
SELECT titre, date _ parution FROM livre Cilia Mauro est gestionnaire de bases de données et développeur
WHERE date _ parution > 1950 ORDER BY date _ d’applications web au CNRS. Elle enseigne les bases de données
parution; et PHP à l’université.
Contact : cilia.mro@gmail.com
Magali Contensin est chef de projet en développement d’applica-
Sur Internet
tions au CNRS. Elle enseigne depuis plus de dix ans le développe-
• http://www.phpmyadmin.net - phpMyAdmin ment d’applications web à l’université et est l’auteur de nombreux
• http://www.mysql.fr – MySQL, articles sur le développement web en PHP.
Contact : http://magali.contensin.online.fr

40 1/2011
Pour les débutants

SQL :
les jointures
Les bases de données sont très utilisées dans les applications
Web. La création, l’interrogation et la manipulation
des données de la base sont réalisées en SQL. Dans
cet article, vous apprendrez à extraire des données issues
de plusieurs tables avec SQL.

Cet article explique : Ce qu’il faut savoir :


• Comment extraire des données de plusieurs tables simulta- • Avoir lu l'article SQL : extraire des données (de ce même nu-
nément. méro).

D
ans les articles précédents vous avez appris les Cet article sera illustré par l'exemple d'une bibliothè-
bases du langage SQL. Vous êtes capables de que privée (Figure 1) dont les données insérées dans les
réaliser des bases de données simples, d’y in- tables auteur et livre sont les mêmes que dans l’arti-
sérer des données et de les interroger. Dans l’article cle sur l’extraction des données. Les données des tables
précédent (dans ce numéro : SQL : extraire des don- zone et ecrit apparaissent dans les tableaux 1 et 2.
nées), vous avez vu comment extraire des données Jusqu’à présent, vous avez extrait des données
d’une table. Cet article explique comment interroger d’une seule table. Parfois il est nécessaire de faire
plusieurs tables en même temps. une extraction sur plusieurs tables. Par exemple, pour
Afin d’appliquer les prochaines notions, il est né- afficher tous les livres présents dans une pièce don-
cessaire que vous utilisiez l’environnement de travail née, une solution est de passer par deux requêtes. La
présenté dans l’article précédent. L'interface Web première extrait les codes zone d’intérêt, ici pour une
phpMyAdmin utilisée jusqu’ici ne permet pas de gé- chambre :
nérer graphiquement des jointures, aussi les requê-
tes suivantes devront être testées via une console SELECT code _ zone FROM zone WHERE piece =
SQL. 'chambre';

Figure 1. Schéma de la base de données biblio

www.phpsolmag.org 41
SQL Jointure

Tableau 1. Contenu de la table zone


La seconde utilise le résultat de la première pour affi-
cher les titres des livres présents dans cette pièce : code_zone piece meuble
c10 chambre armoire en pin
SELECT titre FROM livre WHERE code _ zone IN c18 chambre armoire en pin
('c10','c18','c20','c8'); c20 chambre bibliothèque noire
c8 chambre commode
Une solution plus efficace de procéder est de regrou-
s11 salon bibliothèque noire
per les données des tables livre et zone grâce à une
jointure. s8 salon buffet en chêne
Après avoir présenté le produit cartésien sur lequel
Tableau 2. Contenu de la table ecrit
reposent les jointures, vous verrez quels types de join-
tures existent et comment les utiliser. isbn id_auteur
128-5-56985-5 1
Produit cartésien 523-5-65472-9 2
La jointure consiste à faire le produit cartésien de deux 152-5-55695-2 3
tables puis de restreindre les lignes grâce à une condi- 320-2-02225-6 4
tion. La syntaxe JOIN avec ON permet d’indiquer le type
320-2-02365-5 4
de jointure (interne ou externe, détaillées plus tard) et la
952-5-15632-0 5
condition :
952-5-15632-0 6
SELECT col1[, col2, …] FROM table1 [NATURAL]
[LEFT|RIGHT] JOIN table2 ON condition; ce, il faut donc indiquer que la comparaison porte sur
la colonne code_zone de la table livre et la colonne
Le produit cartésien de deux tables est l’ensemble de code_zone de la table zone :
tous les couples possibles entre les lignes de ces ta-
bles. Il associe à chaque ligne de la table livre la pre- SELECT L.titre, L.date _ parution,
mière ligne de la table zone, puis il associe à chaque li- L.code _ zone AS code1, Z.code _ zone AS code2,
gne de la table livre la seconde ligne de la table zone, Z.piece FROM livre L JOIN zone Z ON
etc. Le tableau 3 montre le produit cartésien d’un sous- L.code _ zone = Z.code _ zone;
ensemble de colonnes des tables livre et zone. Pour
l’afficher, il suffit d’extraire les deux tables sans condi- Cette requête est une jointure interne. Elle s'exerce par
tion de jointure : défaut si le type de jointure n'est pas précisé ou si IN-
NER JOIN est utilisé. Ce type de jointure, le plus fré-
SELECT livre.titre, livre.date _ parution, quemment rencontré, suit la syntaxe :
livre.code _ zone AS code1, zone.code _ zone AS
code2, zone.piece FROM livre JOIN zone; SELECT col1[, col2, …] FROM table1 [INNER]
JOIN table2 ON condition;
Le caractère point permet d'indiquer la table d'où pro-
vient la colonne et évite les ambiguïtés possibles quant La requête de l'exemple retourne cinq lignes. Le livre
à savoir s'il s'agit du code_zone de la table livre ou de non référencé (code_zone à NULL) n'apparaît pas.
celui de la table zone. Pour afficher tous les livres présents dans une cham-
Pour diminuer le nombre de caractère d'une requê- bre, il suffit d'ajouter une restriction à la requête :
te, il est possible de donner un alias aux tables. Dans la
requête suivante, équivalente à la précédente, la table SELECT L.titre, L.date_parution, L.code_zone
livre a été renommée en L et la table zone en Z : AS code1, Z.code_zone AS code2, Z.piece FROM
livre L JOIN zone Z ON L.code_zone = Z.code_
SELECT L.titre, L.date_parution, L.code_zone zone WHERE Z.piece = 'chambre';
AS code1, Z.code_zone AS code2, Z.piece FROM
livre L JOIN zone Z; Une notation plus ancienne peut être rencontrée pour
réaliser une jointure :
Jointure interne
Le produit cartésien du tableau 3 a généré toutes les SELECT col1[, col2, …] FROM table1, table2
possibilités de couples, les seuls qui nous intéressent WHERE condition;
sont ceux dont les codes zone sont identiques (lignes
du tableau 3 marquées d'un | dans la dernière colon- La condition de jointure est spécifiée après la clause
ne). Pour afficher tous les livres présents dans une piè- WHERE et les tables sont listées après le FROM séparées

42 1/2011
Pour les débutants

Tableau 3. Produit cartésien d’un sous-ensemble de colonnes des tables livre et zone
titre date_parution code1 code2 piece
Fall of giants 2010 c20 c10 chambre
Le seigneur des anneaux 1954 c8 c10 chambre
Amphitryon 1668 c18 c10 chambre
Le bourgeois gentilhomme 1670 NULL c10 chambre
David Copperfield 1850 s8 c10 chambre
Un bunker à la Baule 2008 c10 c10 chambre I
Fall of giants 2010 c20 c18 chambre
Le seigneur des anneaux 1954 c8 c18 chambre
Amphitryon 1668 c18 c18 chambre I
Le bourgeois 1670 NULL c18 chambre
gentilhomme
David Copperfield 1850 s8 c18 chambre
Un bunker à la Baule 2008 c10 c18 chambre
Fall of giants 2010 c20 c20 chambre I
Le seigneur des anneaux 1954 c8 c20 chambre
Amphitryon 1668 c18 c20 chambre
Le bourgeois 1670 NULL c20 chambre
gentilhomme
David Copperfield 1850 s8 c20 chambre
Un bunker à la Baule 2008 c10 c20 chambre
Fall of giants 2010 c20 c8 chambre
Le seigneur des anneaux 1954 c8 c8 chambre I
Amphitryon 1668 c18 c8 chambre
Le bourgeois gentilhomme 1670 NULL c8 chambre
David Copperfield 1850 s8 c8 chambre
Un bunker à la Baule 2008 c10 c8 chambre
Fall of giants 2010 c20 s11 salon
Le seigneur des anneaux 1954 c8 s11 salon
Amphitryon 1668 c18 s11 salon
Le bourgeois gentilhomme 1670 NULL s11 salon
David Copperfield 1850 s8 s11 salon
Un bunker à la Baule 2008 c10 s11 salon
Fall of giants 2010 c20 s8 salon
Le seigneur des anneaux 1954 c8 s8 salon
Amphitryon 1668 c18 s8 salon
Le bourgeois gentilhomme 1670 NULL s8 salon
David Copperfield 1850 s8 s8 salon I
Un bunker à la Baule 2008 c10 s8 salon

Tableau 4. Afficher tous les livres et leur zone s’ils sont référencés
titre date_parution code1 code2 piece
Fall of giants 2010 c20 c20 chambre
Le seigneur des anneaux 1954 c8 c8 chambre
Amphitryon 1668 c18 c18 chambre
Le bourgeois gentilhomme 1670 NULL NULL NULL
David Copperfield 1850 s8 s8 salon
Un bunker à la Baule 2008 c10 c10 chambre

www.phpsolmag.org 43
SQL Jointure

par des caractères virgules. La requête précédente peut Tableau 5. Afficher toutes les zones et les livres qu’elles contiennent
être réécrite : titre date_parution code1 code2 piece
Un bunker 2008 c10 c10 chambre
SELECT L.titre, L.date_parution, L.code_zone à la Baule
AS code1, Z.code_zone AS code2, Z.piece FROM
Amphitryon 1668 c18 c18 chambre
livre L , zone Z WHERE L.code_zone = Z.code_
zone AND Z.piece = 'chambre'; Fall of giants 2010 c20 c20 chambre
Le seigneur 1954 c8 c8 chambre
La syntaxe avec JOIN et ON est plus claire car elle per- des anneaux
met de différencier les conditions de jointure des restric- NULL NULL NULL s11 salon
tions, mais les résultats des deux sont équivalentes.
David Copper- 1850 s8 s8 salon
field
Jointure naturelle.
Lorsque les colonnes de la condition de jointure ont le
même nom dans chaque table, la jointure peut être réa-
lisée automatiquement en utilisant le mot-clé NATURAL
devant le type de jointure. La requête, qui affiche les
livres et la pièce dans laquelle ils sont stockés, aurait
pu être écrite :

SELECT L.titre, L.code _ zone AS code1,


Z.code _ zone AS code2, Z.piece FROM livre L
NATURAL JOIN zone Z;

Jointure externe
La jointure interne ne permet pas d’obtenir les livres qui
n’ont pas été rangés dans une pièce, c’est à dire ceux
dont le code zone a la valeur NULL. Seules les lignes qui
ont une correspondance dans l’autre table sont affichées.
Les jointures externes (OUTER JOIN) permettent d’afficher
des lignes qui n’ont pas forcément de correspondance :
Figure 2. Organigramme
SELECT col1[, col2, …] FROM table1 [NATURAL]
[LEFT|RIGHT] [OUTER] JOIN table2 ON condition; Jointure droite
Pour afficher toutes les zones et les livres qu’elles
Jointure gauche contiennent, s’il y en a, il faut utiliser une jointure ex-
Afin d'afficher tous les livres, référencés ou non, il faut réa- terne droite :
liser une jointure externe gauche (LEFT [OUTER] JOIN) :
SELECT L.titre, L.date _ parution, L.code _
SELECT L.titre, L.date_parution, L.code_zone zone AS code1, Z.code _ zone AS code2, Z.piece
AS code1, Z.code_zone AS code2, Z.piece FROM FROM livre L RIGHT JOIN zone Z ON L.code _
livre L LEFT JOIN zone Z ON L.code_zone = zone = Z.code _ zone;
Z.code_zone;
La jointure retourne toutes les lignes de la jointure in-
La requête retourne les lignes de la jointure interne plus terne plus les lignes de la table de droite (zone) qui
les lignes de la table de gauche qui n'ont pas de corres- n'ont pas de correspondance dans la table livre (ta-
pondance dans la table de droite (zone). Dans ce cas, bleau 5).
les colonnes de la table de droite comporteront la valeur Une jointure droite peut s’écrire sous la forme d’une
NULL (tableau 4). jointure gauche en inversant l’ordre des tables. La re-
Les colonnes de la condition de jointure ayant le mê- quête suivante est équivalente à la jointure droite ci-
me nom, il est possible de faire une jointure naturelle dessus (tableau 5) :
externe :
SELECT L.titre, L.date _ parution, L.code _
SELECT L.titre, L.date _ parution, L.code _ zone AS code1, Z.code _ zone AS code2, Z.piece
zone AS code1, Z.code _ zone AS code2, Z.piece FROM zone Z LEFT JOIN livre L ON L.code _
FROM livre L NATURAL LEFT JOIN zone Z; zone = Z.code _ zone;

44 1/2011
Pour les débutants

Tableau 6. Titre des livres et leurs auteurs Les jointures sont faites successivement. Le résultat de
la jointure entre les tables livre et ecrit est joint à la
titre nom
table auteur.
Fall of giants Follett
Comme précédemment, les conditions de jointure
Le seigneur des anneaux Tolkien
portent sur des colonnes de même nom, il est donc pos-
Amphitryon Molière
sible d’écrire :
Le bourgeois gentilhomme Molière
David Copperfield Dickens SELECT L.titre, A.nom FROM livre L NATURAL
Un bunker à la Baule Herbouiller JOIN ecrit NATURAL JOIN auteur A;
Un bunker à la Baule Massonaud

Tableau 7. Contenu de la table employe Auto-jointure


Dans certains cas, il peut s’avérer nécessaire de joindre
id nom chef
une table à elle-même. Par exemple pour retrouver des
1 X NULL
liens de parenté entre des personnes ou afficher le su-
2 Y 1 périeur hiérarchique d’un groupe d’employés (Figure 2).
3 Z 1 Cet exemple sera utilisé pour présenter l’auto-jointure.
4 A 2 Une table stocke tous les employés d’une entreprise
5 B 2 et comporte une colonne chef qui référence l’identifiant
6 C 3 d’un des employés de la même table, ou NULL si l’em-
ployé n’a pas de supérieur hiérarchique (tableau 7). Pour
Tableau 8. Affichage de tous les employés et de leur chef
afficher la liste de tous les employés et de leur chef, il faut
id nom chef faire une jointure interne. Comme elle portera sur la mê-
1 X NULL me table, il faut lui donner deux alias différents :
2 Y X
3 Z X SELECT E.id, E.nom, C.nom AS chef FROM
4 A Y employe E JOIN employe C ON E.chef = C.id;
5 B Y
6 C Z La requête retourne cinq lignes et n’affiche pas les em-
ployés qui n’ont pas de supérieur hiérarchique (dans
Jointure complète l’exemple, celui dont l’id est 1). Pour l’afficher (ta-
La norme SQL définit des jointures externes complètes qui bleau 8), il faut faire une jointure externe :
retournent toutes les lignes de la table de gauche et de la
table de droite (FULL JOIN). Celles-ci ne sont pas implé- SELECT E.id, E.nom, C.nom AS chef FROM
mentées dans MySQL mais peuvent être obtenues grâce employe E LEFT JOIN employe C ON E.chef =
à une union du résultat de deux requêtes (LEFT + RIGHT) : C.id;

SELECT col1[, col2, …] FROM table1 LEFT JOIN Conclusion


table2 ON condition Vous avez appris dans cet article à extraire des don-
UNION nées provenant de plusieurs tables. Grâce aux connais-
SELECT col1[, col2, …] FROM table1 RIGHT JOIN sances acquises dans cette série d'articles, vous êtes
table2 ON condition; à présent à même de réaliser des bases de données
simples, d'y insérer des données et de les interroger. Le
Pour effectuer une union, il faut que les deux requêtes prochain article vous montrera comment interroger une
renvoient le même nombre de colonnes et que celles-ci base de données via PHP avec PDO.
soient du même type.

Jointure sur trois tables Cilia Mauro, Magali Contensin


Il est parfois nécessaire de faire des jointures sur plus Cilia Mauro est gestionnaire de bases de données et développeur
de deux tables. Dans l’exemple, pour afficher les livres d’applications web au CNRS. Elle enseigne les bases de données
et le nom de leurs auteurs (tableau 6), il faut interroger et PHP à l’université.
trois tables. La table ecrit permet d’associer un ou plu- Contact : cilia.mro@gmail.com
sieurs auteurs à un livre. La requête s’écrit donc : Magali Contensin est chef de projet en développement
d’applications au CNRS. Elle enseigne depuis plus de dix ans le déve-
SELECT L.titre, A.nom FROM livre L JOIN ecrit loppement d’applications web à l’université et est l’auteur de nomb-
E ON L.isbn = E.isbn JOIN auteur A ON E.id _ reux articles sur le développement web en PHP.
auteur = A.id _ auteur; Contact : http://magali.contensin.online.fr

www.phpsolmag.org 45
Pour les débutants

46 1/2011
Pour les débutants

www.phpsolmag.org 47

Vous aimerez peut-être aussi