Slide 1

Slide 1 text

PHP modern & secure

Slide 2

Slide 2 text

Who is this guy? Ben Edmunds Open Source Author PHP Town Hall Podcast CTO at Mindfulware

Slide 3

Slide 3 text

Who is this guy? Ben Edmunds @benedmunds http://benedmunds.com

Slide 4

Slide 4 text

Welcome to the Future

Slide 5

Slide 5 text

Great Scott!

Slide 6

Slide 6 text

Welcome to the Future PDO Closures Namespaces

Slide 7

Slide 7 text

Welcome to the Future Anonymous Classes Traits Interfaces

Slide 8

Slide 8 text

Welcome to the Future Null Coalescing Scalar Type Hints Return Type Declarations

Slide 9

Slide 9 text

Welcome to the Future Variadic Functions Authentication Password Hasing

Slide 10

Slide 10 text

Welcome to the Future SQL Injection HTTPS

Slide 11

Slide 11 text

Welcome to the Future Common Hacks

Slide 12

Slide 12 text

Legit Tools Built-in Server Composer Unit Testing

Slide 13

Slide 13 text

Standards PHP-FIG PSRs

Slide 14

Slide 14 text

Exceptions

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

Exceptions try { //your code goes here } catch (Exception $e) { die($e->getMessage()); }

Slide 17

Slide 17 text

Exceptions try { //your code goes here } catch (Exception $e) { die($e->getMessage()); }

Slide 18

Slide 18 text

Errors Exception implements Throwable Error implements Throwable

Slide 19

Slide 19 text

Errors try { //error thrown here } catch (Error $e) { die($e->getMessage()); }

Slide 20

Slide 20 text

Errors try { //error thrown here } catch (Error $e) { die($e->getMessage()); } catch (Exception $e) { die($e->getMessage()); }

Slide 21

Slide 21 text

Errors try { //err or excpt thrown here } catch (Throwable $t) { die($t->getMessage()); }

Slide 22

Slide 22 text

Errors try { //error or excpt thrown here } catch (Error | Exception $e) { die($e->getMessage()); }

Slide 23

Slide 23 text

Namespaces

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

Namespaces namespace Illuminate\Console; class Command { //…

Slide 26

Slide 26 text

Namespaces use Illuminate\Console\Command; namespace Illuminate\Console; class Command { //…

Slide 27

Slide 27 text

Namespaces use Illuminate\Console\Command; namespace Illuminate\Console; class Command { //…

Slide 28

Slide 28 text

PDO

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

PDO Cross System Safe Binding

Slide 31

Slide 31 text

PDO $stmt = $db->prepare(‘ SELECT * FROM users WHERE id=:id ’); $stmt->bindParam(‘:id’, $id); $stmt->execute();

Slide 32

Slide 32 text

Traits

Slide 33

Slide 33 text

Traits // grouping without // strict inheritance trait baseUser { function getName() { return ‘Jon Snow’; } }

Slide 34

Slide 34 text

Traits class adminUser { use baseUser; }

Slide 35

Slide 35 text

Traits $adminUser = new adminUser; echo $adminUser->getName(); //output = ‘Jon Snow’

Slide 36

Slide 36 text

Traits trait Loggable { function log($msg) { echo $msg; } }

Slide 37

Slide 37 text

Traits class Post { function get($id) { return $this->db->get($id); } }

Slide 38

Slide 38 text

Traits class Post { use Loggable; function get($id) { $this->log('Getting post ' . $id); return $this->db->get($id); } }

Slide 39

Slide 39 text

Traits $postModel = new Post; $myPost = $postModel->get(1); //output = ‘Getting post 1’

Slide 40

Slide 40 text

Traits class Post extends Model { use SoftDeletes; }

Slide 41

Slide 41 text

Interfaces

Slide 42

Slide 42 text

Interface Class myLogger { public function log($msg) { echo $msg; } }

Slide 43

Slide 43 text

Interface interface Logger { public function log($msg); }

Slide 44

Slide 44 text

Interface Class myLogger implements Logger { public function log($msg) { echo $msg; } }

Slide 45

Slide 45 text

Closures

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

Closures Route::get(‘/', function(){ return View::make(‘index'); });

Slide 48

Slide 48 text

Closures Route::get(‘/', function(){ return View::make(‘index'); });

Slide 49

Slide 49 text

Closures $input = [1, 2, 3, 4, 5, 6, 7, 8]; $output = array_filter($input, function($v){ return $v > 5; }); // [6,7,8]

Slide 50

Slide 50 text

Closures $input = [1, 2, 3, 4, 5, 6, 7, 8]; $output = array_map(function($n){ return number_format($n * 10, 2) . '%'; }, array_filter($input, function($v){ return $v > 5; })); // ['60.00%', '70.00%', '80.00%']

Slide 51

Slide 51 text

Anonymous Classes

Slide 52

Slide 52 text

Anonymous Classes trait Loggable { function log($msg) { echo $msg; } }

Slide 53

Slide 53 text

Anonymous Classes interface Logger { public function log($msg); }

Slide 54

Slide 54 text

Anonymous Classes trait Loggable { protected $logger; function setLogger(Logger $logger) { $this->logger = $logger; } function log($msg) { $this->logger->log($msg); } }

Slide 55

Slide 55 text

Anonymous Classes class Post { use Loggable; } $post = new Post;

Slide 56

Slide 56 text

Anonymous Classes class Post { use Loggable; } $post = new Post; $post->setLogger( new class implements Logger { public function log($msg) { echo date('m/d G:i') . ': ' .$msg; } });

Slide 57

Slide 57 text

Anonymous Classes $postModel = new Post; $myPost = $postModel->get(1); //output = ‘09/08 16:20: Getting post 1’

Slide 58

Slide 58 text

Null Coalescing Operator

Slide 59

Slide 59 text

Null Coalescing $val = isset($_GET[‘val’]) ? $_GET[‘val’] : 'default';

Slide 60

Slide 60 text

Null Coalescing $val = $_GET['val'] ?? 'default';

Slide 61

Slide 61 text

Null Coalescing $val = $_GET['val'] ?? 'default';

Slide 62

Slide 62 text

Types!

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

Scalar Type Hinting

Slide 65

Slide 65 text

Types declare(strict_types=1); function addNums(float $a, float $b) { return $a + $b; }

Slide 66

Slide 66 text

Types declare(strict_types=1); function addNums(float $a, float $b) { return $a + $b; } addNums(2, "1 week"); // Fatal error: Uncaught TypeError: Argument 2 passed to addNums() must be of the type float, string given

Slide 67

Slide 67 text

Types function addNums(float $a, float $b) addNums(2, "1 week”); // Fatal error: Uncaught TypeError: Argument 2 passed to addNums() must be of the type float, string given

Slide 68

Slide 68 text

Types try { addNums(2, "1 week”); } catch(TypeError $e) {}

Slide 69

Slide 69 text

Types try { addNums(2, 1); } catch(TypeError $e) {} //3

Slide 70

Slide 70 text

Types class/interface array callable bool float int string object

Slide 71

Slide 71 text

Return Type Declarations

Slide 72

Slide 72 text

Types function addNums(float $a, float $b) : int { return $a + $b; }

Slide 73

Slide 73 text

Types function addNums(float $a, float $b) : int { return $a + $b; }

Slide 74

Slide 74 text

Types function addNums($a, $b) : int { return $a + $b; } addNums(1.5, 1); // Fatal error: Uncaught TypeError: Return value of addNums() must be of the type integer, float returned

Slide 75

Slide 75 text

Types function addNums(float $a, ?float $b) : int { return $a + $b??0; } addNums(1, null); // int(1)

Slide 76

Slide 76 text

Types function addNums(float $a, ?float $b) : ?int { return $a + $b??0; } addNums(1, null); // int(1)

Slide 77

Slide 77 text

Types public function log($msg) : void { Logger::write($msg); }

Slide 78

Slide 78 text

Variadic Functions

Slide 79

Slide 79 text

Scalar Types function addNums(float $a, float $b) : int { return $a + $b; }

Slide 80

Slide 80 text

Variadic Functions function addNums(...$numbers) : int { return array_sum($numbers); } addNums(1, 2, 3, 4); // int(10)

Slide 81

Slide 81 text

Variadic Functions function addNums(float …$numbers) : int { return array_sum($numbers); } addNums(1, 2, 3, 4); // int(10)

Slide 82

Slide 82 text

Security

Slide 83

Slide 83 text

No content

Slide 84

Slide 84 text

HTTPS

Slide 85

Slide 85 text

HTTPS Encrypts traffic across the wire Trusted send and receiver Required by OAUTH 2

Slide 86

Slide 86 text

HTTPS https://letsencrypt.org/

Slide 87

Slide 87 text

Authentication

Slide 88

Slide 88 text

Security //authentication - access control if (!$user->inGroup(‘admin’)) { return ‘ERROR YO’; }

Slide 89

Slide 89 text

Security //authentication - brute force if ($user->loginAttempts > 5) { return ‘CAUGHT YA’; }

Slide 90

Slide 90 text

Passwords

Slide 91

Slide 91 text

Passwords //safe password hashing password_hash($_POST['pass'], ALGO);

Slide 92

Slide 92 text

Passwords //safe password hashing password_hash($_POST['pass'], ALGO); //password verification password_verify($_POST['pass'], $u->pass);

Slide 93

Slide 93 text

Passwords //safe password hashing password_hash($_POST['pass'], ALGO); //password verification password_verify($_POST['pass'], $u->pass); //password rehashing password_needs_rehash($u->pass, ALGO);

Slide 94

Slide 94 text

Passwords if (password_verify($_POST['pass'], $u->pass)) { if (password_needs_rehash( $u->pass, PASSWORD_DEFAULT )) { $u->pass = password_hash( $_POST['pass'], PASSWORD_DEFAULT ); $u->save();

Slide 95

Slide 95 text

Safe Defaults

Slide 96

Slide 96 text

Security //safe defaults class Your Controller { protected $var1 = ‘default value’; function __construct() { … } }

Slide 97

Slide 97 text

Security //safe defaults $something = false; foreach ($array as $k => $v) { $something = $v->foo; if ($something == ‘bar’) { … } }

Slide 98

Slide 98 text

Security function addNums(float $a, float $b) : int { return $a + $b; } $something = []; foreach ($array as $v) { $something[] = addNums($v[0], $v[1]) }

Slide 99

Slide 99 text

Common Hacks

Slide 100

Slide 100 text

Security //Non-Persistent XSS http://www.yourSite.com/ ?page_num=2&per_page=50 Send the link to someone, boom

Slide 101

Slide 101 text

Security //Persistent XSS Same idea, except with data that is saved to the server and re-displayed

Slide 102

Slide 102 text

Security //escaping input $stmt->bindParam(‘:id’, $id);

Slide 103

Slide 103 text

Security //escaping input $stmt->bindParam(‘:id’, $id); //escaping output htmlentities($_POST[‘name’]);

Slide 104

Slide 104 text

Security //escaping input Class myModel extend Model { function save($id) { $stmt = $this->query->insert(); $stmt->bindParam(‘:id’, $id); $stmt->execute(); } }

Slide 105

Slide 105 text

Security //escaping output

Title

Hello

Slide 106

Slide 106 text

Security //Cross Site Request Forgery //(CSRF) http://yourSite.com/ users/12/delete

Slide 107

Slide 107 text

Security //CSRF Protection POST / PUT / UPDATE / DELETE behind forms with one-time use tokens

Slide 108

Slide 108 text

Security //CSRF Protection function generateCsrf() { $token = mcrypt_create_iv( 16, MCRYPT_DEV_URANDOM); Session::flash('csrfToken', $token); return $token; }

Slide 109

Slide 109 text

Security //CSRF Protection function generateCsrf() { $token = bin2hex(random_bytes(16)); Session::flash('csrfToken', $token); return $token; }

Slide 110

Slide 110 text

Security //CSRF Protection if ( $_POST['token'] == Session::get(‘csrfToken') ) { … }

Slide 111

Slide 111 text

Legit Tools

Slide 112

Slide 112 text

No content

Slide 113

Slide 113 text

Built-in Web Server

Slide 114

Slide 114 text

Built-in Server $ php -S localhost:8000 PHP 5.7.0 Development Server started… Listening on localhost:8000 Document root is /home/ben/htdocs Press Ctrl-C to quit

Slide 115

Slide 115 text

Composer

Slide 116

Slide 116 text

Another Package Manager!?

Slide 117

Slide 117 text

Composer Sane Package Management Autoloading via PSR4

Slide 118

Slide 118 text

Composer / composer.json { "require": { "stripe/stripe-php": "dev-master", "twilio/sdk": "dev-master" } }

Slide 119

Slide 119 text

Composer $ php composer.phar install -> composer.lock

Slide 120

Slide 120 text

Composer $ php composer.phar install -> composer.lock Commit it ^

Slide 121

Slide 121 text

Composer $ php composer.phar install /composer.lock

Slide 122

Slide 122 text

Composer $ php composer.phar update /composer.json

Slide 123

Slide 123 text

Composer $client = new Services_Twilio($sid, $tkn); $client->account ->messages ->sendMessage(…)

Slide 124

Slide 124 text

Unit Testing

Slide 125

Slide 125 text

No content

Slide 126

Slide 126 text

Unit Testing PHPUnit Behat Mink Selenium CodeCeption PHPSpec

Slide 127

Slide 127 text

Unit Testing class ApiAuthTest extends PHPUnit_Framework_TestCase { public function testVerify() { $auth = new apiAuth(); $this->assertTrue($auth->verify());

Slide 128

Slide 128 text

Unit Testing class ApiAuthTest extends PHPUnit_Framework_TestCase { public function testVerify() { $auth = new apiAuth(); $this->assertTrue($auth->verify());

Slide 129

Slide 129 text

Unit Testing $ phpunit tests PHPUnit 3.3.17 by Sebastian Bergmann. Time: 0.01 seconds OK (1 tests, 1 assertions)

Slide 130

Slide 130 text

Standards

Slide 131

Slide 131 text

No content

Slide 132

Slide 132 text

Standards PHP-FIG Framework Interop Group

Slide 133

Slide 133 text

Standards Member Projects Zend Symfony CakePHP Magento Joomla Drupal

Slide 134

Slide 134 text

Standards PSRs PHP Standards Recommendation

Slide 135

Slide 135 text

Standards PSRs Autoloading Interfaces Style Guides

Slide 136

Slide 136 text

Standards PSRs PSR-4: Autoloading PSR-1: Basic Coding Standards PSR-2: Coding Style Guide PSR-7: HTTP Message Interface PSR-6: Caching Interface PSR-3: Logger Interface

Slide 137

Slide 137 text

Resources

Slide 138

Slide 138 text

No content

Slide 139

Slide 139 text

Resources PHP.net

Slide 140

Slide 140 text

Resources Modern Frameworks Laravel Symfony2 SlimPHP Cake PHP

Slide 141

Slide 141 text

Resources leanpub.com/ phptherightway PHPtheRightWay.com

Slide 142

Slide 142 text

Resources Give Me $$$ SecuringPhpApps.com SecuringNodeApps.com

Slide 143

Slide 143 text

Q/A TIME! https://joind.in/talk/83929 Ben Edmunds @benedmunds