Escolar Documentos
Profissional Documentos
Cultura Documentos
10/2010
Table des matières
www.phpsolmag.org
2/2011
VARIA
www.phpsolmag.org
Rédacteur en chef :
Łukasz Bartoszewicz
PROJETS
8 Accès objet à MySQL avec PHP5
Mbella Ekoume K. Demazy
Couverture : Lorsqu’on décide de faire du PHP orienté objet sans
Sławomir Sobczyk
avoir à faire de la programmation procédurale, très sou-
DTP : vent on est coincé lorsqu’il s’agit d’accéder à une base
Sławomir Sobczyk Studio2W@gmail.com
de données et plus particulièrement à MySQL. Cet arti-
Composition : cle explique comment accéder à une base de données
Sławomir Sobczyk MySQL en orienté objet avec PHP 5 en utilisant l’exten-
sion Mysqli.
Correction :
Valérie Viel, Thierry Borel, Barbara Bourdelles
Bêta-testeurs :
Brice Favre, Valérie Viel, Cyril David,
DOSSIER
Christophe Milhau, Alain Ribault, Stéphane Guedon, 21 Le guide de développement de datatype
Eric Boulet, Mickael Puyfages, Christian Hernoux, eZ Publish
Isabelle Lupi, Antoine Beluze, Timotée Neullas,
Yann Faure, Adrien Mogenet, Jean-François Montgaillard,
Turmeau Nicolas, Jonathan Marois, Wilfried Ceron, Jérôme Vieilledent, Nicolas Pastorino
Wajih Letaief, François Van de Weerdt, Eric Vincent, Les datatypes eZ Publish sont probablement l’une des
Franck Michaël Assi, Francis Hulin-Hubard,
Nicolas Dumas, David Michaud. fonctionnalités les plus puissantes d’eZ Publish. Ils per-
mettent de traiter des éléments de contenu comme
Les personnes intéressées par la coopération vous l’entendez. Cependant, la complexité de leur dé-
sont priées de nous contacter : veloppement est proportionnelle à leur puissance. Cet-
editor@phpsolmag.org
te première partie vous démontrera les fonctionnalités
de base que l’on se doit d’implémenter lors du dévelop-
Publicité :
publicite@software.com.pl pement de son propre datatype eZ Publish.
2/2011
Table des matières
SÉCURITÉ
51 La sécurité de l’information
Tony Fachaux
Aujourd’hui la plupart des données d’une entreprise
sont informatisées. Dans la mesure où les menaces
à l’encontre de la sécurité de l’information se veulent
chaque jour davantage féroces et polymorphes, il est
fondamental de sécuriser au maximum ces données.
Les grands acteurs technologiques comme Google,
Microsoft ou Yahoo sont régulièrement victimes d’at-
taques informatiques. Cet article présente les moyens
techniques et fonctionnels mis en œuvre pour sécuriser
l’information.
Actualités
FlogR
PHP 5.3
http://www.php.net
Joomla 1.6 FLOGR est une nouvelle plateforme
La nouvelle version de Joomla vient de galerie photos, réalisée en PHP
d’être publiée. Elle apporte de nom- et distribuée en Open Source.
breuses évolutions comme une amé-
lioration des nombreux outils aux Le but de ce projet est de vous per-
niveaux de l’accessibilité, avec une mettre d’afficher vos photos venant
nouvelle structure, une amélioration directement du site Flick’R d’une
du code sémantique, une nouvelle manière interactive avec de nom-
gestion de multilangue et génération
de la mise en page xhtml. breuses options vous permettant de
http://www.joomla.fr proposer un album photos très com-
plet comme :
Phractal
Phractal est une application réalisée en • Affichages de différentes vues.
PHP 5.3 et basée sur la technique Man- • Positionner sur une carte le lieu de la photo.
delbrot, pour vous permettre de réaliser • Gestion des tags.
des simples fractales pour le web. Ce
jeune projet devrait évoluer très rapide- • Possibilité de poster des commentaires.
ment car les techniques mathématiques • Différents modes de classements.
sont très vastes.
http://sourceforge.net/projects/phra- Une version de démonstration est disponible pour vous rendre compte de la puis-
ctal/
sance de la plateforme http://thecarruthfamily.com/michael/photos/index.php.
SPIP 2.1.8
SPIP vient de sortir une nouvelle ver- Site officiel : http://code.google.com/p/flogr/.
sion mineure de son CMS, en signa-
lant à l’ensemble des utilisateurs des
versions 2.x d’effectuer la migration
à cause d’un bug important au niveau Rédaction des actualités :
de la sécurité.
http://www.spip.net
Christophe Villeneuve
2/2011
Interview
Interview
de Christophe Gesché,
Directeur Technique pour le site Delcampe
PHP Solutions : Comment voyez-vous le web de de- PS : Quels sont les outils que vous utilisez pour as-
main ? surer à vos clients la qualité du service ?
Christophe Gesché : CG :
www.phpsolmag.org
Projets
Accès objet
à MySQL avec PHP5
Lorsqu’on décide de faire du PHP orienté objet sans avoir
à faire de la programmation procédurale, très souvent
on est coincé lorsqu’il s’agit d’accéder à une base
de données et plus particulièrement à MySQL.
L
’extension Mysql très souvent utilisée en PHP • La classe mysqli : elle permet de créer des objets
pour se connecter à une base de données Mys- de type mysqli _ object. Cette dernière possède
ql est une extension exclusivement procédurale des méthodes et des propriétés nécessaires pour
et n’offre de ce fait aucun mécanisme d’accès aux don- permettre par exemple de se connecter à la ba-
nées en orienté objet. Cependant, la version 5 de PHP, se de données, d’envoyer des requêtes préparées
à savoir PHP5, ayant été conçu pour accroître les capa- à cette dernière, ou alors d’effectuer des transac-
cités orientées objet de PHP, a prévu des moyens de le tions.
faire, et cet article nous montrera comment. • La classe mysqli _ result : elle permet de gérer
Grâce à l’évolution qu’a connue le langage PHP en- les résultats des requêtes SQL effectuées à l’aide
tre la version 4 et la version 5 la programmation orienté de l’objet mysqli précédent. C’est ainsi qu’elle pos-
objet avec ce langage a connu pas mal de modifications sède des méthodes et des propriétés permettant de
et d’amélioration ; et l’accès aux données n’est pas res- manipuler de plusieurs manières les résultats issus
té en marge de cette logique. C’est ainsi que l’accès ob- d’une requête SQL en rendant par exemple ceux-ci
jet à une base de données MySQL est désormais pos-
sible grâce à l’utilisation de l’extension Mysqli (ou Mysql
improved pour améliorée) de PHP. Cette extension a les
avantages suivants par rapport à ces prédécesseurs :
2/2011
MySQL avec PHP5
-- --------------------------------------------------------
--
-- Structure de la table 'produit'
--
--
-- Contenu de la table 'produit'
--
INSERT INTO 'produit' ('prd _ id', 'prd _ libelle', 'prd _ reference', 'prd _ fabricant', 'prd _ qteStock', 'prd _
qteAllert', 'prd _ unite') VALUES
(4, 'alcool', 'alc', 'novartis', 10, 20, 'cm'),
(6, 'benzene', 'ben', 'chococam', 10, 2, 'cm'),
(8, '24DNPH', 'DNPH', 'areva', 124588, 1250, 'ml'),
(9, 'acide chlohydrique', 'hcl', 'chimie', 124588, 0, 'ml'),
(10, 'aspirine', 'asp', 'chimie', 124588, 0, 'ml'),
(11, 'uranium 235', 'U235', 'AIEA', 125, 12, 'bekerel'),
(12, 'polonium 210', 'pol', 'AIEA', 25, 0, 'ur'),
(13, 'bromure', 'br', 'chimie', 1254, 0, 'l'),
(14, 'urée', '201010', 'engrais', 100, 0, 'sac'),
(15, 'phosphate', 'ph', 'arcelor', 145, 0, 'cm');
class Config
{
private $HOST = "localhost";
private $USER = "root";
private $PASSWORD = "";
private $DATABASE = "cabinet";
public function connect()
{
//fonction permettant de ce connecter a la bd en utilisant l'extension mysqli
//elle retourne l'objet de connection
$con = new mysqli($this->HOST,$this->USER,$this->PASSWORD,$this->DATABASE);
$con->set _ charset("utf8"); //definition du jeu de caractère par defaut du client
if(mysqli _ connect _ error())
$con = 'echec de la connexion à la base de données ('. mysqli _ connect _
errno().')'. mysqli _ connect _ error();
return $con;
}
public function disconnect(mysqli $con)
{
//cette fonction, permet de ce déconnecter de la BD
//elle prend en entrée un objet de connection de type mysqli
$val = $con->close();
if($val!= true)
{
echo("echec de la fermeture de la connection a la BD");
}
}
www.phpsolmag.org
Projets
sous forme de tableau associatif, de tableau indicé, mysqli->insert _ id : retourne l’identifiant automa-
d’obtenir le nombre de tuple d’un résultat etc. tiquement généré pour un attribut déclaré AUTO _
• La classe mysqli _ stmt : elle permet d’effectuer INCREMENT.
des requêtes préparées sur la base de données.
• La classe mysqli _ driver : elle permet la gestion • Les méthodes :
des drivers mysqli.
mysqli ( [string $host [, string $username
La classe mysqli [, string $passwd [, string $base [, int
Cette classe possède un certain nombre de propriétés $port [,
et de méthodes ; nous nous limiterons à n’évoquer que string $socket]]]]]] ) : permet de créer un objet
quelques-unes. mysqli, afin de se connecter à la base de données
MySQL.
• Propriétés : close(void) : permet de fermer une connexion à la
base de données MySQL ; elle retourne true en cas
mysqli->affected _ rows : contient le nombre de de succès et false sinon.
lignes affectées par la dernière requête INSERT, query(string $query [, int $mode]) : permet
UPDATE ,REPLACE ou DELETE. d’exécuter une requête sur la base de données ;
10 2/2011
MySQL avec PHP5
www.phpsolmag.org 11
Projets
12 2/2011
MySQL avec PHP5
www.phpsolmag.org 13
Projets
d’un tableau associatif, d’un tableau indexé, ou les fetch _ row ( void ) : permet de récupérer
deux suivant la valeur du paramètre $resultty- une ligne de résultats sous forme de tableau in-
pe qui peut être : MYSQLI _ ASSOC, MYSQLI _ NUM, dexé.
MYSQLI _ BOTH (valeur par défaut).
fetch _ assoc ( void ) : permet de récupérer La classe mysqli_stmt
une ligne de résultats sous forme de tableau asso- - Les propriétés :
ciatif ;
fetch _ object ([ string $class _ name [, mysqli _ stmt->affected _ rows : retourne le
array $params ]]) : retourne la ligne courante nombre total de lignes modifiées, effacées, ou insé-
d’un jeu de résultats sous forme d’objet ; en para- rées par la dernière requête.
mètre nous avons $class _ name qui représente le mysqli _ stmt->insert _ id : récupère l’ID généré
nom de la classe à instancier , et $params un ta- par la dernière requête INSERT.
bleau contenant la liste des paramètres à passer au mysqli _ stmt ->num _ rows : retourne le nombre
constructeur de cette classe. de ligne d’un résultat Mysql.
14 2/2011
MySQL avec PHP5
www.phpsolmag.org 15
Projets
client _ version : qui indique la version du client. embedded _ server _ start ( bool $start ,
driver _ version : qui indique la version du driver Mysqli. array $arguments , array $groups ) : qui per-
met d’initialiser et de démarrer le serveur embarqué.
- Les méthodes
Mise en œuvre
Il n’y en a que deux pour le moment et elles sont Pour illustrer l’utilisation de mysqli pour accéder à MyS-
également peu documentées, il s’agit de : QL, nous allons mettre en place une application web ba-
sique. L’architecture ici étant l’architecture MVC (Model
embedded _ server _ end(void) : qui permet d’ar- View Controller) cela nous permettra de séparer l’accès
rêter le serveur embarqué. aux données de la présentation et des traitements.
16 2/2011
MySQL avec PHP5
www.phpsolmag.org 17
Projets
18 2/2011
MySQL avec PHP5
</fieldset>
</form>
</div>
</body>
</html>
www.phpsolmag.org 19
Projets
Conclusion
Sur Internet : Nous venons à travers cet article de voir comment ac-
céder à MySQL en orienté objet grâce à l’extension
• http://www.php.net/download-docs.php - Le manuel de mysqli ; nous avons également pu effectuer des trai-
PHP5 sous divers formats, pour plus de détails sur la tements grâce aux classes mysqli_stmt et mysqli_
classe Mysqli. result et à leurs méthodes. Désormais vous pouvez
développer votre application PHP5 en adoptant une
approche complètement orienté objet, même au ni-
• current() : retourne l’élément courant de la collec- veau de l’accès aux données. Cependant pour ceux
tion, qui ne sont pas encore familiarisés avec l’approche
• key() : retourne la valeur de la clé de l’élément cou- orientée objet de PHP5 et veulent pouvoir tirer pro-
rant de la collection, fit des avantages de l’extension mysqli, ils peuvent
• next() : permet de se positionner sur l’élément sui- dans ce cas opter pour l’approche procédurale de cet-
vant de la collection, te API ; cela pourrait d’ailleurs faire l’objet d’un article
• rewind() : permet de se positionner sur le premier futur.
élément de la collection, Étant donné que cet article ne saurait être exhaus-
• valid() : permet de savoir si l’on a atteint la fin de tif sur ce sujet, nous vous invitons à compléter vos
la collection. connaissances en faisant un tour sur Internet et en
lisant quelques livres spécialisés.
Le Listing 7 représente le code source de la vue
liste produit elle permet d’afficher sous forme de ta-
bleau la liste des produits présents dans la table
produit. Ce qui nous donne dans un navigateur la
Figure 2.
On remarque bien la présence de notre nouvel en-
registrement vitamine c à la dernière ligne de notre ta-
bleau.
20 2/2011
Dossier
Le guide
de développement de datatype eZ Publish
Les datatypes eZ Publish sont probablement
l’une des fonctionnalités les plus puissantes d’eZ Publish
car ils permettent de traiter des éléments de contenu comme
vous l’entendez. Cet article vous expliquera les fonctionnalités
de base que l’on se doit d’implémenter lors du développement
de son propre datatype eZ Publish.
www.phpsolmag.org 21
Dossier
Extension ZIP pour PHP
2
22 9/2010
2/2011
eZ Publish
[DataTypeSettings]
La partie configuration ExtensionDirectories[]=mycustomdatatypeextension
Ici nous indiquons à eZ Publish qu’il doit également cher- AvailableDataTypes[]=mycustomdatatypeid
cher des datatypes dans le dossier d’extension mycustom */ ?>
datatypeextension. Nous déclarons également notre
www.phpsolmag.org 23
Dossier
Captures d’écran
Listing 5. extension/mycustomdatatypeextension/settings/
design.ini.append.php
<?php /* #?ini charset="utf-8"?
[ExtensionSettings]
DesignExtensions[]=mycustomdatatypeextension
*/ ?>
Le projet
Pour une meilleure compréhension, nous allons placer
l’étude des datatypes eZ Publish dans le cadre d’un
projet. Nous proposons de développer un datatype
gérant les IDs produits Amazon, basé sur l’extension
JVAmazonAdvertising (http://projects.ez.no/jvama-
zonadvertising). L’extension entière, contenant le da-
tatype finalisé, peut-être récupérée dans le dépôt SVN
suivant : http://svn.projects.ez.no/jvamazonadverti-
sing/trunk/ (le package proposé en téléchargement
n’est pas à jour).
Spécifications
La fonction de ce datatype est de supporter les ID pro-
duits spécifiques à Amazon (ASIN), en procurant :
24 2/2011
eZ Publish
Côté template
L’objectif est de pouvoir ajouter un attribut du datatype Figure 3. Edition de la classe de contenu ‘Product’
que nous sommes en train de développer à une clas-
se de contenu existante, ou bien une nouvelle classe.
Comme le montre la Figure 4, représentant notre data-
type dans l’interface d’édition d’une classe de contenu,
la partie supérieure de l’interface, par attribut, est stan-
dard et commune à tous les datatypes. Elle ne deman-
de pas de création de template.
La partie inférieure, optionnelle (le template corres-
pondant, même vide, doit cependant exister), est néces-
saire lorsque de la configuration supplémentaire est re-
quise, ce qui est notre cas. Nous allons devoir créer, dans
un template, cet élément d’interface (voir Figure 4). Figure 4. Interface d’édition de notre datatype, au niveau de la
Ce découpage d’interface standard/personnalisé se classe de contenu.
retrouve lors de la visualisation de l’attribut dans la clas-
se de contenu, voir Figure 5. Nous allons également
créer cet élément d’interface personnalisé dans un tem-
plate propre à notre datatype (voir Figure 5). Commen-
çons donc par créer la partie d’interface personnalisée
de l’édition de classe de contenu.
Template d’édition
Comme nous l’avons vu plus haut (cf Structure Stan- Figure 5. Interface de visualisation de notre datatype, au niveau de
dard), c’est dans le template jvamazonid.tpl, placé dans la classe de contenu.
extension/jvamazonadvertising/design/standard/tem-
plates/class/datatype/edit/ que nous allons permettre Markup
au webmestre de : Notez le réflexe <fieldset>/<legend>, qui permet de dé-
• Activer la recherche de produit correspondant dans ployer l’interface en deux parties visuellement distinc-
le catalogue Amazon si le champ de saisie, au ni- tes, en s’appuyant sur les styles par défaut de l’inter-
veau de l’édition de l’objet de contenu, a été laissé face d’administration d’eZ Publish. Une autre bonne
vide. Ceci doit pouvoir se contrôler par une option pratique est d’utiliser une balise <label> correspondant
dédiée, à chaque balise <input>, en les liant par l’attribut ‘for’ de
• Contrôler quels attributs de contenus serviront de la balise <label>.
texte de recherche, dans le cas où l’option ci-des-
sus est activée, Variables à disposition
• Définir sur quelle catégorie du catalogue Amazon La principale variable nous intéressant ici est $class_
portera la recherche, si elle est activée ou manuelle, attribute, un objet PHP de la classe eZContent-
• Définir sur quel emplacement du catalogue Amazon ClassAttribute (détails : http://doc.ez.no/eZ-Publish/
(BrowseNode) portera la recherche, si elle est acti- Technical-manual/4.x/Reference/Objects/ezcontent-
vée ou manuelle. classattribute), donnant accès à toutes les propriétés
et données de notre attribut de classe de contenu. La
Ajoutons ces trois contrôles dans jvamazonid.tpl référence complète des attributs est consultable ici :
(cf Listing 6). http://goo.gl/aeumK.
www.phpsolmag.org 25
Dossier
Listing 6. extension/jvamazonadvertising/design/standard/templates/class/datatype/edit/jvamazonid.tpl
<div class="block">
<fieldset>
<legend>
{"Reference field for ASIN search"|i18n( "design/standard/class/datatype/jvamazonid" )}
</legend>
<label for="ContentClass _ jvamazonid _ asin _ search _ field _ {$class _ attribute.id}">
{"Enter attribute identifiers as for object name (ie. <my _ attribute _ identifier>)"|i18n( "design/
standard/class/datatype/jvamazonid" )}
</label>
<input type="text" size="50"
name="ContentClass _ jvamazonid _ asin _ search _ field _ {$class _ attribute.id}"
id="ContentClass _ jvamazonid _ asin _ search _ field _ {$class _ attribute.id}"
value="{$class _ attribute.data _ text1}" />
<i>{"If left empty, will be content object name"|i18n( "design/standard/class/datatype/jvamazonid" )}</i>
<br /><br />
<label for="ContentClass _ jvamazonid _ asin _ search _ if _ empty _ {$class _ attribute.id}">
{"Automatically search ASIN on publish if object attribute is left empty (default value)"|i18n(
"design/standard/class/datatype/jvamazonid" )}
</label>
<input type="checkbox"
name="ContentClass _ jvamazonid _ asin _ search _ if _ empty _ {$class _ attribute.id}"
id="ContentClass _ jvamazonid _ asin _ search _ if _ empty _ {$class _ attribute.id}"{if $class _ attribute.
data _ int1} checked="checked"{/if} />
</fieldset>
<fieldset>
<legend>
{"Amazon SearchIndex (category) to search into"|i18n( "design/standard/class/datatype/jvamazonid" )}
</legend>
<label for="ContentClass _ jvamazonid _ asin _ search _ index _ {$class _ attribute.id}">
{"Enter a valid search index (product category)."|i18n( "design/standard/class/datatype/jvamazonid" )}<br />
</label>
<input type="text" size="50"
name="ContentClass _ jvamazonid _ asin _ search _ index _ {$class _ attribute.id}"
id="ContentClass _ jvamazonid _ asin _ search _ index _ {$class _ attribute.id}"
value="{$class _ attribute.data _ text2}" /><br />
<i>{"Search indexes are listed here"|i18n( "design/standard/class/datatype/jvamazonid" )} :
<a href={"http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/APPNDX _ SearchIndexValues.
html"|ezurl} target=" _ blank">http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/APPNDX _
SearchIndexValues.html</a>
</i>
</fieldset>
<fieldset>
<legend>
{"Amazon BrowseNode (sub-category) to search into"|i18n( "design/standard/class/datatype/jvamazonid" )}
</legend>
<label for="ContentClass _ jvamazonid _ browsenode _ {$class _ attribute.id}">
{"Enter a valid browse node (product location in Amazon catalog). Leave empty if not applicable"|i18n(
"design/standard/class/datatype/jvamazonid" )}<br />
</label>
<input type="text" size="50"
name="ContentClass _ jvamazonid _ browsenode _ {$class _ attribute.id}"
id="ContentClass _ jvamazonid _ browsenode _ {$class _ attribute.id}"
value="{$class _ attribute.data _ int2}" /><br />
<i>{"Find a browse nodes non-exhaustive list here"|i18n( "design/standard/class/datatype/jvamazonid" )} :
<a href={"http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/index.html?APPNDX _
SearchIndexValues.html"|ezurl} target=" _ blank">http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/index.
html?APPNDX _ SearchIndexValues.html</a>
</i>
</fieldset>
</div>
26 2/2011
eZ Publish
Listing 9. extension/jvamazonadvertising/design/standard/templates/class/datatype/view/jvamazonid.tpl
<div class="block">
<label>{"Reference field for ASIN search"|i18n( "design/standard/class/datatype/jvamazonid" )} :</label>
<p>{$class _ attribute.data _ text1|wash}</p>
<label>{"Automatically search ASIN on publish if object attribute is left empty (default value)"|i18n( "design/
standard/class/datatype/jvamazonid" )} :</label>
<p>{$class _ attribute.data _ int1|choose( 'No'|i18n( "design/standard/class/datatype/jvamazonid" ), 'Yes'|i18n( "design/
standard/class/datatype/jvamazonid" ) )}</p>
<label>{"Amazon SearchIndex (category) to search into"|i18n( "design/standard/class/datatype/jvamazonid" )} :</label>
<p>{$class _ attribute.data _ text2|wash}</p>
<label>{"Amazon BrowseNode (sub-category) to search into"|i18n( "design/standard/class/datatype/jvamazonid" )} :</
label>
<p>{$class _ attribute.data _ int2}</p>
</div>
Construction du nom des <input> ceci permettant de s’appuyer sur les styles par défaut
L’attribut ‘name’ des balises <input> suit une règle de de l’interface d’administration. Une autre bonne prati-
nommage stricte : que est d’utiliser des balises <label> autour de chaque
élément de configuration.
ContentClass_<data_type_string>_<nom_de_l_
input>_<ID_d_attribut_de_classe> Variables et données à disposition
Comme pour le template d’édition, la variable $class_
qui doit être respectée dans le template, et conséque- attribute nous permet d’avoir accès aux propriétés
mment dans la partie PHP, lors du traitement des en- et données de notre attribut de classe. Le contenu de
trées. Le Listing 7 montre un exemple extrait du templa- cette variable est le même que pour l’édition de classe,
te d’édition de l’attribut de classe. et la récupération des données stockées se fait de la
On y retrouve bien les éléments constitutifs de la rè- même façon que lors de l’édition :
gle de nommage (voir Tableau 1). Ce motif doit être sui-
vi pour toutes les balises <input> utilisées, entraînant {$class_attribute.data_text1|wash}
l’unicité de nom de toutes les balises <input> pouvant
être présentes dans le formulaire d’édition de classe de L’utilisation de l’opérateur wash permet de “laver” la
contenu (qui contient généralement plusieurs attributs, sortie (équivalent de htmlentities en PHP, cf http://www.
on évite donc tout conflit). php.net/htmlentities), évitant une injection potentielle.
Markup Initialisation
On encapsule l’ensemble de cette partie d’interface La méthode initializeClassAttribute() reçoit en
personnalisée dans un <div class=”block”></div>, paramètre une référence du Content Class Attribute
www.phpsolmag.org 27
Dossier
Listing 10. Initialisation de l'attribut de classe Listing 12. Récupération des données et stockage de l'attribut de
classe
<?
/** /**
* Sets default values for a new class attribute. * Handles the input specific for one attribute from
* @param eZContentClassAttribute the class edit interface.
$classAttribute * @param eZHTTPTool $http
* @return void * @param string $base Seems to be always
*/ 'ContentClass'.
public function initializeClassAttribute( * @param eZContentClassAttribute $classAttribute
$classAttribute ) * @return void
{ */
// Default value for search field public function fetchClassAttributeHTTPInput( $http,
if ( !$classAttribute->attribute( self:: $base, $classAttribute )
CLASSATTRIBUTE _ DEFAULT _ FIELD ) ) {
{ // Search field(s)
$classAttribute->setAttribute( self:: $searchFieldName = $base . self::SEARCH _ FIELD _
CLASSATTRIBUTE _ DEFAULT _ FIELD, VARIABLE . $classAttribute->attribute( 'id' );
self:: if( $http->hasPostVariable( $searchFieldName ) )
CLASSATTRIBUTE _ DEFAULT _ EMPTY ); {
$searchFieldValue = $http->postVariable(
} $searchFieldName );
$classAttribute->setAttribute( self::
// Default value for "Allow search if empty" CLASSATTRIBUTE _ DEFAULT _ FIELD, $searchFieldValue );
if ( $classAttribute->attribute( self:: }
CLASSATTRIBUTE _ ALLOW _ SEARCH _ FIELD ) === null )
{ // Allow search if object attribute empty
$classAttribute->setAttribute( self:: $searchIfEmptyFieldName = $base . self::
CLASSATTRIBUTE _ ALLOW _ SEARCH _ FIELD, ALLOW _ SEARCH _ IF _ EMPTY _ VARIABLE . $classAttribute-
self:: >attribute( 'id' );
CLASSATTRIBUTE _ ALLOW _ SEARCH _ DEFAULT ); if( $http->hasPostVariable(
$searchIfEmptyFieldName ) ) // Checkbox : only set if posted
} {
$classAttribute->setAttribute( self::
// Default value for search index CLASSATTRIBUTE _ ALLOW _ SEARCH _ FIELD, 1 );
if ( !$classAttribute->attribute( self:: }
CLASSATTRIBUTE _ SEARCHINDEX _ FIELD ) )
{ // Search index
$classAttribute->setAttribute( self:: $searchIndexFieldName = $base . self::SEARCH _
CLASSATTRIBUTE _ SEARCHINDEX _ FIELD, INDEX _ FIELD _ VARIABLE . $classAttribute->attribute( 'id'
self:: );
CLASSATTRIBUTE _ SEARCHINDEX _ DEFAULT ); if( $http->hasPostVariable( $searchIndexFieldName
} ) )
{
// Default value for browse node $searchIndexFieldValue = $http->postVariable(
if ( !$classAttribute->attribute( self:: $searchIndexFieldName );
CLASSATTRIBUTE _ BROWSENODE _ FIELD ) ) $classAttribute->setAttribute(
{ self::CLASSATTRIBUTE _ SEARCHINDEX _ FIELD,
$classAttribute->setAttribute( self:: $searchIndexFieldValue );
CLASSATTRIBUTE _ BROWSENODE _ FIELD, }
self::
CLASSATTRIBUTE _ BROWSENODE _ DEFAULT ); // BrowseNode
} $browseNodeFieldName = $base . self::BROWSENODE _
} FIELD _ VARIABLE . $classAttribute->attribute( 'id' );
if( $http->hasPostVariable( $searchIndexFieldName
Listing 11. Validation de l'attribut de classe ) )
{
/** $browseNodeFieldValue = $http->postVariable(
* Validates the input from the class definition $browseNodeFieldName );
form concerning this attribute. $classAttribute->setAttribute( self::
* @param eZHTTPTool $http CLASSATTRIBUTE _ BROWSENODE _ FIELD, $browseNodeFieldValue );
* @param string $base Seems to be always }
'ContentClass'. }
* @param eZContentClassAttribute
$classAttribute Listing 13. Récupération via eZHTTPTool
* @return int eZInputValidator::STATE _ ACCEPTED
|eZInputValidator::STATE _ INVALID|eZInputValidator:: if( $http->hasPostVariable( $searchFieldName ) )
STATE _ INTERMEDIATE {
*/ $searchFieldValue = $http->postVariable(
public function validateClassAttributeHTTPInput( $searchFieldName );
$http, $base, $classAttribute ) $classAttribute->setAttribute( self::CLASSATTRIBUTE _
{ DEFAULT _ FIELD,
return eZInputValidator::STATE _ ACCEPTED; $searchFieldValue );
} }
(classe PHP eZContentClassAttribute, détails ici : http:// classe de contenu, de peupler au besoin les champs de
doc.ez.no/eZ-Publish/Technical-manual/4.x/Reference/ stockage utilisés avec des valeurs par défaut. De ma-
Objects/ezcontentclassattribute). Elle permet, alors que nière générique, on assigne une valeur à un champ de
l’on ajoute un nouvel attribut de notre datatype à une la manière suivante :
28 2/2011
eZ Publish
www.phpsolmag.org 29
Dossier
Le corps de cette méthode est trivial dans notre cas, Récupération et stockage
comme le montre le Listing 11. C’est la méthode fetchClassAttributeHTTPInput()
La méthode fixupClassAttributeHTTPInput() qui assure ces deux fonctions. Nous devons stocker
sera donc vide. Vous aviez suivi ? Parfait. On continue. trois informations :
30 2/2011
eZ Publish
• [Booléen] Doit-on chercher automatiquement un L’étape suivante pour chaque variable POST est d’en tes-
ASIN dans le catalogue Amazon si le champ de ter l’existence, et si elle est bien présente dans les don-
contenu n’est pas renseigné ? nées reçues, la stocker. La variable $http reçue en pa-
• [Chaîne de caractères] De quels attributs de conte- ramètre, instance (singleton) de la classe eZHTTPTool
nus les termes de recherche seront extraits ? (détails ici : http://pubsvn2.ez.no/phpdoc/trunk/html/de-
• [Chaîne de caractères] Dans quel index de recher- fault/eZHTTPTool.html), expose une interface simple et
che Amazon doit-on effectuer la recherche ? efficace d’accès aux données HTTP. On ne se prive pas
• [Entier] Dans quel noeud du catalogue de recher- de l’utiliser pour la récupération de chacune des 3 infor-
che Amazon doit-on effectuer la recherche ? mations (Listing 13).
Nous avons à ce stade terminé l’implémentation
Nous stockerons ces quatre informations dans les de notre datatype au niveau classe de contenu. Il est
champs respectifs : temps d’aborder le niveau objet de contenu.
www.phpsolmag.org 31
Dossier
32 2/2011
eZ Publish
www.phpsolmag.org 33
Dossier
- et de l’objet eZHTTPTool permettant de manipuler les du/des champ(s) posté(s), de le(s) valider et d’en récu-
données transférées via HTTP (POST, GET...). La seule pérer la/les valeur(s). Pour ce faire, comme pour la clas-
exception à cela est la méthode onPublish(), un peu se de contenu, il est préférable d’utiliser des constantes
particulière, qui sera vue en détail. de classe pour la partie fixe du nom de la variable POST
Au moment de la publication d’un objet de contenu, (<nom_du_champ>), afin d’éviter de se retrouver avec
eZ Publish itère sur ses différents attributs et appelle des valeurs en dur dans le code (Listing 14).
toutes les méthodes de publication de leurs datatypes Les principales méthodes de publication sont, dans
respectifs. Cependant, ne connaissant pas à l’avance le leur ordre d’appel (voir Tableau 4).
nombre et le type de champ(s) pour tel ou tel datatype,
eZ Publish ne filtre pas lui-même les données postées. Initialisation de l’attribut
C’est au datatype, et donc à vous, de savoir reconnaître La méthode initializeObjectAttribute() permet
quel(s) est/sont le(s) champ(s) concerné(s). d’insérer une valeur par défaut le cas échéant (premiè-
Par convention, le nom du/des champ(s) d’un attri- re version d’un objet). Dans notre cas, elle permettra de
but posté est constitué suivant le motif suivant : pré-cocher ou non la case à cocher autorisant la recher-
che automatique d’ASIN (Listing 15).
ContentObjectAttribute_<nom_du_champ>_<identi-
fiant_attribut_numérique_unique> Validation des données postées
Il est toujours utile de valider les données postées par
A noter que la valeur ContentObjectAttribute dans un utilisateur/contributeur, que ce soit par sécurité ou
le nom du champ est passée dans le paramètre $base pour s’assurer que ce qui a été saisi correspond bien
des méthodes de publication. Note : Cette règle de nom- à ce qui est attendu côté serveur. De cette manière on
mage est identique à celle utilisée au niveau classe de évite souvent bien des erreurs et/ou des failles poten-
contenu. Ainsi, il vous appartient de reconstruire le nom tielles.
34 2/2011
eZ Publish
www.phpsolmag.org 35
Dossier
{* Bouton de recherche *}
<input class="button jvamazonid _ search _ button" type="submit"
id="jvamazonid _ search _ button-{$attribute.id}"
name="CustomActionButton[{$attribute.id} _ search _ asin]"
value="{"Search Amazon ID"|i18n( "design/standard/content/datatype/jvamazonid" )}" />
{* Case à cocher pour autoriser une recherche d'ASIN automatique si le champ ASIN est vide à la publication *}
<input id="ezcoa-{$attribute _ base}-{$attribute.contentclassattribute _ id} _ {$attribute.contentclass _ attribute _
identifier} _ allow _ search _ empty"
class="ezcc-{$attribute.object.content _ class.identifier} ezcca-{$attribute.object.content _ class.identifier} _
{$attribute.contentclass _ attribute _ identifier}"
type="checkbox"
name="{$attribute _ base} _ jvamazonid _ asin _ search _ if _ empty _ {$attribute.id}"{if $attribute.data _ int}
checked="checked"{/if} />
<label style="display:inline;" for="ezcoa-{$attribute _ base}-{$attribute.contentclassattribute _ id} _ {$attribute.
contentclass _ attribute _ identifier} _ allow _ search _ empty">
{"Automatically search Amazon ID on publish if empty"|i18n( "design/standard/content/datatype/jvamazonid" )}
</label>
36 2/2011
eZ Publish
www.phpsolmag.org 37
Dossier
38 2/2011
eZ Publish
Sur Internet
• http://share.ez.no/download – Télécharger eZ Publish,
• http://share.ez.no – Portail de la Communauté eZ Publish,
• http://twitter.com/ezcommunity – La communauté eZ Publish sur Twitter,
• http://doc.ez.no – La documentation officielle,
• community@ez.no – Contact,
• http://pubsvn2.ez.no/phpdoc/trunk/html/index.html – Documentation de l’API,
• http://share.ez.no/learn/ez-publish/a-quick-and-friendly-introduction-to-ezpersistentobject – “Introduction rapide aux ob-
jets persistents eZ Publish“
• http://share.ez.no/learn/ez-publish/creating-a-simple-custom-workflow-event – “Comment étendre le système de Work-
flows d’eZ Publish“
• http://share.ez.no/learn/ez-publish/extending-ez-publish-s-rest-api-developer-preview-2 – “Comment étendre l’API REST
d’eZ Publish“
• http://goo.gl/oHMfk et http://goo.gl/OM1ZX – Les fonctions fetch eZ Publish, puissant outil du language de template
HTTPValue. Cette variable est directement accessible Nous vous invitons à venir retrouver la communau-
depuis le template du datatype ($attribute.value) té eZ Publish sur son portail : http://share.ez.no, point
et nous pouvons y stocker n’importe quel type de don- d’entrée principal. On y retrouve une vaste base de
nées. Le Listing 25 illustre l’action. connaissances (didacticiels), des blogs d’experts, des
Dans le template, comme le montre le Listing 26, forums hyperactifs, un canal IRC, du twitter, des flux
nous affichons les résultats de la recherche. Le contri- RSS, ainsi que la possibilité de développement colla-
buteur aura juste à cliquer sur le nom du bon produit boratif d’extensions, ainsi que du noyau d’eZ Publish
pour remplir le champ texte avec son ASIN via Javas- même, conjointement avec l’équipe d’eZ (eZ Publish
cript (Listing 27). Voici le résultat final (voir Figure 6). Community Project).
Conclusion A bientôt !
Après une courte introduction aux concepts de gestion
de contenu d’eZ Publish (que vous pourrez approfondir
au besoin), nous avons parcouru tour à tour, dans le ca-
dre d’un interfaçage avec le catalogue Amazon et ses
web-services (AWS), la structure standard d’un data-
type eZ Publish (PHP, enregistrement du datatype), ce
qui doit être fait pour qu’il s’intègre correctement aux
classes de contenu, puis enfin aux objets de contenu
(aux plans graphique et logique métier).
L’exemple utilisé est suffisamment générique pour
servir d’inspiration pour n’importe quel autre datatype :
il implémente quasiment toutes les méthodes à disposi-
tion, illustrant le spectre fonctionnel complet et la puis- Jérôme Vieilledent
sance d’un datatype eZ Publish. Nous espérons vous Nicolas Pastorino
avoir montré comment vous pourrez l’exploiter dans Jérôme Vieilledent – Software Engineer at eZ Systems – Twitter :
vos cas métiers concrets. @jvieilledent
Jérôme est un développeur web autodidacte. Il a appris le PHP par
Listing 27. Code JS lui-même, et a fait ses débuts avec eZ Publish en 2007. Il est déve-
loppeur certifié eZ Publish et travaille actuellement dans l’équipe
$(document).ready(function() {
$('a.jvamazonid _ result').click(function() { d’ingénierie logicielle d’eZ Systems, depuis Lyon.
var aID = $(this).attr('id').split(' _ '); Nicolas Pastorino – Director Community at eZ Systems – Twitter :
var attributeID = aID[1];
var asin = aID[2]; @jeanvoye – nfrp@ez.no
var nameAttribute = 'ContentObjectAttribute _ Consultant et formateur sur eZ Publish de 2005 à 2008, d’abord en
jvamazonid _ data _ text _ +attributeID;
Norvège puis pour la région Europe de l’Ouest, il a ensuite rejoint
$('input[name="'+nameAttribute+'"]').val(asin); l’équipe de gestion de produit, ainsi que l’équipe d’ingénierie en
});
2009, travaillant sur leur articulation. Il prend maintenant soin de
}); la Communauté eZ Publish (38 000+ embres), l’intensifiant, la fai-
sant croître, et la structurant.
www.phpsolmag.org 39
Pratique
Écrire
un Web Service en PHP
Des systèmes peuvent interagir avec le service Web
de la manière prescrite par sa description en utilisant
des messages SOAP, typiquement transmis via le protocole
HTTP et une sérialisation XML en conjonction avec
d’autres normes liées au Web.
C
et article vous présentera dans un premier pour la définition de l’interface du service sont définis
temps les services de l’interface par l’intermé- au sein de l’élément types.
diaire du WSDL, abordera la mise en oeuvre du La section message définit deux messages. Le pre-
service en PHP et montrera comment déployer le ser- mier est getResultRequest, qui est une requête pour
vice sur votre serveur Web. relayer le message getResult et prend deux paramè-
tres de type int nommés : integer1, integer2 et un
Définir les services de l’interface paramètre de type string nommé : operation. L’autre
Nous allons essayer d’écrire notre propre Web Servi- message est getResultResponse, qui est la réponse
ce SOAP, qui réalisera l’addition / soustraction de deux au message getResult, contenant une valeur de type
entiers. La première tâche est de créer un document int, nommé result.
WSDL décrivant notre service dans un format compré- La section portType combine plusieurs éléments
hensible par les clients. message pour composer une opération : getResult.
Chaque opération se réfère à un message en entrée
Contenu (input) et à des messages en sortie (output). L’élé-
Dans la mesure où il s’agit d’un standard basé sur XML, ment <binding> décrit les spécifications concrètes de
la structure du WSDL vous semblera familière si vous la manière dont le Web Service sera implémenté et dé-
avez une connaissance un peu approfondie du XML. Le finit la façon dont les messages doivent être transmis. Il
fichier WSDL se divise en plusieurs parties : un ensem- spécifie également les espaces de noms et la valeur de
ble d’éléments décrivant les types de données utilisés l’entête soapAction pour la méthode getResult. Enfin,
par le service, les messages que le service peut rece- le service du document permet d’invoquer le service
voir, ainsi que les liaisons SOAP associées à chaque donné, ce qui sert à regrouper un ensemble de ports
message. reliés (port). La plupart du temps, c’est une URL invo-
Le document WSDL commence par l’entête XML quant un service SOAP.
standard contenant un identificateur de version <?xml
version=»1.0»?>, et que l’élément racine du docu- Conseil de création
ment se nomme <definitions>. Ce dernier, donnant Voici quelques conseils pour créer votre document
le nom du service, peut prendre plusieurs attributs fa- WSDL :
cultatifs, qui le décrivent et déclarent les espaces de
noms utilisés (namespaces) à utiliser dans le reste du • Documentez toujours votre fichier WSDL, à la fois par
document. Ensuite, les types complexes nécessaires le biais de la balise documentation, et en fournissant
40 2/2011
Web Service
• Utilisez l’élément type, dans tous les cas, ne faites <!-- partie 1 : Definitions -->
pas référence aux types dans l’élément message.
<definitions name='getResult'
targetNamespace='http://example.org/getResult'
Exemples xmlns:tns='http://example.org/getResult'
xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
Je vais vous décrire pas à pas la construction du xmlns:xsd='http://www.w3.org/2001/XMLSchema'
WSDL : xmlns:soapenc='http://schemas.xmlsoap.org/soap/
encoding/'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
• Le Listing 1 commence par définir l’entête XML, xmlns='http://schemas.xmlsoap.org/wsdl/'>
...
puis l’élément definitions. </definitions>
• Le Listing 2 présente l’élément message.
Listing 2. Partie 2 : Message
Le Listing 3 présente l’élément PortType. Un port est ...
<message name='getResultRequest'>
simplement une suite d’opérations. Dans de nombreux <part name='operation' type='xsd:string'/>
langages de programmation, on appelle ceci une biblio- <part name='integer1' type='xsd:int'/>
<part name='integer2' type='xsd:int'/>
thèque, un module ou une classe, mais dans le mon- </message>
de des Web Services, les points de connexion sont <message name='getResultResponse'>
<part name='result' type='xsd:string'/>
des ports, et la définition abstraite d’un port est appe- </message>
lée Type de Port. Ici, nous créons la définition abstraite ...
d’une procédure getResult, en WSDL, dont l’input est Listing 3. Partie 3 : PortType
le message d’invocation de la méthode, et l’output le
...
message de retour de la méthode. <portType name='getResultPortType'>
Le Listing 4 va décrire l’élément binding du WSDL. <operation name='getResult'>
<input message='tns:getResultRequest'/>
Cette partie va nous permettre de rattacher le port à SOAP. <output message='tns:getResultResponse'/>
Les types de ports sont indépendants du protocole. Ici, </operation>
</portType>
nous utiliserons des requêtes SOAP (soap:binding) de ...
type RPC (style='rpc') via HTTP(transport='http://
schemas.xmlsoap.org/soap/http') avec un encodage Listing 4. Partie 4 : Binding
SOAP (encodingStyle='http://schemas.xmlsoap. ...
org/soap/encoding/'). <binding name='getResultBinding' type='tns:
getResultPortType'>
Le Listing 5 présente l’élément service. Le service, <soap:binding style='rpc' transport='http://
déclaré ci-dessous, est défini avec une seule occurren- schemas.xmlsoap.org/soap/http'/>
<operation name='getResult'>
ce du port getResultPort, ainsi que la définition de ce <soap:operation soapAction='urn:xmethods-
service. Le port est lié à la liaison getResultBinding. delayed-quotes#getResult'/>
<input>
Enfin, on donne l’information sur l’URL du point de sor- <soap:body use='encoded' namespace='urn:
xmethods-delayed-calcul'
tie de l’application (ici l’URL du serveur SOAP). encodingStyle='http://schemas.xmlsoap.org/
Remarque : Notez bien que si on ne trouve qu’un seul soap/encoding/'/>
</input>
élément documentation dans cet exemple, il faudra nor- <output>
malement en déclarer un pour chaque élément… L’exem- <soap:body use='encoded' namespace='urn:
xmethods-delayed-calcul'
ple montre bien le caractère verbeux de WSDL. Cepen- encodingStyle='http://schemas.xmlsoap.org/
dant, il est dans la pratique assez rare d’écrire le corps du soap/encoding/'/>
</output>
fichier à la main : la plupart des environnements de déve- </operation>
loppement savent en effet générer le fichier WSDL sur la </binding>
...
base des caractéristiques du service développé.
Listing 5. Partie 5 : Service
Séparation et capitalisation ...
La facilité de maintenance est toujours au cœur des préoc- <service name='getResultService'>
<documentation>Retourne le résultat de l'opération
cupations des éditeurs. Il se révèle de ce point de vue très </documentation>
bénéfique de distinguer dans un contrat WSDL l’aspect <port name='getResultPort' binding='getResultBindi
ng'>
Abstrait (ce qui est indépendant de la technologie et des <soap:address location='http://votre-adresse.com/
protocoles) et l’aspect Concret (ce qui est dépendant). samples/soap-server.php'/>
</port>
Cette distinction permet de joindre ou réutiliser des sous- </service>
parties de modèles WSDL et de les redéployer à loisir : ...
le WSDL est classiquement séparable en trois parties :
www.phpsolmag.org 41
Pratique
42 2/2011
Web Service
www.phpsolmag.org 43
Pour les débutants
SQL/PHP :
communication avec une base
de données avec PDO (1/2)
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 à vous connecter à une base
de données grâce à PHP via l’extension PDO.
D
e nombreuses applications web utilisent des cilite le développement, en effet il suffit de connaître
bases de données afin de stocker des infor- les fonctions d’une seule API pour communiquer avec
mations nécessaires à l’application : blogs, fo- les principaux SGBD utilisés dans le développement
rums, paniers de commande, galeries d’images, etc. d’applications web. L’utilisation de PDO facilite éga-
Une application web utilisant une base de données re- lement la migration de base de données dans le code
pose sur une architecture client/serveur mettant en jeu d’une application. Par exemple, si l’application repose
un serveur web permettant l’exécution de programmes sur MySQL et qu’une migration vers PostgreSQL est
(Apache avec le module PHP), un serveur de base de réalisée, les fonctions utilisées dans le code PHP pour
données (MySQL, Oracle, PostgreSQL, …) et un client envoyer des requêtes et les traiter restent les mêmes.
web (navigateur). Le client émet une requête HTTP. Le La migration nécessite uniquement la modification de
serveur web la reçoit et transmet une réponse HTTP la ligne de code indiquant le pilote utilisé, à condition
au client. Lorsque la réponse nécessite l’interrogation bien sûr que les requêtes suivent strictement la norme
d’une base de données, une interface de programma- SQL.
tion (API) est utilisée. Le serveur web et le serveur de Cet article sera illustré par l’exemple d’une biblio-
base de données peuvent être installés sur un même thèque dont le schéma est le même que celui don-
ordinateur (en local) ou sur deux ordinateurs distants né dans les précédents articles de la série SQL, pour
(Figure 1). laquelle deux utilisateurs ont été créés (lecteur
Dans les articles précédents de cette série SQL, et bibliothecaire) avec différents droits d’accès (voir
vous avez appris à créer une base de données, à stoc- la série d’articles sur SQL parus chaque mois depuis oc-
ker des informations et à extraire des données de la tobre 2010). Pour pouvoir reproduire cet exemple, vous
base. Vous allez à présent apprendre à vous connec- devez utiliser un serveur de base de données MySQL,
ter à une base de données et à l’interroger depuis un de préférence la version 5 et un serveur web avec PHP
script PHP avec PDO. Cette extension permet de se version 5. Les distributions XAMPP (Windows, Linux,
connecter à un SGBD, d’envoyer des requêtes et de Mac OS), WAMP (Windows), EasyPHP (Windows) ou
traiter les résultats. C’est une interface dédiée à l’in- MAMP (Mac OS) vous fourniront l’environnement de
terrogation et à la manipulation de bases de données. travail nécessaire.
Elle présente l’avantage de ne pas être spécifique La première partie de cet article présente les termes
à un SGBD, comme le sont les extensions fournies par et la notation objet nécessaires à la compréhension
les éditeurs de bases de données (extensions mys- et à l’utilisation de l’extension PDO. Vous apprendrez
qli et mysql pour MySQL, extension OCI8 pour Ora- ensuite à vous connecter à une base de données, à la
cle, extension pgsql pour PostgreSQL, …). Ceci fa- manipuler et à l’interroger via PDO.
44 2/2011
SQL et PDO
Notation objet
Une classe est un modèle pour créer plusieurs objets
présentant des caractéristiques communes. Elle définit
des propriétés (variables) et des méthodes (fonctions).
Chaque objet peut être manipulé en utilisant ses mé-
thodes.
Avant de présenter les classes utilisées dans cet ar-
ticle, voici un exemple concret pour illustrer les notions
de classe, méthodes et propriétés. Une classe Contact
pourrait être utilisée pour stocker les contacts d’un car-
net d’adresse. Les informations stockées pour cha-
que contact sont les propriétés de cette classe (nom,
prénom, date de naissance, adresse, numéro de télé-
phone, …). Chaque personne du carnet est un objet
Contact. Les informations contenues dans chaque objet Figure 1. Serveur Web et serveur de bases de données
sont spécifiques à une personne du carnet, mais cha-
que objet suit le même modèle. Des opérations peuvent Accéder à une constante
être réalisées sur un objet, telles que le calcul de l’âge Lorsque des constantes de classe sont utilisées, el-
à partir de la date de naissance. Le résultat de ce calcul les doivent être préfixées du nom de la classe suivi de
est spécifique à la valeur de la propriété date de nais- l’opérateur de résolution de portée (::). La classe PDO
sance de chaque contact, mais les instructions pour ef- a une constante ATTR_SERVER_VERSION qui peut être
fectuer le calcul sont identiques pour chaque objet. El- passée en paramètre à la méthode getAttribute afin
les sont donc placées dans une méthode de la classe d’obtenir la version du serveur de base de données :
Contact.
Dans cet article, trois classes prédéfinies seront uti- $cnx->getAttribute(PDO::ATTR _ SERVER _
lisées : VERSION);
www.phpsolmag.org 45
Pour les débutants
46 2/2011
SQL et PDO
valeur dans le tableau associatif d’options $options Lorsque le serveur Web et le SGBD ne sont pas situés
du Listing 1 : sur le même ordinateur, il faut s’assurer également que
l’utilisateur est autorisé à se connecter à la base depuis
PDO::ATTR_PERSISTENT => true le serveur Web.
Lorsqu’une connexion échoue, une exception PDO
Gérer les erreurs est levée. L’exception est un objet PDOException qui
Les erreurs peuvent intervenir à différents niveaux lors fournit des informations sur l’erreur survenue : code
de la connexion, et génèrent ainsi des messages spé- d’erreur, fichier, numéro de ligne et texte explicatif en
cifiques : anglais quant à l’exception survenue. Ces informations
sont retournées respectivement par les méthodes get-
− nom d'utilisateur ou mot de passe incorrect : Code, getFile, getLine et getMessage de la classe
Access denied for user ‘bibliothecair’@’localhost’ PDOException (Tableau 1). Le message renvoyé par
(using password: YES) getMessage comporte trois parties, un code d’erreur
− adresse du serveur de bases de données incorrec- de cinq caractères défini dans le standard ANSI SQL
te : (SQLSTATE), un code et un message d’erreur spécifi-
Unknown MySQL server host ‘loclhost’ ques au pilote (ici mysql) :
− port incorrect :
Can’t connect to MySQL server on ‘localhost’ SQLSTATE[28000] [1045] Access denied for user ‘bi-
− nom de base erroné : bliothecair’@’localhost’ (using password: YES)
Access denied for user ‘bibliothecaire’@’%’ to data-
base ‘bibio’ L’utilisation d’exceptions permet de centraliser le traite-
− login et mot de passe de l'utilisateur correct, mais ment des erreurs. Les exceptions doivent être intercep-
aucun privilège sur la base demandée : tées et traitées. Pour ce faire, il faut utiliser deux blocs
Access denied for user ‘pierre’@’%’ to database ‘bi- : try et catch. L’instruction qui est susceptible de pro-
blio’ voquer l’exception est placée dans un bloc try. Si un
www.phpsolmag.org 47
Pour les débutants
problème survient lors de la création de l’objet, PHP igno- Cette erreur est retournée au navigateur et/ou stockée
re la suite des instructions dans le bloc try et exécute les dans le fichier de log des erreurs, en fonction des régla-
instructions du bloc catch, où sont centralisés les trai- ges du fichier php.ini.
tements des erreurs. Il faut préciser entre parenthèses
le type d’exceptions à intercepter (PDOException) ainsi Modifier la base
que la variable qui va stocker les informations ($e) : Maintenant que vous êtes connectés à la base de données,
vous pouvez apporter des modifications à celle-ci. Dans l’ar-
try{ ticle SQL : langage de manipulation des données du mois
/* code de connexion à la base et de décembre 2010, vous avez appris à insérer des données
manipulation des données */ (INSERT), les modifier (UPDATE) ou les supprimer (DELETE).
}catch (PDOException $e){ Vous allez maintenant voir comment soumettre ces requê-
/* traitement des erreurs */ tes au SGBD avec PDO. La méthode est la même pour tou-
} tes ces requêtes qui n’extraient pas d’information de la base.
Cette partie sera illustrée par une commande d’insertion.
Si la connexion est réalisée sans erreur, alors toutes les
instructions du bloc try sont exécutées et le contenu du Soumettre la requête
bloc catch est ignoré. Le Listing 2 insère un nouvel auteur dans la table auteur
Le bloc catch du Listing 2 intercepte et traite l’excep- de la base biblio. La requête SQL stockée dans la va-
tion. En cas d’erreur, un message est affiché. Il contient le riable $req_insert est la suivante :
48 2/2011
SQL et PDO
INSERT INTO auteur (nom, prenom, date _ de exec retourne la valeur false. Dans ce cas, le déve-
naissance) VALUES ('Pagnol','Marcel', '1895-02-28') loppeur doit faire un test pour vérifier si la modification
de la base a réussi. Attention, une requête qui ne pro-
L’identifiant de l’auteur ne nécessite pas d’être rensei- duit pas d’erreur mais qui n’a affecté aucune ligne dans
gné car il est incrémenté automatiquement par MySQL la base de données retournera la valeur 0 (instructions
lors d’une insertion. UPDATE ou DELETE). Cette valeur est interprétée comme
La méthode exec de la classe PDO envoie au ser- false dans un test, pensez donc à utiliser l’opérateur
veur la requête SQL passée en paramètre : de comparaison tenant compte du type === afin de vous
assurer dans le test que la valeur retournée est le boo-
$cnx->exec($req _ insert); léen false et non pas l’entier 0. Lorsque l’attribut AT-
TR_ERRMODE prend la valeur ERRMODE_EXCEPTION, une
Elle retourne un entier correspondant au nombre de li- exception est générée lorsqu’il y a une erreur. C’est la
gnes affectées par la requête. Dans le cas d’une de- solution choisie dans cet article (Listing 1).
mande de mise à jour ou de suppression, il peut y avoir Il est préférable de tester vos requêtes en mode
zéro, une ou plusieurs lignes concernées en fonction de console ou grâce à phpMyAdmin avant de les insérer
la restriction. dans votre script afin de bien vérifier qu’elles ne com-
portent aucune erreur de syntaxe ou autre.
Gérer les erreurs
Il existe différents types d’erreurs pouvant empêcher Interroger la base
une insertion, une modification ou une suppression de La création d’une page Web présentant des données
données : extraites d’une base de données suit toujours les mê-
mes étapes : le script PHP établit une connexion vers
− nom de table incorrect : le serveur de base de données. La requête SQL est
Table ‘biblio.autur’ doesn’t exist envoyée au serveur de base de données. Celui-ci l’exé-
− nom de colonne incorrect : cute et retourne un résultat au script PHP. Le script ex-
Unknown column ‘prnom’ in ‘field list’ trait les données de chaque ligne de résultat, les met en
− erreur de syntaxe (oubli d'opérateur, de parenthè- forme et les envoie au navigateur.
ses, …) : Dans cette partie, vous allez apprendre à soumettre
You have an error in your SQL syntax; [...] une requête SQL de sélection au SGBD, extraire et pré-
− duplication de la clé primaire (insertion et modifica- senter les données du résultat.
tion) :
Duplicate entry ‘7’ for key ‘PRIMARY’ Soumettre la requête
− enregistrement d'une clé étrangère non référencée Le Listing 2 affiche tous les auteurs de la table auteur
(insertion et modification) : de la base biblio dans l’ordre alphabétique (Figure 3).
Cannot add or update a child row: a foreign key Il soumet la requête suivante stockée dans la variable
constraint fails ('biblio'.'livre', CONSTRAINT 'fk_zo- $req_affich :
ne' FOREIGN KEY ('code_zone') REFERENCES
'zone' ('code_zone') ON DELETE SET NULL ON SELECT nom, prenom FROM auteur ORDER BY nom;
UPDATE CASCADE)
− non renseignement d'une donnée de type NOT NULL La méthode query de la classe PDO envoie la requête
(insertion et modification) : au SGBD :
Field ‘titre’ doesn’t have a default value
− erreur de type de données (insertion et modifica- $res = $cnx->query($req _ affich);
tion) :
Incorrect integer value: ‘tre’ for column ‘nb_pages’ Elle retourne un objet de la classe PDOStatement stoc-
at row 1 ké dans la variable $res dans cet exemple. Cet objet
− nombre de valeurs différentes du nombre de colon- permet de manipuler les lignes du résultat retourné par
nes indiquées (insertion) : le SELECT.
Column count doesn’t match value count at row 1
− utilisateur avec privilèges insuffisants (droit de lec- Extraire le résultat
ture uniquement) : Le résultat de la requête SELECT peut comporter zéro,
INSERT command denied to user ‘lec- une ou plusieurs lignes. Le parcours du résultat est réa-
teur’@’localhost’ for table ‘livre’ lisé ligne par ligne, en utilisant une boucle while. La mé-
thode fetch de la classe PDOStatement extrait la ligne
En cas d’erreur le comportement de PDO est fixé par la suivante du résultat (ici stocké dans $res) et la retourne.
valeur de l’attribut ATTR_ERRMODE. Par défaut, la métho- Lorsque toutes les lignes du résultat ont été extraites, la
www.phpsolmag.org 49
Pour les débutants
50 2/2011
Sécurité
La sécurité
de l'information
Cet article présente d’une manière générale la sécurité
de l’information dans un contexte professionnel.
A
ujourd’hui la plupart des données d’une entre- l’information regroupe tous les moyens techniques
prise sont informatisées. Dans la mesure où les et fonctionnels à mettre en œuvre pour protéger les
menaces à l’encontre de la sécurité de l’infor- données d’une société.
mation se veulent chaque jour davantage féroces et po-
lymorphes, il est fondamental de sécuriser au maximum • Disponibilité : l’information doit être continuelle-
ces données. ment disponible.
Les grands acteurs technologiques comme Goo- • Intégrité : l’information ne doit pas être altérée.
gle, Microsoft ou Yahoo sont régulièrement victimes • Confidentialité : l’information doit être uniquement
d’attaques informatiques. Ces dernières ont, depuis accessible aux personnes autorisées.
leur existence au début des années 2000 des visées • Preuve/Traçabilité : Tous les mouvements de don-
intellectuelles, mais pas seulement. Le hacker des nées doivent être tracés.
années 2000, fier d’avoir pénétré un système d’in-
formation sans l’avoir dégradé pour autant, a bien La mise en place d’un processus
évolué. Pour sécuriser l’information, il convient de mettre en
Actuellement, toute attaque informatique, ou pres- place un processus de protection des données. Ce pro-
que, comporte des objectifs lucratifs ou destructeurs. cessus doit suivre les étapes suivantes :
L’espionnage industriel par exemple peut motiver un
hacker. Une tierce personne lui achète les informations • Inspection : Evaluer les besoins en sécurité de
de recherche dans le but de développer la concurrence. l’entreprise…
Une tâche grassement/hautement rémunérée qui attire • Protection : …avant d’appliquer des moyens de
plus d’un pirate informatique. protection de l’information.
Dans ce contexte ô combien hostile, nous définirons • Détection : Mettre en œuvre des moyens pour pré-
d’abord la sécurité de l’information, avant d’aborder les venir l’attaque…
moyens techniques et fonctionnels utilisés à l’heure ac- • Réaction : …afin d’être réactif en cas d’atta-
tuelle pour protéger le système d’information d’une en- que et pouvoir élaborer un plan de reprise d’ac-
treprise. tivité…
• Réflexion : …et procéder à une analyse post-in-
Définition cident.
La sécurité de l’information est un processus qui vise
à protéger les données d’une société. La sécurité de Les moyens techniques de protection
www.phpsolmag.org 51
Sécurité de l’information
52 2/2011
Sécurité
Réflexion
Chaque incident de sécurité doit être analysé après l’in-
cident. Il convient de s’interroger sur la cause de l’inci-
dent. Il faut ensuite mettre en œuvre des mesures pour
que ce type d’incident ne se reproduise plus. Dans cer-
tains cas, des poursuites judiciaires peuvent être en-
gagées.
Normes
Une norme est un document de référence décrivant des
mesures à mettre en œuvre. Les normes ISO 27001
et ISO 27002, par exemple, sont de plus en plus utili-
sées pour sécuriser l’information.
Figure 3. Exemple d’architecture de protection des accès ditants. La norme ISO 27001 décrit la mise en œuvre d’un
système de management de la sécurité de l’informa-
indispensables comme les ports USB, les lecteurs tion. Et la norme ISO 27002 prévoit les bonnes prati-
de cartes ou encore les lecteurs de CD/DVD est in- ques de sécurité à mettre en œuvre au sein du système
dispensable. d’information.
Il existe aussi une norme de gestion des risques :
Les moyens fonctionnels de protection l’ISO 27005.
Des mesures fonctionnelles doivent aussi exister afin
de compléter les mesures techniques précédemment Méthodes
décrites. Ces moyens fonctionnels doivent être a mi- En sécurité de l’information, il existe plusieurs métho-
nima les suivants : des pour réaliser des analyses de risques. Parmi les
plus connues, on peut citer les méthodes suivantes :
• Politique de sécurité : une politique de sécurité
du système d’information doit être écrite et respec- • MEHARI,
tée au sein de l’organisation. • EBIOS.
• Sécurité physique : des mesures de sécurité phy-
sique doivent être mises en œuvre (accès aux lo- Conclusion
caux par badge, accès au datacenter, etc.) La sécurité de l’information est aujourd’hui un maillon
• La sensibilisation des utilisateurs : les utilisa- indispensable à la bonne gestion d’une entreprise. Il
teurs étant bien souvent les maillons faibles de la convient donc de ne pas la prendre à la légère et d’en
sécurité, il convient de réaliser des campagnes de respecter, a minima, les bonnes pratiques. Malheureu-
sensibilisation régulières. sement, force est de constater que la sécurité de l’infor-
• La désignation d’un responsable de la sécurité mation est rarement l’une des préoccupations majeures
du système d’information : un RSSI doit être dé- des entreprises.
signé afin de gérer toutes les activités sensibles de
l’entreprise.
Détection et réaction
Des équipes opérationnelles doivent être présentes afin
de maintenir à jour l’architecture technique ainsi que
les moyens fonctionnels décrits précédemment. Ces
équipes doivent aussi mettre en place des moyens de
détection. Cela peut par exemple être des remontées
d’alertes depuis les systèmes. Par exemple, s’il y a cin-
quante tentatives de connexion sur un système avec un
mot de passe erroné, il y a alors de grandes probabilités
que le système soit victime d’une attaque par brute for-
ce. L’équipe opérationnelle doit alors agir. Cette même
équipe doit aussi analyser régulièrement les journaux Tony Fachaux
des équipements. L’auteur travaille en tant que consultant sécurité pour la société
Toute détection d’incident doit être résolue et remon- LEXSI (Laboratoire d’EXpertise en Sécurité Informatique). Il se pas-
tée au responsable afin de prendre des mesures cor- sionne pour toutes les problématiques liées à la sécurité dans un
rectrices. contexte professionnel.
www.phpsolmag.org 53
Rejoignez le Club .PRO
Sécurité de l’information
Pour plus de renseignement : editor@phpsolmag.org
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éciques ; 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
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
54 2/2011
Sécurité
www.phpsolmag.org 55