Slide 1

Slide 1 text

Composing a Better Phuture by Jeremy Lindblom @jeremeamia

Slide 2

Slide 2 text

● Composer ● Packages ● SemVer ● Autoloading ● PSRs Composing a Better Phuture

Slide 3

Slide 3 text

But first, a history lesson. (Don’t worry, we’ll only cover a few years)

Slide 4

Slide 4 text

PHP is “mostly dead” 2008

Slide 5

Slide 5 text

is “mostly dead” 2008 2009 PHP 5.3.0 is released

Slide 6

Slide 6 text

♥ for Git/GitHub grow 2010

Slide 7

Slide 7 text

PSR-0 & Composer 2011

Slide 8

Slide 8 text

HaPHPy 20th Birthday 2015

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

1. Dependency Manager 2. Autoloader Generator What is Composer?

Slide 12

Slide 12 text

1. Dependency Manager 2. Autoloader Generator What is Composer?

Slide 13

Slide 13 text

Dependency Management ● Declare, resolve, and install project-specific dependencies ● Use others’ code ○ Use open source packages ○ Focus on your biz features ○ Avoid “NIH syndrome” ● Create reusable packages in your own org

Slide 14

Slide 14 text

Before Composer ● Compile PHP with extensions ● System-level package managers ● PEAR packages (system-system) ● Include 3rd-party code in source ● Git submodules Composer inspired by bundler and npm

Slide 15

Slide 15 text

getcomposer.org packagist.org

Slide 16

Slide 16 text

https://github.com/engrade/engrade-php-sdk/blob/master/composer.json Composer.json Example

Slide 17

Slide 17 text

Specifying Versions MAJOR.MINOR.PATCH (SemVer.org) “{vendor}/{package}”: “{version constraints}” ● “>=3.1.4” – Use any version >= 3.1.4 ● “3.1.*” – Use any patch version of 3.1 ● “~3.2” – Use any 3.x version >= 3.2

Slide 18

Slide 18 text

Installing Composer curl -sS https://getcomposer.org/installer | php mv composer.phar /usr/local/bin/composer

Slide 19

Slide 19 text

Installing Your Dependencies For development: composer install and composer update For production: composer install --no-dev --optimize-autoloader

Slide 20

Slide 20 text

your-project-root/ |— src/ |— tests/ |— vendor/ |— composer.json |— composer.lock What does that do?

Slide 21

Slide 21 text

SHOULD YOU COMMIT YOUR composer.lock FILE? THE ANSWER MAY SHOCK YOU!

Slide 22

Slide 22 text

For Applications? ?

Slide 23

Slide 23 text

For Applications? YES!

Slide 24

Slide 24 text

For Applications? For Libraries? ? YES!

Slide 25

Slide 25 text

For Applications? For Libraries? Sure. YES!

Slide 26

Slide 26 text

How do you use your installed code? get(‘http://example.com’);

Slide 27

Slide 27 text

1. Dependency Manager 2. Autoloader Generator What is Composer?

Slide 28

Slide 28 text

— Includes —

Slide 29

Slide 29 text

a.php CODE CODE include ‘b.php’; CODE Includes = Why I Started Using PHP b.php CODE CODE CODE CODE Executed code CODE CODE CODE CODE CODE CODE CODE

Slide 30

Slide 30 text

Includes = Why I Started Using PHP header.php sidebar.php main.php

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

include include_once require require_once Including vs. Requiring What’s the difference between all of these?

Slide 33

Slide 33 text

Including Classes - Not Fun

Slide 34

Slide 34 text

The Bottom Line Explicit includes/requires are: 1. Necessary and helpful for procedural code. 2. Cumbersome and harmful for object- oriented code.

Slide 35

Slide 35 text

— Autoloaders —

Slide 36

Slide 36 text

What is an Autoloader? 1. A callback triggered when a non-existent class is referenced.

Slide 37

Slide 37 text

What is an Autoloader? 1. A callback triggered when a non-existent class is referenced. 2. A function that provides a definition for a specified class name.

Slide 38

Slide 38 text

Autoloader Advantages ● Classes are loaded on demand ○ No need to write specific include statements ○ Class never loaded unless it’s needed ● Leads to better code maintainability ● Easy to write

Slide 39

Slide 39 text

Simple Autoloader Implementation class Autoloader { public function __construct($root) {...} public function load($class) { $path = $path->root; $path .= str_replace(‘\\’, ‘/’, $class); if (file_exists($path)) require $path; } }

Slide 40

Slide 40 text

Registering Autoloaders $loader = new Autoloader(__DIR__); spl_autoload_register([$loader, ‘load’]);

Slide 41

Slide 41 text

Autoloader Implementation Tips ● You can have multiple autoloaders. ● Don’t throw errors/exceptions if a file doesn’t exist. Let the other autoloaders try. ● Don’t use the __autoload() function. ● Use Composer’s autoloader. ○ You don’t have to write your own ○ It already follows the PSR autoloading standards

Slide 42

Slide 42 text

— PSRs & PHP-FIG —

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

● FIG = Framework Interop Group ● PSR = PHP Standards Recommendation ○ Autoloading: PSR-0, PSR-4 ○ Others: ■ PSR-1, PSR-2 - Coding style ■ PSR-3 - Logging interface ■ PSR-7 - HTTP message interface PHP-FIG

Slide 45

Slide 45 text

Autoloader Implementation Revisited class Autoloader { public function __construct($root) {...} public function load($class) { $path = $path->root; $path .= str_replace(‘\\’, ‘/’, $class); if (file_exists($path)) require $path; } }

Slide 46

Slide 46 text

Autoloader Implementation Revisited class Autoloader { public function __construct($root) {...} public function load($class) { $path = $path->root; $path .= str_replace(‘\\’, ‘/’, $class); if (file_exists($path)) require $path; } }

Slide 47

Slide 47 text

Class to load: Zend\Http\Client Include file: /Zend/Http/Client.php Autoloading PSRs (PSR-0)

Slide 48

Slide 48 text

Source root base namespace: Zend\Http Class to load: Zend\Http\Client Include file: /Client.php Autoloading PSRs (PSR-4)

Slide 49

Slide 49 text

Base Namespace in composer.json { ... "autoload": { "psr-4": { "Zend\\Http\\": "src/" } } }

Slide 50

Slide 50 text

— Optimization —

Slide 51

Slide 51 text

BAD GOOD There are many ways to implement autoloaders.

Slide 52

Slide 52 text

All classes in one file; no autoloader BAD GOOD

Slide 53

Slide 53 text

Many autoloaders; Each can only load 1 class BAD GOOD

Slide 54

Slide 54 text

BAD GOOD 2 1

Slide 55

Slide 55 text

BAD GOOD Composer autoloader (1 autoloader handles all classes)

Slide 56

Slide 56 text

BAD GOOD Composer optimized autoloader (1 autoloader; fast lookup; no file_exists)

Slide 57

Slide 57 text

Classmap Autoloading In your project root: composer install --no-dev --optimize-autoloader

Slide 58

Slide 58 text

Classmap Autoloading $paths = [...]; // class => file mappings if (isset($paths[$class])) require $paths[$class]; // vs. $path = $root . str_replace(‘\\’, ‘/’, $class); if (file_exists($path)) require $path;

Slide 59

Slide 59 text

One Autoloader to rule them all.

Slide 60

Slide 60 text

Composing a Better Phuture by Jeremy Lindblom @jeremeamia