79
PHP Architectures avancées Resp: S. SALVA IUT 2ème année IUT daubiere

PHP Architectures avancées

  • Upload
    others

  • View
    11

  • Download
    0

Embed Size (px)

Citation preview

Page 1: PHP Architectures avancées

PHP

Architectures avancées

Resp: S. SALVA IUT 2ème année IUT d’aubiere

Page 2: PHP Architectures avancées

•Séparation du traitement des données•Utilisation de plusieurs classes à partir du CGI initial•Modèle Service to Workers•Modèle vue/contrôleur

Index.php

Chargement d’un objet

Traitement

Évite la redondance

Facilite la réutilisation

2

Page 3: PHP Architectures avancées

Quels exemples de classes donneriez vous ?????

3

Page 4: PHP Architectures avancées

4

Page 5: PHP Architectures avancées

Modèle vue contrôleur

•Séparer l’affichage du traitement

•Définition de rôles (qui fait l’affichage, etc.)

•Utilisation de plusieurs fichiers et classes (traitement, affichage, etc.)

Programmation extrêmement répandue, notamment en Web !

ex: Servlet/JSP (struts, spring) en Java

ex: php.mvc, symfony, zend, Yii, Code Igniter, etc. en php

5

Page 6: PHP Architectures avancées

Modèle vue contrôleur

Plusieurs possibilités:

1. Développement d’un MVC complet qui est proche du problème traité (peu fréquent)

2. Utilisation d’un framework MVC

• Nécessité de comprendre, de se former mais ensuite rapidité d’implantation, garantie qualité de certaines parties (DAL, etc.)

=>Il faut comprendre le MVC -> retour à 1. (Et pourquoi de ce cours)

6

Page 7: PHP Architectures avancées

Aujourd’hui, une application web, est au moins basée sur une architecture 3 tiers

Couche utilisateur Couche métier Couche

persistanceutilisateur

Le MVC prend place dans la première couche

Serveur 1 Serveur 2

7

Page 8: PHP Architectures avancées

8

Architecture Vue en Module Objet 3

Page 9: PHP Architectures avancées

Modèle

Contrôleur

utilisateurCouche métier

Appel couche métiervue

voit

appelle

9MVC simple (non observeur observable)

Page HTML

appelle

Crée, extrait des données métier

Page 10: PHP Architectures avancées

Organisation des répertoires:

Index.php =><?php//appel au contrôleur (si un seul controler ou appel front controler) ?>

10

Page 11: PHP Architectures avancées

Contrôleur

C’est toujours le contrôleur qui est appelé

Son rôle:

1. Contrôler l’intégrité des données reçues (Validation)

(peut aussi être fait par modèle)

2. Lecture d’une action:

Action: donnée par la vue

=>indique le traitement à faire

3. Création d’un modèle, gestion des données

4. Redirection vers la vue en donnant les données (=>page réponse ou une page d’erreur)

Contrôleur gère les erreurs (classiques + exceptions !!!)11

Page 12: PHP Architectures avancées

Les actions ?

Ex: connecter, ajouterLivre, supprimerLivre, Action NULL ( ou pas d’action ->en général appel page principale)

=> Toujours commencer par effectuer une analyse !!!

<?phpClass ControllerUser {

Si Action1 -> méthode 1…Si Action n -> méthode n?>

12

Page 13: PHP Architectures avancées

Les actions ? Comment les donner ?

Sur un lien, GET<a href=http://…?action=etre_attentif</a>

Dans un formulaire GET ou POST<form action=http://…?action=etre_attentif

Ou<input type=hidden name=action…>

13

Page 14: PHP Architectures avancées

Classe Controller<?php

class controller {

function __construct() {//code du contrôleur ici// on démarre ou reprend la sessionsession_start();…try{$action=$_REQUEST['action'];switch($action) {case NULL:

$this->action();break;

case "action2":$this->action2();break;

…}} catch (PDOException $e){

//si erreur BD, pas le cas ici$dataVueEreur[] = "Erreur

inattendue!!! ";require(__DIR__.'/../vues/erre

ur.php'); // ajout du code de la vue ici}

catch (Exception $e2){$dataVueEreur[] = "Erreur

inattendue!!! ";require ($rep.$vues['erreur']);}

}//fin constructeur

14

Page 15: PHP Architectures avancées

function action1() {//traitement$mdl = new modele();$mdl->traitement();$dVue = array (

//exemple données dans un tableau);

//utilisation d’une vue pour afficherrequire(__DIR__.'/../vues/vueaction1.php'); }?>}//fin class

Contrôleurs toujours identiques, pas besoin du pattern observeur/observable(possible avec closure et classes anonymes…)

=> Facile à faire depuis une analyse !

15

Page 16: PHP Architectures avancées

Resp: S. SALVA IUT 2ème année GI IUT d’aubiere

Couche qui manipule les données

peut valider les données

peut être simple: retourne une chaîne ? Une liste de chaîne

Souvent fait appel à DAL pour extraire des collections d’objets

-> appel aux classes ***Gateway (cours PDO et DAL)

Modèle = classe, pas d’HTML ou autre

Session, cookies ? Idéalement gestion par un modèle

Modèle

16

Page 17: PHP Architectures avancées

Remarques:

Parfois, il n’y a pas de modèle

Pas de SQL dans un modèle, ni de parseur, etc.

Une méthode d’un modèle peut faire plusieurs choses : demander une collection d’objets depuis une BD, mettre à jour une session, etc.

Modèle

17

Page 18: PHP Architectures avancées

Vue(html+php)

Vue : code html+php qui produit la page HTML (php est utilisé en moteur de template)

1. Récupère des variables produites par contrôleur ou modèle (tableaux, variables, etc.)

2. Crée la page avec ces données et echo et boucles

Attention: ne se connecte pas à la base ou ne modifie pas des données => c’est le modèle qui le fait !!!

Pas de : $_GET, $_POST, $_SESSION, etc. car ces données ne sont pas validées !

Les boutons (ou autres) de la vue font appels uniquement à des contrôleurs en leur donnant des paramètres et une action !

18

Page 19: PHP Architectures avancées

Contrôleur

Récupérationaction

Try{switchaction1

appelméthode1

switchaction2appelméthode2

…}Catch{pageerreur}Catch…

Methode méthode1//Appelmodele1($m=newmodele1();$m->mdl1();

classModele1{

publicmdl1()//remontéedesexceptionsverscontrôleur

Publicmld2()

Couchepersistance(gateway)

ClassModele2{

Publicglob1()

Publicglob2()

19

Appe

l

Appel

Page 20: PHP Architectures avancées

Exemple MVC (dispo sur mon site)

Site qui demande un nom, un age via un formulaire

retourne le même formulaire rempli avec le nom et l’age donné, + gestion des erreurs (de base)

Resp: S. SALVA IUT 2ème année GI IUT d’aubiere

Vues: erreur, vuephp1Modele: SimpleModele qui ne fait rien ici

20

Page 21: PHP Architectures avancées

Index.php

<?php//chargement configrequire_once(__DIR__.'/config/config.php');

//chargement autoloader pour autochargement des classesrequire_once(__DIR__.'/config/Autoload.php');Autoload::charger();

//chargement d’un controleur$cont = new controller();?>

21

Page 22: PHP Architectures avancées

config.php (exemple simple, il y a plein de façons de faire)Avec des variables globalesVariables récupérables dans des fonctions avec mot clé globalVoir http://php.net/manual/fr/language.variables.scope.php

<?php//préfixe$rep=__DIR__.'/../';

//BD$base="votre_base";$login="";$mdp="";

//Vues$vues['erreur']='vues/erreur.php';$vues['vuephp1']='vues/vuephp1.php';?> 22

Page 23: PHP Architectures avancées

Vuephp d’erreur (minimaliste)

<!DOCTYPE html> <html lang="fr"><body>

<h1>ERREUR !!!!!</h1>

<?php

if (isset($dataVueErreur)) {

foreach ($dataVueErreur as $value){echo $value;

}}?>

</body> </html>

Resp: S. SALVA IUT 2ème année GI IUT d’aubiere

donnéesobtenuesparlavariable$VueErreur

23

Page 24: PHP Architectures avancées

‘vuephp1.php'

<!DOCTYPE html> <html lang="fr">…<?php// on vérifie les données provenant du modèle if (isset($dataVue)) //tableau contenant les informations à afficher{?><center>

<?php

if (isset($dataVueEreur) && count($dataVueEreur)>0) {echo "<h2>ERREUR !!!!!</h2>";

foreach ($dataVueEreur as $value){echo $value;

}}?><h2>Personne - formulaire</h2><hr><!-- affichage des données provenant du modèle, juste pour exemple ici--> <?= $dataVue['data'] ?>

24

Page 25: PHP Architectures avancées

Resp: S. SALVA IUT 2ème année GI IUT d’aubiere

Donneicil’actionducontrôleur

<form method="post" ><table> <tr><td>Nom</td><td><input name="txtNom" value="<?= $dataVue['nom'] ?>" type="text" size="20"></td></tr>

<tr><td>Age</td><td><input name="txtAge" value="<?= $dataVue['age'] ?>" type="text" size="3"></td></tr><tr></table><table> <tr><td><input type="submit" value="Envoyer"></td>

<!-- action !!!!!!!!!! --> <input type="hidden" name="action" value="validationFormulaire"></form></center>

<?php }else {print ("erreur !!<br>");print ("utilisation anormale de la vuephp");} ?>

</body> </html> 25

Page 26: PHP Architectures avancées

class Validation {

static function val_form($nom,$age,&$dataVueEreur) {

if (!isset($nom)||$nom=="") {$dataVueEreur[] ="pas de nom";throw new Exception('pas d\'action');

}if (!isset($age)||$age=="") {

$dataVueEreur[] ="pas d'age ";throw new Exception('pas d\‘age');

}

}} ?>

Mais on peut aussi retourner un booleen

ValidationFormulaire=> valide les paramètres recus

26

Page 27: PHP Architectures avancées

<?php

class Controleur {

function __construct() {global $rep,$vues; // nécessaire pour utiliser

variables globalessession_start();

//on initialise un tableau d'erreur$dVueEreur = array ();

try{$action=$_REQUEST['action'];

switch($action) {

//pas d'action, on r�initialise 1er appelcase NULL:

$this->Reinit();break;

27

case "validationFormulaire":$this->ValidationFormulaire($dVueEreur);break;

//mauvaise actiondefault:$dVueEreur[] = "Erreur d'appel php";require ($rep.$vues['vuephp1']);break;}

} catch (PDOException $e){

//si erreur BD, pas le cas ici$dVueEreur[] = "Erreur inattendue!!! ";require ($rep.$vues['erreur']);

}catch (Exception $e2)

{$dVueEreur[] = "Erreur inattendue!!! ";require ($rep.$vues['erreur']);}

Page 28: PHP Architectures avancées

28

//finexit(0);}//fin constructeur

…function ValidationFormulaire(array $dVueEreur) {global $rep,$vues;

//si exception, ca remonte !!!$nom=$_POST['txtNom']; // txtNom = nom du champ texte dans le formulaire$age=$_POST['txtAge'];Validation::val_form($nom,$age,$dVueEreur);

$model = new Simplemodel();$data=$model->get_data();

$dVue = array ('nom' => $nom,'age' => $age,

'data' => $data,);require ($rep.$vues['vuephp1']);

}

Page 29: PHP Architectures avancées

Comment charger une classe ? – Require

– Mieux : autoloader

– spl_autoload_register — Enregistre une fonction en tant qu'implémentation de __autoload()->charge des classes

• http://php.net/manual/fr/language.oop5.autoload.php, que vous pouvez faire vous-même

• Autoloader PSR-0, PSR-4 si utilisation de Namespaces, http://www.php-fig.org/psr/psr-0/fr/, http://www.php-fig.org/psr/psr-4/

29

Page 30: PHP Architectures avancées

Exemple simple de classe de Chargement (de classes)class Autoload{

private static $_instance = null;

public static function charger(){

if(null !== self::$_instance) {

throw new RuntimeException(sprintf('%s is already started', __CLASS__));}

self::$_instance = new self();

if(!spl_autoload_register(array(self::$_instance, '_autoload'), false)) {

throw RuntimeException(sprintf('%s : Could not start the autoload', __CLASS__));}

}

…..

30

private static function _autoload($class){

global $rep; // récupère var. globales

$filename = $class.'.php';

$dir =array('modeles/','./','config/','controleur/');

foreach ($dir as $d){

$file=$rep.$d.$filename;

//echo $file;

if (file_exists($file))

{

include $file;}

}

}}

A chaque new -> on lance _autoload()

Page 31: PHP Architectures avancées

31

Page 32: PHP Architectures avancées

DAL

Présentation DAL� Couched’accèsauxdonnées(DAL)

Couche utilisateur Couche métier Couche

persistanceutilisateur

Serveur 1 Serveur 2

• Couche généralement composée de plusieurs classes• Permet de gérer les données à la sauce Objet

• on y trouve des patrons : singleton, fabrique, stratégie, etc.

32

Page 33: PHP Architectures avancées

Architecture DAL

BD

ClasseConnection

ConnexionàlaBD

Méthodespdo_php de

bases

CouchemétierClassesMétiers(livres,personnes,pattates,

etc.

Classemodèle

ClassesGateway

appelle

Crée, supp. Modifie des données

PasdeSQL!

Voir cours précédent

33

appelle

Page 34: PHP Architectures avancées

Architecture DAL

Couchemétier

Classemodèle

Exemple: on veut gérer des livres

Classe Book (POPO)Isbn, titre, getter, setter, etc.

Arrray Book Get_allbooks()

Array Book Get_allbooks_by_year(year)

Book Get_book(isbn)

Add_book(title, isbn) Classe

BookGateway

Array Book FindByYear(year) [ year = 0->toutes]

Book FindbyISBN(isbn)

insert(title, isbn)

34PasdeSQL

SQLIci

Page 35: PHP Architectures avancées

Architecture DALExemple: on veut gérer des livres

Classemodèle

Public function get_allbooks($year){

$b = new BookGateway(…); $Tab_de_Books=$b->FindByYear($year);// puis renvoyer vers le contrôleur (return) ou autre…}

Ou avec méthodes statiques quand c’est possible

35

Page 36: PHP Architectures avancées

Architecture DAL

ClasseConnection

ConnexionàlaBD

Méthodespdo_php de

bases

Composée du code en PDO

Rôle: préparer les requêtes, injecter les paramètres, exécuter la requête

=> Découpler l’accès bas niveau de la BD du reste du projet

Non rôle: ne traite pas les erreursPas d’affichage

!! Ne pas retourner d’objet statement (objet retourné par l’appel prepare)!! Ne pas faire de fetchall (ou autre) or de cette classeChacun son rôle

36

Page 37: PHP Architectures avancées

Architecture DAL

ClasseConnection

ConnexionàlaBD

Méthodespdo_php de

bases

Gestion des erreurs (PDOExeception)

Cas 1 : le plus simple

Pas de try catch dans la classe ConnectionLes erreurs sont automatiquement remontées dans le Contrôleur

C’est le rôle du Contrôleur de récupérer les erreurs, de les gérer et d’appeler la bonne vue qui affiche les erreurs

Dans contrôleur

Try{ $action=… switch($action)Catch (PDOException $e)

{$dataVueEreur[]=$e->getmessage()require ($vue[‘vue’]);

37

Page 38: PHP Architectures avancées

Architecture DAL

ClasseConnection

ConnexionàlaBD

Méthodespdo_php de

bases

Gestion des erreurs

Cas 2 :

Class Connection : pas de try …catch

Les classes *Gateway récupèrent les exceptions PDOretournent des exceptions non PDOCatch (PDOExecption $e) {throw new Exception (‘message’);

=> découpler PDO du reste=>le contrôleur n’est plus lié à PDO

ou ajoute des messages d’erreur dans tableau d’erreurtableau d’erreur = var globale 38

Page 39: PHP Architectures avancées

39

Page 40: PHP Architectures avancées

Des acteurs …

� Plusieursacteurspeuventêtreutilisateursd’uneapplicationWeb:

� Visiteur

� Utilisateur

� Administrateur� …. 40

Page 41: PHP Architectures avancées

Des acteurs� EnUML,exemple:

41

include

include

Page 42: PHP Architectures avancées

Des acteurs� EnUML,exemple:

ContrôleurUser

ContrôleurAdmin

2 actions

4 actions

+: on fait l’analyse, et on a l’architecture !C’est clair, propre, maintenable, pas 50 questions à se poser 42

include

include

Page 43: PHP Architectures avancées

Des acteurs� Commentlierlescontrôleurs

ContrôleurUser

ContrôleurAdmin

2 actions

4 actions

Solution 1 HéritageDans chaque Vue, on fait appel à l’un ou l’autre

+: solution simple

-: mais complexe à mettre en œuvre car chaque lien ou formulaire doit faire appel au bon contrôleur

On perd en souplesse

43

Page 44: PHP Architectures avancées

Des acteurs� Commentlierlescontrôleurs

ContrôleurUser

ContrôleurAdmin

Solution 2 Front contrôleur (a.k.a. dispatcheur)

Rôle: choisit le bon contrôleur suivant les droits et l’action demandée

-: ajout d’un contrôleur supplémentaire+: toujours le même, partout+: gère les droits

FrontContrôleur

44

Page 45: PHP Architectures avancées

Front controller� C’estunpatrond’architecture

� Wikipedia:

TheFrontControllerPattern isasoftwaredesignpatternlistedinseveralpatterncatalogs.

Thepatternrelatestothedesignofwebapplications.It"providesacentralizedentrypointforhandlingrequests."

45

Page 46: PHP Architectures avancées

Front controller (du cours)

46

Frontcontroller

Testactionsuivant role

ctrlUser

RécupèreactionSwithaction->appelméthodesuivant

l’action

ctrlAdmin

RécupèreactionSwithaction->appelméthodesuivant

l’action

appelle

appelle

Page 47: PHP Architectures avancées

Front controller

47

Frontcontroller

Testactionsuivantrole

EtSwith(action)

Appelméthodeducontrôleur

$ctrl=Newctrl()Ctrl->méthode()

ctrlUserPasdeconstructeuravecSwitch

méthodessuivantl’action

ctrlAdminPasdeconstructeuravecSwitch

méthodesuivantl’action

Dans les Frameworks: c’est un peu différent

Page 48: PHP Architectures avancées

Front controller

� Frontcontroller =classeappeléedansindex.php (newFrontController();)

� Repreneztouteslesvues� Chaquelienouactiondoitfaireappelàindex.php

� CodeprincipalduFrontcontroller danssonconstructeur

Page 49: PHP Architectures avancées

Front controller� Idéegénéraledefonctionnement

ContrôleurUser

ContrôleurAdmin

Initialisation(session,lib,autoloader,etc.)

1.Quelestlerôledelapersonneconnectée?(user,admin,etc.)LectureRôledansunesession

2.Quelleestl’action?

3.L’actionexiste-t-elle?A. Non->Vued’erreur

B. Oui,quelrôlefaut-ilpourcetteaction?C. Lerôleestbon->appelduboncontrôleurD. Lerôlen’estpasbon->envoiVuede

connection

4.Danstouslesautrescas->Vued’erreur

Vued’erreur

49

Page 50: PHP Architectures avancées

Front controllerQuelestlerôledelapersonneconnectée?(user,admin,etc.)Lecturedurôledansunesession

Exemple:� ClasseMdlAdmin

� Méthodeconnection()� Méthodedéconnexion()� MéthodeisAdmin()

Page 51: PHP Architectures avancées

Front controllerClasseMdlAdmin� Méthodeconnection($login,$mdp)

1. Nettoyage($login,$mdp2. AppelGatewaypourvérifiersi$login+$mdp danslaBD3. AjoutRôledanssession

$_SESSION[‘role’]=‘admin’;$_SESSION[‘login’]=$login;

� Onpeutsécuriserencryptantdonnéesdesession,etc.� http://php.net/manual/fr/session.security.php

� Méthodedéconnexion()� MéthodeisAdmin()

Page 52: PHP Architectures avancées

Front controller� ClasseMdlAdmin� Méthodedéconnexion()

session_unset();session_destroy();$_SESSION=array();

� MéthodeisAdmin(){ //testerôledanslasession,retourneinstanced’objetoubooleenifisset$_SESSION[‘login’]&&isset$_SESSION[‘role’]){

$login=Nettoyer::nettoyer_string($_SESSION[‘login’]);$role=Nettoyer::nettoyer_string($_SESSION[‘role’]);returnnewAdmin($login,$role)}

elsereturnnull;}

Page 53: PHP Architectures avancées

Front controller� Algorithmesimplifié(2acteursAdmin,User):

$listeAction_Admin =array(‘deconnecter’,’supprimer’,‘ajouter’);//appelmodèleadminpourvérifiersiutilisateurestconnectéTry{$admin=mdlAdmin.isAdmin();

Récupérationdel’actionSiactiondanslisteAction_Admin

si$admin=nullrequire PageAuthentification//ouappelctrlUser avecactionconnecter

sinonnewCtlrAdmin()

SinonnewCtrlUser()//onpeutaussivaliderl’actioniciaulieudelefairedansCtrlUser}Catch{require Page_Erreur}

53

Page 54: PHP Architectures avancées

Front controller� Algorithmesimplifié(2acteursAdmin,User):

Attention:toujourstestersi$admin==nullaudébutdeCtrAdminSinull->paged’erreur

appelduCtrlAdmindirectementdoitretournerunepaged’erreur!!!

54

Page 55: PHP Architectures avancées

Front controller� Autresfonctionnalitésdufrontcontroller:

� Vérificationdetouteslesactions

55

Page 56: PHP Architectures avancées

Front controller� Autresfonctionnalitésdufront(modeavancé)

URLrewritting,routing(Aulieud’utiliserdesparamètresGET/POSToudeformulaire):

� Actiondansl’URLex:…/user1/action1/param1/param2� frontcontrollerdécoupel’URLrécupèrel’actionetenvoieauContrôleurquidoitfairel’action

� ->routage!!!

� http://www.phpaddiction.com/tags/axial/url-routing-with-php-part-one/

� https://github.com/bencrowder/router

56

Page 57: PHP Architectures avancées

57

Page 58: PHP Architectures avancées

Architecture DAL, optimisation

ClasseConnection

ConnexionàlaBD

Méthodespdo_php de

bases

ObjetsMétiers

Classemodèle

ClasseGatewa

y

Fabrique(concrète

+Abstraite)

$résultats de requètes

58

Page 59: PHP Architectures avancées

Architecture DAL, optimisation

ObjetsMétiers

Fabrique(concrète)

Avantage:

Fabrique seule responsable de la création / distribution de l’objet,

Elle peut faire :préparer l’encodage (UTF8, …)Réaliser des opérations de logetc.

59

Page 60: PHP Architectures avancées

Architecture DAL, optimisation

ObjetsMétiers

Fabrique(concrète)

Exemple:

class DBFactory_Books{public static function create ($resultats, $param){

if ( ! Isset($resultats)){throw new Exception (‘Aucune donnée!');

}

switch ($param){case 'mysql':

mysqlBooks($resultats);break;

case ‘xml':XMLBooks($resultats);

break;default:

throw new Exception ('Type de base inconnu');}

} 60

Page 61: PHP Architectures avancées

Architecture DAL, optimisationObjetsMétiers

Fabrique(concrète)

Exemple:

mysqlBooks($resultats) {

$Tab_Books=array(); $i=0;

Foreach ($results as $row)$Tab_de_Books[]=new

Book($row[‘isbn’], $row[‘titre’], $row[‘year’]);

Return $Tab_Books;

61

Page 62: PHP Architectures avancées

Moteur de template : séparer code HTML et PHP

Pourquoi ? Souvent 2 métiers (postes)

Resp: S. SALVA IUT 2ème année GI IUT d’aubiere

HTML PHPMoteurtemplate

variablesVariablesboucles

Soit à la main (PHP est un moteur de template à la base)

Soit outilsExemple Moteur : twig (https://twig.symfony.com/)

Séparation HTML PHP

62

Page 63: PHP Architectures avancées

Exemples:

HTML PHPMoteurtemplate

variablesVariablesboucles <?php

require_once __DIR__ . '/vendor/autoload.php'; $loader = new Twig_Loader_Filesystem('templates'); // Dossier contenant les templates$twig = new Twig_Environment($loader, array( 'cache' => false ));

echo $twig->render('index.html', array( ‘name' => ’Salva’ ,‘users’=> array(‘1’=> array(‘username’=>’toto’),‘2’=> array(‘username’=>’sasa’)));

Template Index.html<html><body><strong>{{ name }}</strong> <br />

{% if users|length > 0 %} <ul> {% for user in users %}

<li>{{ user.username }}</li> {% endfor %} </ul>{% endif %}

</body></html>

Séparation HTML PHP

63

Page 64: PHP Architectures avancées

Architecture DAL, optimisation

Classemodèle

PasdeSQL!

Faire une DAL au moins une fois pour comprendre c’est bienMais à chaque fois, c’est lourd !

ORM(object relational mapping)

Doctrine,propel

On donne la couche métier, relations entre classes et tables et c’est tout (gen. de code)

64

Page 65: PHP Architectures avancées

Architecture DAL, optimisation

Tutoriel : https://www.doctrine-project.org/projects/doctrine-orm/en/2.8/tutorials/getting-started.htmlRésumé dans la suite:

65

Page 66: PHP Architectures avancées

Architecture DAL, optimisation

Installation avec Composer https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/tutorials/getting-started.html

Configuration de EntityManager:Classe qui donne accès à l’ORM, entités (classes métiers), persistance.

66

Page 67: PHP Architectures avancées

Architecture DAL, optimisationCréation d’entité avec annotations dans le code (ou fichier XML)<?php// src/Product.php

use Doctrine\ORM\Mapping as ORM;

/*** @ORM\Entity* @ORM\Table(name="products")*/

class Product{

/** * @ORM\Id* @ORM\Column(type="integer")* @ORM\GeneratedValue*/

protected $id;67

/** * @ORM\Column(type="string")*/

protected $name;

// .. (other code)

}

Pour créer des relations entre objets/tables@ORM\OneToMany(targetEntity= »XXX",

mappedBy= »YYY") @ORM\ManyToMany(targetEntity= »XXX",

mappedBy= »YYY")

Page 68: PHP Architectures avancées

Architecture DAL, optimisationCréarion de la BD associée

Taper en ligne de commande:vendor/bin/doctrine orm:schema-tool:create

Ou

vendor/bin/doctrine orm:schema-tool:update --force --dump-sqlPour mettre à jour

68

Page 69: PHP Architectures avancées

Architecture DAL, optimisation

Voilà c’est fini !

Insertion en BD (avec Mdl)

$product = new Product();$product->setName(‘toto’);

$entityManager->persist($product);$entityManager->flush();

Supression$entityManager->remove($product);$entityManager-> flush();

69

Page 70: PHP Architectures avancées

Architecture DAL, optimisation

Lecture en BD (tous les objets)

$productRepository = $entityManager->getRepository('Product');$products = $productRepository->findAll();

foreach ($products as $product) {echo sprintf("-%s\n", $product->getName());

}

70

Page 71: PHP Architectures avancées

Architecture DAL, optimisation

Lecture en BD (par id) puis modification$id = $argv[1];$newName = $argv[2];

$product = $entityManager->find('Product', $id);if ($product === null) {

echo "Product $id does not exist.\n";exit(1);

}$product->setName($newName);$entityManager->flush();

71

Page 72: PHP Architectures avancées

Architecture DAL, optimisation

Lecture en BD avec condition simple (https://www.doctrine-project.org/projects/doctrine-orm/en/2.8/reference/working-with-objects.html)

// All users that are 20 years old$users = $em->getRepository('MyProject\Domain\User')->findBy(array('age' => 20));

// All users that are 20 years old and have a surname of 'Miller'$users = $em->getRepository('MyProject\Domain\User')->findBy(array('age' => 20, 'surname' => 'Miller'));

// A single user by its nickname$user = $em->getRepository('MyProject\Domain\User')->findOneBy(array('nickname' => 'romanb')); 72

Page 73: PHP Architectures avancées

Architecture DAL, optimisation

Requètes complexes (en DQL, req sur instance d’objet)

$dql = "SELECT b, e, r, p FROM Bug b JOIN b.engineer e "."JOIN b.reporter r JOIN b.products p ORDER BY b.created DESC";

$query = $entityManager->createQuery($dql);$bugs = $query->getArrayResult();

73

Page 74: PHP Architectures avancées

Frameworks

Simples:

code igniter (https://ellislab.com/codeigniter), Yii (http://www.yiiframework.com/)

Plus complexes:

zend -> Laminas Project (https://getlaminas.org/)symfony (https://symfony.com/)

Ces frameworks intègrent des ORM soit maison soit doctrine, propelEx: symfony utilise twig et doctrine

74

Page 75: PHP Architectures avancées

Oubliez les ORM, les bases de données ???????

Services Web (Rest)instances d’objets sur serveurs Web, génériques, utilisables sur Web, Mobile, desktop !framework slim, Springboot, micronaut

Marre du SQL ?Faites du NoSQL

dépôt ou l’on met de tout comme on veutMongoDb, ElasticSearch

Marre de l’hébergement (d’ailleurs c’est quoi ?)Faites du Cloud, des VMs, Heroku, Google App Engine, AWS, etc. etc.

Resp: S. SALVA IUT 2ème année GI IUT d’aubiere 75

Page 76: PHP Architectures avancées

Le vaste Monde du JS (Javascript), qui bouge tous les 6 mois

Tout est mis à la sauce JS ! (windows, mobile, jeux)

Jquery (à connaitre, de base)

WinJs pour Windows 8, 10

createJs,phaser ->jeux en JS

BabylonJS->(opengl (webgl) ) dans navigateur, façon easy

Aframe -> VR, webXR

NodeJs (application réseaux serveur en asynchrone) http://nodejs.org/envie de faire son serveur Web plus rapide qu’Apache ?

76

Page 77: PHP Architectures avancées

Angular, Reactfaire du MVVM (adieu MVC?)

•La vue est couplée aux données via du DataBinding et invoque les méthodes du ViewModel.

•Le ViewModel invoque les méthodes du modèle. Il contient la data spécifique à la gestion de l’écran et les méthodes de réponses aux interactions utilisateurs. Il contient également une référence vers un ou des modèles.

•Le modèle contient la data et les méthodes de manipulation de cette dernière (calculs, appels de services, …).

Resp: S. SALVA IUT 2ème année GI IUT d’aubiere 77

Page 78: PHP Architectures avancées

Faire des tests !

Test unitaires (de classes): phpunit

Test d’intégration: selenium, CasperJs

78

Page 79: PHP Architectures avancées

Pattern Observer avec classes anonymes et SplObserver

Pattern CommandBus

But: séparer les aspects techniques lourds des contrôleurs Ex: acheter un podcast -> demander login, utiliser carte de crédit, assigner podcast, etc.

Objet Command = classe métier contenant les données provenant d’une requète, puis exécuter par un Objet Commandhandler(découplage)

Intégré dans les frameworks laravel, symfony, etc.

Ex:http://php-and-symfony.matthiasnoback.nl/2015/01/a-wave-of-command-buses/

Implémentation: simpleBus: https://github.com/SimpleBus

Resp: S. SALVA IUT 2ème année GI IUT d’aubiere

D’autres patterns

79