how to work with legacy code phpers rzeszow #2
TRANSCRIPT
![Page 1: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/1.jpg)
HOW TO WORK WITHLEGACY CODE
PHPERS RZESZÓW #2
![Page 2: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/2.jpg)
MICHAŁ SZCZURPHP Developer since 2010
bass guitarist and trumpeter
michalszczur.plCreated by / Michał Szczur @partikus
![Page 3: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/3.jpg)
AGENDAWhat is legacy codeWhen code can be called Legacy?How to start and not dieStep by step to heaven
![Page 4: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/4.jpg)
WHAT IS LEGACY CODE?
![Page 5: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/5.jpg)
CODE WRITTEN MANY YEARS AGOBY MYSELF OR OTHER NINJAS
![Page 6: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/6.jpg)
LOW QUALITY CODE
![Page 7: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/7.jpg)
(PRE)HISTORICAL CODE USES NONEXISTINGFRAMEWORKS/LIBRARIES
![Page 8: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/8.jpg)
NO ENVIRONMENT SEPARATION
![Page 9: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/9.jpg)
NO TESTS !!!
![Page 10: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/10.jpg)
WHEN CODE CAN BE CALLED
LEGACY ???
![Page 11: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/11.jpg)
WHEN IT IS
UNMANAGED
![Page 12: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/12.jpg)
WHEN IT IS
TOO BUGGY
![Page 13: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/13.jpg)
WHEN IT IS
TOO HARD TO UNDERSTAND
![Page 14: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/14.jpg)
WHEN IT IS
NONUPGRADABLE
![Page 15: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/15.jpg)
WHEN IT IS
UNDEBUGGABLE
![Page 16: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/16.jpg)
WHEN IT IS
UNREADABLE
![Page 17: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/17.jpg)
WHEN IT IS
TOO COUPLED TO FRAMEWORK
![Page 18: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/18.jpg)
WHEN IT IS
TOO HARD TO ADD NEW FEATURE
![Page 19: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/19.jpg)
WHAT IS NEXT?
![Page 20: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/20.jpg)
FIGHT OR DIE
![Page 21: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/21.jpg)
NO !!!WE'RE NINJA DEVS
WE LOVE CHALLENGES
![Page 22: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/22.jpg)
LET'S DO IT!
![Page 23: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/23.jpg)
TAKE NEW FRAMEWORK AND START FROM THE BEGINNING
![Page 24: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/24.jpg)
:(MAYBE SOME DAY IN THE FUTURE
![Page 25: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/25.jpg)
WHAT IS NEXT?
![Page 26: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/26.jpg)
LET'S REFACTOR
![Page 27: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/27.jpg)
BUT WHY ???
![Page 28: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/28.jpg)
EXTENDED LEGACYCODE
WEB PHP APP
![Page 29: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/29.jpg)
ASSUMPTIONSYOU DON'T KNOW BUSINESS LOGIC
MOSTLY PROCEDURAL CODE
NO SEPARATION, JUST A FEW LARGE FILES
YOU NEED TO CHANGE STH
![Page 30: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/30.jpg)
HOW TO START?
![Page 31: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/31.jpg)
ANALYZE
![Page 32: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/32.jpg)
COVERIT MEANS WRITE TESTS
![Page 33: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/33.jpg)
WHAT SHOULD WETEST?
![Page 34: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/34.jpg)
![Page 35: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/35.jpg)
![Page 36: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/36.jpg)
WHY SHOULD WE WRITE TESTS?
![Page 37: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/37.jpg)
LOW LEVEL DOCUMENTATIONFEATURES DESCRIBED BY SCENARIOS (E.G.
GHERKIN)CLEAN CODE
EASY TO CHANGE (LESS PAIN)EASY CONTINUOUS DEPLOYMENT
![Page 38: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/38.jpg)
START REFACTORING
![Page 39: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/39.jpg)
# Project structure /404.php /database.php /functions.php /index.php /page.php
![Page 40: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/40.jpg)
PROCEDURAL CODEWRITTEN IN PHP
INLINE PHP FUNCTIONS MIXED WITH HTML,CSS,JS
![Page 41: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/41.jpg)
#/functions.php function show_all() { $db = connect_to_db(); $sql = 'SELECT * FROM receivers'; $result = mysql_query($sql) or die(mysql_error()); while ($row = mysql_fetch_array($result)) { //echo 'ID: ' . $row['id'] . ', mail: ' . $row['mail']; echo ''.$row['mail'].''; echo '<form id="'.$row['id'].'" name="n_ID" method="POST" action=<input type="hidden" name="id" value="'.$row['id'].'" /> <input type="submit" name="delete" value="Delete" /> </form>'; } if (isset($_POST['delete'])) { $n_ID = $_POST['id']; $sql = "DELETE FROM receivers WHERE id = $n_ID"; mysql_query($sql) or die(mysql_error());
![Page 42: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/42.jpg)
WRITE FUNCTIONALTEST
![Page 43: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/43.jpg)
// show_all_receivers.jscasper.test.begin('List all receivers', 5, function suite(test) { casper.start("http://myapp.dev/mailsender.php", function() { test.assertHttpStatus(200); test.assertTitle("Homepage | Mail Sender", "Homepage title is expected" }); casper.thenClick('a#show-all', function() { test.assertHttpStatus(200); test.assertTitle( "Receivers list | Mail Sender", "Page title is correct" ); }); casper.run(function() { test.done(); }); });
![Page 44: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/44.jpg)
PROCEDURAL CODE??
YOU NEED STH MORE
![Page 45: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/45.jpg)
IOCINVERSION OF CONTROL
![Page 46: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/46.jpg)
DEPENDENCYINJECTION
IOC IMPLEMENTATION
![Page 47: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/47.jpg)
DON'T REINVENT THEWHEEL
![Page 48: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/48.jpg)
PACKAGE MANAGERCOMPOSER
RUBYGEMS
MAVEN
![Page 49: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/49.jpg)
COMPONENTSDEPENDENCY INJECTION
/ / SYMFONY DI PIMPLE AURA DI
![Page 50: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/50.jpg)
WHY SYMFONYCOMPONENTS?
![Page 51: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/51.jpg)
WELL TESTED
![Page 52: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/52.jpg)
DECOUPLED
![Page 53: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/53.jpg)
REUSABLE
![Page 54: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/54.jpg)
WELL DOCUMENTEDAND KNOWN BY COMMUNITY
![Page 55: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/55.jpg)
NEXT STEP IS...
![Page 56: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/56.jpg)
MOVE APP TO /WEB/# new project structure / /web/404.php /web/database.php /web/functions.php /web/index.php /web/page.php
![Page 57: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/57.jpg)
INSTALL COMPOSERphp -r "readfile('https://getcomposer.org/installer');" > composer-setup.phpphp -r "if (hash('SHA384', file_get_contents('composer-setup.php')) === php composer-setup.php php -r "unlink('composer-setup.php');"
![Page 58: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/58.jpg)
INIT COMPOSER CONFIG IN THE ROOT DIRphp composer.phar init
![Page 59: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/59.jpg)
PROJECT STRUCTUREls -l / /composer.json /web/
![Page 60: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/60.jpg)
COMPOSER.JSON
{ "name": "michalszczur/legacy-demo", "authors": [ { "name": "Michal Szczur", "email": "[email protected]" } ], "require": {}, "autoload": { "psr-4": { "": "src/" } }, "description": "Legacy app demo", "type": "project", "license": "proprietary"
![Page 61: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/61.jpg)
ADD DEPENDENCIESphp composer.phar require symfony/dependency-injection php composer.phar require symfony/config php composer.phar require symfony/yaml
![Page 62: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/62.jpg)
<?php # /web/container.php use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
require __DIR__.'/../vendor/autoload.php';
$container = new ContainerBuilder(); $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../app/config'$loader->load('services.yml');
$container->compile();
![Page 63: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/63.jpg)
WHICH SERVICES DO WE REALLYNEED?
![Page 64: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/64.jpg)
function show_all() { # Database connection needed $db = connect_to_db(); $sql = 'SELECT * FROM receivers'; $result = mysql_query($sql) or die(mysql_error()); //...
![Page 65: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/65.jpg)
CREATE SEVICES.YML DEFINITION
![Page 66: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/66.jpg)
SERVICES.YMLparameters: db_host: localhost db_port: 3306 db_name: legacyapp db_user: myuser db_pass: mypass
services: db: class: \PDO arguments: ['mysql:port=%db_port%;host=%db_host%;dbname=%db_name%' receiver_repository: class: PDOReceiverRepository arguments: ['@db']
![Page 67: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/67.jpg)
USE CONTAINER AND REPOSITORY
![Page 68: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/68.jpg)
#index.php ... require 'container.php'; ... function show_all() { # Database connection needed $receiverRepository = $container->get('receiver_repository'); $result = $receiverRepository->findAll(); ...
![Page 69: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/69.jpg)
#index.php ... $result = $receiverRepository->findAll(); foreach ($result as $row) { echo ''.$row['mail'].''; echo '<form id="'.$row['id'].'" name="n_ID" method="POST" action="mail_sender.php?page=show_all"><input type="hidden" name="id" value="'.$row['id'].'" /> <input type="submit" name="delete" value="Usuń" /> </form>'; } ...
![Page 70: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/70.jpg)
PHP ~ HTMLSTILL MIXED TOGETHER
![Page 71: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/71.jpg)
TWIGTEMPLATE ENGINE FOR PHP
![Page 72: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/72.jpg)
INSTALL TWIG USING COMPOSERphp composer.phar require twig/twig
![Page 73: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/73.jpg)
SERVICES.YMLparameters: ... twig_paths: - app/Resources/views services: ... twig.loader: class: Twig_Loader_Filesystem arguments: ['%twig_paths%'] twig: class: Twig_Environment arguments: ['@twig.loader']
![Page 74: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/74.jpg)
#index.php ... $twig = $container->get('@twig'); $result = $receiverRepository->findAll(); echo $twig->render( 'receiver_list.html.twig', ['receivers' => $result] ); ...
![Page 75: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/75.jpg)
{% for receiver in receivers %} <form id="{{ receiver.id }}" name="n_ID" method="POST" action="mail_sender.php?page=show_all"<input type="hidden" name="id" value="{{ receiver.id }}" /> <input type="submit" name="delete" value="Delete" /> </form> {% endfor %}
![Page 76: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/76.jpg)
BEFOREfunction show_all() { $db = connect_to_db(); $sql = 'SELECT * FROM mail_sender'; $result = mysql_query($sql) or die(mysql_error()); while ($row = mysql_fetch_array($result)) { //echo 'ID: ' . $row['id'] . ', mail: ' . $row['mail']; echo ''.$row['mail'].''; echo '<form id="'.$row['id'].'" name="n_ID" method="POST" action="mail_sender.php?page=show_all"><input type="hidden" name="id" value="'.$row['id'].'" /> <input type="submit" name="delete" value="Usuń" /> </form>'; } ... mysql_free_result($result); mysql_close($db); }
![Page 77: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/77.jpg)
AFTERfunction show_all() { $receiverRepository = $container->get('receiver_repository'); $twig = $container->get('@twig'); $result = $receiverRepository->findAll(); echo $twig->render( 'receiver_list.html.twig', ['receivers' => $result] ... );
![Page 78: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/78.jpg)
LET'S SUM UP
![Page 79: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/79.jpg)
COMMUNICATION
![Page 80: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/80.jpg)
ANALYZE
![Page 81: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/81.jpg)
TESTS
![Page 82: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/82.jpg)
SMALL STEPS
![Page 83: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/83.jpg)
NOT EVERYTHING SIMUNTANOUSLY
![Page 84: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/84.jpg)
PACKAGE MANAGER
![Page 85: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/85.jpg)
DEPENDENCY INJECTION
![Page 86: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/86.jpg)
THIRD PARTY LIBRARIES
![Page 87: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/87.jpg)
DESIGN PATTERNS
![Page 88: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/88.jpg)
SOLID
![Page 89: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/89.jpg)
DECOUPLE
![Page 90: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/90.jpg)
TESTS
![Page 91: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/91.jpg)
THANKS!
![Page 92: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/92.jpg)
QUESTIONS?SLIDES: SLIDESHARE.NET/MICHASZCZUR
TWITTER: @PARTIKUS
HOMEPAGE: MICHALSZCZUR.PL
![Page 93: How to work with legacy code PHPers Rzeszow #2](https://reader031.vdocuments.us/reader031/viewer/2022020203/587127d31a28abe4448b6807/html5/thumbnails/93.jpg)
LINKSCasperJSSymfony ComponentsWorking Effectively with Legacy Code by Michael FeathersPage Object Pattern (Martin Fowler)Page Object Pattern (Selenium Docs)Marek Matulka - Modernising the Legacy