SlideShare une entreprise Scribd logo
1  sur  34
Télécharger pour lire hors ligne
DE LEGACY À SYMFONY
PHP QUÉBEC
3 MARS 2016
Etienne Lachance
@elachance
QUI SUIS-JE
Sys admin de formation
Programmeur depuis ~10 ans
Propriétaire de elcweb.ca
Consultation en entreprise
Programmation
Hébergement spécialisé
Fin de l'auto promotion
CONTEXT
Evolution d'un projet "Legacy" sans affecter la productivité mais en
introduisant les bonne pratique d’un nouveau framework.
PAR LEGACY J'ENTEND
peu/pas de documentation
peu/pas de tests
Code procédural
Code spaghetti
Duplication de code (copier-coller)
Include-ception
Couplage de responsabilité
... Non SOLID
OBJECTIF
Permet de refactoriser le code petit peu par petit peu mais d'avoir des
avantages rapidement.
ATTENTION!
IL EST FORTEMENT RECOMMANDÉ D’ÉCRIRE DES TESTS
AUTOMATISÉS.
PHPUnit
Behat
3 MÉTHODOLOGIES
1. PARALLEL
simple a implémenter (mod_rewrite)
aucune communication direct entre les 2 applications
utilisation de la BD ou Redis pour l'échange entre les 2 apps
peu/pas d'impacte sur l'application 1
2. PROXY
l'utilisateur voie uniquement une application (Symfony)
necessite plus de travail pour la mise en place
"wrapper" pour les requêtes a l'application Legacy
authentification
sécurité entre les 2 applications
peu/pas d'impacte sur l'application Legacy
3. INTÉGRATION
On veut changer la structure fondamental du code actuel.
une seule application
OPTION PRÉSENTÉ
QU'EST-CE QUE SYMFONY?
Symfony est *
une collection de composante
un framework applicatif
une philosophy
une communauté
Symfony est a la base un framework HTTP
GESTION DES REQUÊTE / RÉPONSE
source: http://symfony.com/what-is-symfony
EXEMPLE
STRUCTURE DE FICHIER
BONNE PRATIQUE: PLACER LE CODE A L'EXTERIEUR DU RÉPERTOIRE PUBLIQUE.
STRUCTURE RÉVISÉ
MODIFIONS LE CODE
EXEMPLE DE TYPE "INCLUDE-CEPTION"
<?php
// index.php
include("includes/common.php");
include("includes/config.php");
$mod = $_GET['mod'];
if ($mod=="" || !preg_match('/^[A-Za-z1-90_]+$/Ui',$mod))
$mod = "dashboard";
include ("modules/".$mod.".php");
aucun namespace
logique basé sur include() / require()
LEGACY CONTROLLER
namespace AppBundleController;
use ...;
class LegacyController extends Controller
{
/** @Route("/index.php") */
public function legacyAction()
{
// __DIR__ == 'src/AppBundle/Controller'
include __DIR__ . '/../includes/common.php';
include __DIR__ . '/../includes/config.php';
// @todo: renommé $mod pour $module
$mod = $_GET['mod'];
if ($mod=="" || !preg_match('/^[A-Za-z1-90_]+$/Ui', $mod)) {
$mod = "dashboard";
}
RÉCAPITULATION
déplacer les fichiers a l'extérieur du répertoire publique
vérifier si le module exist
si le module n'existe pas, retourne une erreur 404
encapsuler les "echo" du code legacy dans un objet Response
PROCHAINE ÉTAPES
Authentification/Autorisation (incluant la session)
Isolation de la base de donnée (Repository)
Vue (Templates)
AUTHENTIFICATION/AUTORISATION
AUTHENTIFICATION
Qui es-tu ?
AUTORISATION
Quels sont les accès / droits
MAINTENANT DANS SYMFONY
UTILISATEUR
Implement UserInterface
<?php
namespace AppBundleSecurityUser;
use ...
class User implements UserInterface
{
private $username;
private $password;
private $salt
prirate $roles;
...
}
PROVIDER
Est responsable d'aller chercher l'utilisateur
Implement UserProviderInterface
<?php
namespace AppBundleSecurityUser;
use ...
class UserProvider implements UserProviderInterface
{
public function loadUserByUsername($username)
{
// aller chercher l'utilisateur
// dans la base de donnée, le webservice, ...
$userData = ...
// pretend it returns an array on success, false if there is no user
if ($userData) {
$password = '...';
ENCODER
Responsable d'encoder et de valider un mot de passe
<?php
namespace AppBundleSecurityEncoder;
use SymfonyComponentSecurityCoreEncoderBasePasswordEncoder;
class LegacyMd5Encoder extends BasePasswordEncoder
{
public function isPasswordValid($encoded, $raw, $salt = null) :bool
{
return $this->comparePasswords(strtolower($encoded), strtolower($this->encodePassword($raw, $
}
/**
* @param string $raw
* @param null|string $salt
*
* @return string
CONFIGURATION
app/config/services.yml
services:
app.user_provider:
class: AppBundleSecurityUserUserProvider
app.security.encoder.md5:
class: AppBundleSecurityEncoderLegacyMd5Encoder
app/config/security.yml
security:
encoders:
AppBundleSecurityUserUser:
id: app.security.encoder.md5
providers:
legacy:
id: app.user_provider
firewall:
main:
pattern: ^/
http_basic: ~
RECOMMANDATION
Utilisation d'un algorithme plus sécuritaire comme bcrypt ou sha512
Convertion des mots de passes "on the fly"
DOCTRINE
Permet de représenter en Objet et non en Base de donnée relationnel.
DOCTRINE / REPOSITORY
Dans le contexte de Doctrine, un Repository est utilisé pour allez chercher
l'information
Centraliser les requêtes SQL
Isoler les requêtes du "controlleur"
Classifier par context d'objet (Utilisateur/Produit/Client)
LEGACY
<?php
// ...
$conn = mysql_connect($db_host, $db_user, $db_password);
if (!$conn) {
echo "Unable to connect to DB: " . mysql_error();
exit;
}
if (!mysql_select_db($dbname)) {
echo "Unable to select mydbname: " . mysql_error();
exit;
}
$sql = "SELECT * FROM products WHERE category = ".mysql_real_escape_string($_GET['cat']).";"
$result = mysql_query($sql);
GÉNÉRATION D'ENTITÉ A PARTIR D'UNE BASE DE DONNÉ
EXISTANTE
$ php bin/console doctrine:mapping:import --force AcmeBlogBundle xml
$ php bin/console doctrine:mapping:convert annotation ./src
$ php bin/console doctrine:generate:entities AcmeBlogBundle
http://symfony.com/doc/current/cookbook/doctrine/reverse_engineering.html
REPOSITORY
namespace AppBundleEntity;
use DoctrineORMEntityRepository;
class ProductRepository extends EntityRepository
{
public function findByCategory($categoryId)
{
$sql = "SELECT * FROM products WHERE category = ".mysql_real_escape_string($categoryId
$stmt = $this->getEntityManager()->getConnection()->prepare($sql);
$stmt->execute();
return $stmt->findAll();
}
}
RawSQLTrait: https://gist.github.com/estheban/3eae41271f6cf5f3180a
UTILISATION DANS UN CONTROLLEUR
class ProductController extends Controller
{
/**
* @Route("/product.php/category/{id}")
*/
public function productByCategory(Category $category)
{
// throw 404 si pas de Catégorie trouvée
$entityManager = $this->getDoctrine()->getManager();
return $entityManager
->getRepository("AppBundle:Product")
->findByCategory($category->getId());
}
}
QUESTIONS ?
MERCI!
http://elcweb.ca
http://etiennelachance.com
@elachance
https://github.com/estheban

Contenu connexe

Tendances

Docker Tours Meetup #1 - Introduction à Docker
Docker Tours Meetup #1 - Introduction à DockerDocker Tours Meetup #1 - Introduction à Docker
Docker Tours Meetup #1 - Introduction à DockerThibaut Marmin
 
Deep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKDeep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKJosé Paumard
 
Introduction to Docker - VIT Campus
Introduction to Docker - VIT CampusIntroduction to Docker - VIT Campus
Introduction to Docker - VIT CampusAjeet Singh Raina
 
Clean architecture
Clean architectureClean architecture
Clean architectureLieven Doclo
 
Clean architecture
Clean architectureClean architecture
Clean architecture.NET Crowd
 
Clean Architecture
Clean ArchitectureClean Architecture
Clean ArchitectureFlavius Stef
 
Architecture java j2 ee a partager
Architecture java j2 ee a partagerArchitecture java j2 ee a partager
Architecture java j2 ee a partageraliagadir
 
Hexagonal architecture - message-oriented software design
Hexagonal architecture  - message-oriented software designHexagonal architecture  - message-oriented software design
Hexagonal architecture - message-oriented software designMatthias Noback
 
CI/CD 101
CI/CD 101CI/CD 101
CI/CD 101djdule
 
The 16th Intl. Workshop on Search-Based and Fuzz Testing
The 16th Intl. Workshop on Search-Based and Fuzz TestingThe 16th Intl. Workshop on Search-Based and Fuzz Testing
The 16th Intl. Workshop on Search-Based and Fuzz TestingSebastiano Panichella
 
How to write a Dockerfile
How to write a DockerfileHow to write a Dockerfile
How to write a DockerfileKnoldus Inc.
 
React-JS Component Life-cycle Methods
React-JS Component Life-cycle MethodsReact-JS Component Life-cycle Methods
React-JS Component Life-cycle MethodsANKUSH CHAVAN
 
The Proxy Fairy, and The Magic of Spring Framework
The Proxy Fairy, and The Magic of Spring FrameworkThe Proxy Fairy, and The Magic of Spring Framework
The Proxy Fairy, and The Magic of Spring FrameworkVictor Rentea
 

Tendances (20)

Docker Tours Meetup #1 - Introduction à Docker
Docker Tours Meetup #1 - Introduction à DockerDocker Tours Meetup #1 - Introduction à Docker
Docker Tours Meetup #1 - Introduction à Docker
 
Deep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKDeep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UK
 
Maven
MavenMaven
Maven
 
Introduction to Docker - VIT Campus
Introduction to Docker - VIT CampusIntroduction to Docker - VIT Campus
Introduction to Docker - VIT Campus
 
Curso gratuito de Docker
Curso gratuito de DockerCurso gratuito de Docker
Curso gratuito de Docker
 
Clean architecture
Clean architectureClean architecture
Clean architecture
 
Clean architecture
Clean architectureClean architecture
Clean architecture
 
Les collections en Java
Les collections en JavaLes collections en Java
Les collections en Java
 
Introduction to React JS
Introduction to React JSIntroduction to React JS
Introduction to React JS
 
React Hooks
React HooksReact Hooks
React Hooks
 
Clean Architecture
Clean ArchitectureClean Architecture
Clean Architecture
 
Architecture java j2 ee a partager
Architecture java j2 ee a partagerArchitecture java j2 ee a partager
Architecture java j2 ee a partager
 
Hexagonal architecture - message-oriented software design
Hexagonal architecture  - message-oriented software designHexagonal architecture  - message-oriented software design
Hexagonal architecture - message-oriented software design
 
CI/CD 101
CI/CD 101CI/CD 101
CI/CD 101
 
The 16th Intl. Workshop on Search-Based and Fuzz Testing
The 16th Intl. Workshop on Search-Based and Fuzz TestingThe 16th Intl. Workshop on Search-Based and Fuzz Testing
The 16th Intl. Workshop on Search-Based and Fuzz Testing
 
TypeScript
TypeScriptTypeScript
TypeScript
 
How to write a Dockerfile
How to write a DockerfileHow to write a Dockerfile
How to write a Dockerfile
 
Docker
DockerDocker
Docker
 
React-JS Component Life-cycle Methods
React-JS Component Life-cycle MethodsReact-JS Component Life-cycle Methods
React-JS Component Life-cycle Methods
 
The Proxy Fairy, and The Magic of Spring Framework
The Proxy Fairy, and The Magic of Spring FrameworkThe Proxy Fairy, and The Magic of Spring Framework
The Proxy Fairy, and The Magic of Spring Framework
 

Similaire à De Legacy à Symfony

Qualité logicielle
Qualité logicielleQualité logicielle
Qualité logiciellecyrilgandon
 
ALT.Net Juin 2012 - Specflow
ALT.Net Juin 2012 - SpecflowALT.Net Juin 2012 - Specflow
ALT.Net Juin 2012 - SpecflowMathias Kluba
 
Machine learning pour tous
Machine learning pour tousMachine learning pour tous
Machine learning pour tousDamien Seguy
 
Spring Boot & Containers - Do's & Don'ts
Spring Boot & Containers - Do's & Don'tsSpring Boot & Containers - Do's & Don'ts
Spring Boot & Containers - Do's & Don'tsJulien Wittouck
 
Soutenance Zend Framework vs Symfony
Soutenance Zend Framework vs SymfonySoutenance Zend Framework vs Symfony
Soutenance Zend Framework vs SymfonyVincent Composieux
 
Epitech securite-2012.key
Epitech securite-2012.keyEpitech securite-2012.key
Epitech securite-2012.keyDamien Seguy
 
Uni.sherbrooke 2015 créez la meilleur application grâce à gwt, gwtp et j...
Uni.sherbrooke 2015   créez la meilleur application grâce à gwt, gwtp et j...Uni.sherbrooke 2015   créez la meilleur application grâce à gwt, gwtp et j...
Uni.sherbrooke 2015 créez la meilleur application grâce à gwt, gwtp et j...Arcbees
 
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniterAtsé François-Xavier KOBON
 
20090615 - Ch'ti JUG - Apache Maven
20090615 - Ch'ti JUG - Apache Maven20090615 - Ch'ti JUG - Apache Maven
20090615 - Ch'ti JUG - Apache MavenArnaud Héritier
 
PHP #4 : sessions & cookies
PHP #4 : sessions & cookiesPHP #4 : sessions & cookies
PHP #4 : sessions & cookiesJean Michel
 
RefCard Tests sur tous les fronts
RefCard Tests sur tous les frontsRefCard Tests sur tous les fronts
RefCard Tests sur tous les frontsOCTO Technology
 
Build automatique et distribution OTA avec Xcode 4.x et Jenkins
Build automatique et distribution OTA avec Xcode 4.x et JenkinsBuild automatique et distribution OTA avec Xcode 4.x et Jenkins
Build automatique et distribution OTA avec Xcode 4.x et JenkinsCocoaHeads France
 
20081113 - Nantes Jug - Apache Maven
20081113 - Nantes Jug - Apache Maven20081113 - Nantes Jug - Apache Maven
20081113 - Nantes Jug - Apache MavenArnaud Héritier
 
AFUP Aix/Marseille - 16 mai 2017 - Open API
AFUP Aix/Marseille - 16 mai 2017 - Open APIAFUP Aix/Marseille - 16 mai 2017 - Open API
AFUP Aix/Marseille - 16 mai 2017 - Open APIRomain Cambien
 
Common features in webapi aspnetcore
Common features in webapi aspnetcoreCommon features in webapi aspnetcore
Common features in webapi aspnetcoreMSDEVMTL
 
Formation PHP avancé - Cake PHP
Formation PHP avancé - Cake PHPFormation PHP avancé - Cake PHP
Formation PHP avancé - Cake PHPkemenaran
 

Similaire à De Legacy à Symfony (20)

De legacy à symfony
De legacy à symfonyDe legacy à symfony
De legacy à symfony
 
Qualité logicielle
Qualité logicielleQualité logicielle
Qualité logicielle
 
ALT.Net Juin 2012 - Specflow
ALT.Net Juin 2012 - SpecflowALT.Net Juin 2012 - Specflow
ALT.Net Juin 2012 - Specflow
 
Machine learning pour tous
Machine learning pour tousMachine learning pour tous
Machine learning pour tous
 
Spring Boot & Containers - Do's & Don'ts
Spring Boot & Containers - Do's & Don'tsSpring Boot & Containers - Do's & Don'ts
Spring Boot & Containers - Do's & Don'ts
 
Soutenance Zend Framework vs Symfony
Soutenance Zend Framework vs SymfonySoutenance Zend Framework vs Symfony
Soutenance Zend Framework vs Symfony
 
Epitech securite-2012.key
Epitech securite-2012.keyEpitech securite-2012.key
Epitech securite-2012.key
 
Uni.sherbrooke 2015 créez la meilleur application grâce à gwt, gwtp et j...
Uni.sherbrooke 2015   créez la meilleur application grâce à gwt, gwtp et j...Uni.sherbrooke 2015   créez la meilleur application grâce à gwt, gwtp et j...
Uni.sherbrooke 2015 créez la meilleur application grâce à gwt, gwtp et j...
 
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
 
Etude des Frameworks PHP
Etude des Frameworks PHPEtude des Frameworks PHP
Etude des Frameworks PHP
 
20090615 - Ch'ti JUG - Apache Maven
20090615 - Ch'ti JUG - Apache Maven20090615 - Ch'ti JUG - Apache Maven
20090615 - Ch'ti JUG - Apache Maven
 
PHP #4 : sessions & cookies
PHP #4 : sessions & cookiesPHP #4 : sessions & cookies
PHP #4 : sessions & cookies
 
RefCard Tests sur tous les fronts
RefCard Tests sur tous les frontsRefCard Tests sur tous les fronts
RefCard Tests sur tous les fronts
 
Build automatique et distribution OTA avec Xcode 4.x et Jenkins
Build automatique et distribution OTA avec Xcode 4.x et JenkinsBuild automatique et distribution OTA avec Xcode 4.x et Jenkins
Build automatique et distribution OTA avec Xcode 4.x et Jenkins
 
20081113 - Nantes Jug - Apache Maven
20081113 - Nantes Jug - Apache Maven20081113 - Nantes Jug - Apache Maven
20081113 - Nantes Jug - Apache Maven
 
AFUP Aix/Marseille - 16 mai 2017 - Open API
AFUP Aix/Marseille - 16 mai 2017 - Open APIAFUP Aix/Marseille - 16 mai 2017 - Open API
AFUP Aix/Marseille - 16 mai 2017 - Open API
 
Common features in webapi aspnetcore
Common features in webapi aspnetcoreCommon features in webapi aspnetcore
Common features in webapi aspnetcore
 
Retour d'expérience sur PowerShell
Retour d'expérience sur PowerShellRetour d'expérience sur PowerShell
Retour d'expérience sur PowerShell
 
Intégration Continue et PHP
Intégration Continue et PHPIntégration Continue et PHP
Intégration Continue et PHP
 
Formation PHP avancé - Cake PHP
Formation PHP avancé - Cake PHPFormation PHP avancé - Cake PHP
Formation PHP avancé - Cake PHP
 

De Legacy à Symfony