PHP Bertrand Estellon Aix-Marseille Université 26 avril 2012 Bertrand Estellon (AMU) PHP 26 avril 2012 1 / 214
SQLite et PDO Base de données SQLite et PDO SQLite écrit les données relatives à la base dans un unique fichier sur le disque dur du serveur. La commande sqlite3 permet d ouvrir la base et effectuer des requêtes SQL (pratique pour débugger). PDO (PHP Data Objects) est une interface pour accéder à une base de données depuis PHP. Elle gère la connexion, l envoie des requêtes, la déconnexion à la base de données. Elle permet de changer plus facilement de moteur de bases de données (Par exemple, SQLite MySQL). Ouverture de la base : <? t r y { $bd = new PDO( s q l i t e : d a t a b a s e. s q l i t e ) ; c a t c h ( PDOException $e ) { d i e ( E r r e u r :. $e >getmessage ( ) ) ;?> Bertrand Estellon (AMU) PHP 26 avril 2012 154 / 214
SQLite et PDO Une fois l instance de PDO construite, vous effectuez des requêtes avec : $bd->exec($requete) : pour modifier la base de données $bd->query($requete) : pour extraire des données de la base Exemples : $bd >e x e c ( CREATE TABLE u s e r s (. nickname c h a r ( 2 0 ),. p a ssword c h a r ( 5 0 ). ) ; ) ; $ r e s =$bd >e x e c ( UPDATE u s e r s SET p a ssword =. md5( $password ). WHERE nickname =. $nickname. ; ) ; echo nombre de l i g n e s m o d i f i e e s = $ r e s ; $ r e s = $bd >q u e r y ( s e l e c t nickname from u s e r s ; ) ; Bertrand Estellon (AMU) PHP 26 avril 2012 155 / 214
Injections SQL Base de données Le code suivant : $nickname = aa ; DELETE FROM u s e r s ;. SELECT FROM u s e r s WHERE nickname = ; $password = t r u c ; $ r e s = $bd >e x e c ( UPDATE u s e r s SET p a ssword =. md5( $password ). WHERE nickname =. $nickname. ; ) ; exécute la requête SQL suivante : UPDATE u s e r s SET p a ssword=.... WHERE nickname= aa ; DELETE FROM u s e r s ; SELECT FROM u s e r s WHERE nickname= ; Protection contre les injections SQL : $ r = $bd >p r e p a r e ( UPDATE u s e r s SET p a ssword =?. WHERE nickname =? ) ; $r >e x e c u t e ( a r r a y (md5( $password ), $nickname ) ) ; Bertrand Estellon (AMU) PHP 26 avril 2012 156 / 214
SQLite et PDO Base de données Pour faire une requête SQL : $ r e s = $bd >q u e r y ( s e l e c t from s o n d a g e s ) ; var dump ( $ r e s ) ; affiche object(pdostatement)#2 (1) { [ querystring ]=> string(19) select * from sondages Pour connaître le nombre de lignes : echo nombre de l i g n e s :. $ r e s >rowcount ( ). \n ; Pour parcourir les lignes : $ r e s = $bd >q u e r y ( s e l e c t from s o n d a g e s ) ; w h i l e ( $ l i g n e = $ r e s >f e t c h ( ) ) { echo $ l i g n e [ c r e a t e u r ]. pose l a q u e s t i o n :. $ l i g n e [ q u e s t i o n ]. \n ; Bertrand Estellon (AMU) PHP 26 avril 2012 157 / 214
SQLite et PDO Pour mettre toutes les lignes dans un tableau : $ r e s = $bd >q u e r y ( s e l e c t from s o n d a g e s ) ; $ l i g n e s = $ r e s >f e t c h A l l ( ) ; f o r e a c h ( $ l i g n e s as $ l i g n e ) { echo $ l i g n e [ c r e a t e u r ]. pose l a q u e s t i o n :. $ l i g n e [ q u e s t i o n ]. \n ; Voir aussi, dans la classe PDOStatement, les méthodes : bindcolumn : attache une variable à une colonne errorinfo : information d erreur fetchcolumn : récupère la valeur dans une colonne donnée closecursor : ferme le curseur Bertrand Estellon (AMU) PHP 26 avril 2012 158 / 214
SQLite et PDO Voir aussi, dans la classe PDO, les méthodes : begintransaction : démarre une transaction commit : valide une transaction rollback : annule une transaction errorinfo : Retourne les informations associées à l erreur errorcode : Retourne le SQLSTATE associé avec la dernière opération prepare : Prépare une requête à l exécution et retourne un objet quote : Protège une chaîne pour l utiliser dans une requête SQL PDO $ s t r i n g = Chaine \ p a r t i c u l i e r e ; p r i n t non echappee : $ s t r i n g \n ; p r i n t echappee :. $bd >quote ( $ s t r i n g ). \n ; Chaine non echappee : Chaine particuliere Chaine echappee : Chaine particuliere Bertrand Estellon (AMU) PHP 26 avril 2012 159 / 214
Base de données du projet Les trois tables utilisées dans le projet : u s e r s ( nickname c h a r ( 2 0 ), p a ssword c h a r ( 5 0 ) ) ; s u r v e y s ( i d i n t e g e r p r i m a r y key a u t o i n c r e m e n t, owner c h a r ( 2 0 ), q u e s t i o n c h a r ( 2 5 5 ) ) ; r e s p o n s e s ( i d i n t e g e r p r i m a r y key a u t o i n c r e m e n t, i d s u r v e y i n t e g e r, t i t l e c h a r ( 2 5 5 ), count i n t e g e r ) ; Bertrand Estellon (AMU) PHP 26 avril 2012 160 / 214
Exemple : sauvegarde d un sondage p u b l i c f u n c t i o n s a v e S u r v e y (& $ s u r v e y ) { i f ( $ s u r v e y >g e t I d ()!== n u l l ) r e t u r n f a l s e ; $ t h i s >c o n n e c t i o n >b e g i n T r a n s a c t i o n ( ) ; $ r = $ t h i s >c o n n e c t i o n >p r e p a r e ( INSERT INTO s u r v e y s ( owner,. q u e s t i o n ) VALUES (?,? ) ; ) ; i f ( $ r===f a l s e ) { $ t h i s >c o n n e c t i o n >r o l l b a c k ( ) ; r e t u r n f a l s e ; i f ( $r >e x e c u t e ( a r r a y ( $ s u r v e y >getowner ( ), $ s u r v e y >g e t Q u e s t i o n ()))=== f a l s e ) { $ t h i s >c o n n e c t i o n >r o l l b a c k ( ) ; r e t u r n f a l s e ; $ i d = $ t h i s >c o n n e c t i o n >l a s t I n s e r t I d ( ) ; $ s u r v e y >s e t I d ( $ i d ) ; f o r e a c h ( $ s u r v e y >g e t R e s p o n s e s ( ) a s $ r e s p o n s e ) i f (! $ t h i s >s a v e R e s p o n s e ( $ r e s p o n s e ) ) { $ t h i s >c o n n e c t i o n >r o l l b a c k ( ) ; r e t u r n f a l s e ; $ t h i s >c o n n e c t i o n >commit ( ) ; r e t u r n t r u e ; Bertrand Estellon (AMU) PHP 26 avril 2012 161 / 214
La classe Database Base de données c l a s s Database { p r i v a t e $ c o n n e c t i o n ; p u b l i c f u n c t i o n c o n s t r u c t ( ) {... p u b l i c f u n c t i o n checkpassword ( $nickname, $password ) {... p u b l i c f u n c t i o n adduser ( $nickname, $password ) {... p u b l i c f u n c t i o n u p d a t e U s e r ( $nickname, $password ) {... p u b l i c f u n c t i o n s a v e S u r v e y (& $ s u r v e y ) {... p u b l i c f u n c t i o n loadsurveysbyowner ( $owner ) {... p u b l i c f u n c t i o n loadsurveysbykeyword ( $keyword ) {... p u b l i c f u n c t i o n v o t e ( $ i d ) {... p r i v a t e f u n c t i o n c r e a t e D a t a B a s e ( ) {... p r i v a t e f u n c t i o n c h e c k N i c k n a m e V a l i d i t y ( $nickname ) {... p r i v a t e f u n c t i o n c h e c k P a s s w o r d V a l i d i t y ( $password ) {... p r i v a t e f u n c t i o n c h e c k N i c k n a m e A v a i l a b i l i t y ( $nickname ) {... p r i v a t e f u n c t i o n s a v e R e s p o n s e (& $ r e s p o n s e ) {... p r i v a t e f u n c t i o n l o a d S u r v e y s ( $ a r r a y S u r v e y s ) {... p r i v a t e f u n c t i o n l o a d R e s p o n s e s (& $ s u r v e y, $ a r r a y R e s p o n s e s ) {... Bertrand Estellon (AMU) PHP 26 avril 2012 162 / 214
Persistance et mapping objet-relationnel (ORM) Les besoins : Sauvegarde simple des objets en base de données : $ u s e r = new User ( ) ; $ u s e r >nickname = bob ; $ u s e r >p a ssword = md5( t r u c ) ; $ u s e r >s a v e ( ) ; Création automatique des tables ; Chargement des objets ; Gestion des relations entre les objets/enregistrements ;... Quelques solutions en PHP : Propel Doctrine Zend Framework Redbean... Bertrand Estellon (AMU) PHP 26 avril 2012 163 / 214