SlideShare une entreprise Scribd logo
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

presentation on Docker
presentation on Dockerpresentation on Docker
presentation on Docker
Virendra Ruhela
 
Cloud-native Application Development on OCI
Cloud-native Application Development on OCICloud-native Application Development on OCI
Cloud-native Application Development on OCI
Sven Bernhardt
 
Mutiny + quarkus
Mutiny + quarkusMutiny + quarkus
Mutiny + quarkus
Edgar Domingues
 
Ceph with CloudStack
Ceph with CloudStackCeph with CloudStack
Ceph with CloudStack
ShapeBlue
 
DevOps and the Case for ROI to Executives
DevOps and the Case for ROI to ExecutivesDevOps and the Case for ROI to Executives
DevOps and the Case for ROI to Executives
IBM UrbanCode Products
 
CodeIgniter For Project : Workshop 001 - Install Docker and CodeIgniter
CodeIgniter For Project : Workshop 001 - Install Docker and CodeIgniterCodeIgniter For Project : Workshop 001 - Install Docker and CodeIgniter
CodeIgniter For Project : Workshop 001 - Install Docker and CodeIgniter
Weerayut Hongsa
 
Why to Cloud Native
Why to Cloud NativeWhy to Cloud Native
Why to Cloud Native
Karthik Gaekwad
 

Tendances (7)

presentation on Docker
presentation on Dockerpresentation on Docker
presentation on Docker
 
Cloud-native Application Development on OCI
Cloud-native Application Development on OCICloud-native Application Development on OCI
Cloud-native Application Development on OCI
 
Mutiny + quarkus
Mutiny + quarkusMutiny + quarkus
Mutiny + quarkus
 
Ceph with CloudStack
Ceph with CloudStackCeph with CloudStack
Ceph with CloudStack
 
DevOps and the Case for ROI to Executives
DevOps and the Case for ROI to ExecutivesDevOps and the Case for ROI to Executives
DevOps and the Case for ROI to Executives
 
CodeIgniter For Project : Workshop 001 - Install Docker and CodeIgniter
CodeIgniter For Project : Workshop 001 - Install Docker and CodeIgniterCodeIgniter For Project : Workshop 001 - Install Docker and CodeIgniter
CodeIgniter For Project : Workshop 001 - Install Docker and CodeIgniter
 
Why to Cloud Native
Why to Cloud NativeWhy to Cloud Native
Why to Cloud Native
 

Similaire à De Legacy à Symfony

De legacy à symfony
De legacy à symfonyDe legacy à symfony
De legacy à symfony
Etienne Lachance
 
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 tous
Damien 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'ts
Julien 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.key
Damien 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 CodeIgniter
Atsé François-Xavier KOBON
 
Etude des Frameworks PHP
Etude des Frameworks PHPEtude des Frameworks PHP
Etude des Frameworks PHP
JEAN-GUILLAUME DUJARDIN
 
20090615 - Ch'ti JUG - Apache Maven
20090615 - Ch'ti JUG - Apache Maven20090615 - Ch'ti JUG - Apache Maven
20090615 - Ch'ti JUG - Apache Maven
Arnaud Héritier
 
PHP #4 : sessions & cookies
PHP #4 : sessions & cookiesPHP #4 : sessions & cookies
PHP #4 : sessions & cookies
Jean Michel
 
RefCard Tests sur tous les fronts
RefCard Tests sur tous les frontsRefCard Tests sur tous les fronts
RefCard Tests sur tous les fronts
OCTO 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 Jenkins
CocoaHeads France
 
20081113 - Nantes Jug - Apache Maven
20081113 - Nantes Jug - Apache Maven20081113 - Nantes Jug - Apache Maven
20081113 - Nantes Jug - Apache Maven
Arnaud 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 API
Romain Cambien
 
Common features in webapi aspnetcore
Common features in webapi aspnetcoreCommon features in webapi aspnetcore
Common features in webapi aspnetcore
MSDEVMTL
 
Retour d'expérience sur PowerShell
Retour d'expérience sur PowerShellRetour d'expérience sur PowerShell
Retour d'expérience sur PowerShell
Microsoft Technet France
 
Intégration Continue et PHP
Intégration Continue et PHPIntégration Continue et PHP
Intégration Continue et PHP
Oswald De Riemaecker ☁
 
Formation PHP avancé - Cake PHP
Formation PHP avancé - Cake PHPFormation PHP avancé - Cake PHP
Formation PHP avancé - Cake PHP
kemenaran
 

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