Slide 1

Slide 1 text

Writing Faster PHP with HHVM and Hack

Slide 2

Slide 2 text

Proprietary and Confidential •Community Engineer at Engine Yard •Author of Zend PHP 5 Certification Study Guide, Sitepoints PHP Anthology: 101 Essential Tips, Tricks & Hacks & PHP Master: Write Cutting Edge Code •A contributor to Zend Framework 1 & 2, phpdoc, & PHP internals • Original creator of PHAR/ PHP_Archive •@dshafik Davey Shafik

Slide 3

Slide 3 text

Let’s start a conversation about mental health in tech mhprompt.org

Slide 4

Slide 4 text

Proprietary and Confidential

Slide 5

Slide 5 text

Proprietary and Confidential

Slide 6

Slide 6 text

Proprietary and Confidential

Slide 7

Slide 7 text

Proprietary and Confidential

Slide 8

Slide 8 text

Proprietary and Confidential

Slide 9

Slide 9 text

Proprietary and Confidential

Slide 10

Slide 10 text

A Brief History of HipHop VM Better known as HHVM

Slide 11

Slide 11 text

HPHPc 2009 - 2012

Slide 12

Slide 12 text

Proprietary and Confidential • Cross-compiler: PHP -> C++ • Needed to compile for every change, which took hours • Created huge binaries (approaching 2GB Linux “limit”) • PHP 5.2 (ish) feature-set • Missing support for large parts of the language (e.g. all 5.3+ features including namespaces, closures, and dynamic features like create_function(), and eval()) • Broke the developer workflow HPHPc — 2009 - 2012

Slide 13

Slide 13 text

HipHop VM (HHVM) 2013 -

Slide 14

Slide 14 text

Proprietary and Confidential • Alternate interpreted runtime with JIT compiler • No compiling process • Twice as fast as PHP in interpreted mode. • Ludicrous speed for JITed code • Bug-for-bug compatible with PHP • 5.6 feature set (e.g. support for variadics, splat) • Working on PHP 7 support HHVM

Slide 15

Slide 15 text

Hack A super-set of PHP

Slide 16

Slide 16 text

Proprietary and Confidential • AKA Hacklang (because “Hack” is un-google-able) • A syntactic super-set of PHP that allows for strong typing via static analysis. Adds support for: • type hinting • generics • async functions • annotations • more… • A language sub-set of PHP that disallows a number of bad practices • variable-variables • globals • mixing HTML & PHP • more… Hack

Slide 17

Slide 17 text

Performance

Slide 18

Slide 18 text

Proprietary and Confidential 0 75 150 225 300 Wordpress 3.9 SugarCRM CE 6.5.16 - login page Drupal 7.28 homepage Symfony 2.5 ACME app home page ZF 2.3.1 Skeleton App Magento 1.9 Homepage Magento 1.9 item page PHP 5.4 (no OPcache) PHP 5.5 PHP 5.6 hhvm 3.1 (prebuilt binaries) hhvm 3.2-dev(src) PHPNG Source: Zeev Suraski http://zsuraski.blogspot.com/2014/07/benchmarking-phpng.html

Slide 19

Slide 19 text

Proprietary and Confidential • Facebook (#2) • Baidu (#5, #1 Search Engine in China) • Wikimedia (incl. Wikipedia, #6) • Etsy (for their API) That’s 3 of the top 4 PHP sites in the world, and ~1/3 of the top 10 overall. (Yahoo! is the outlier, FYI) Actual Users

Slide 20

Slide 20 text

Repo Authoritative Mode Ludicrous Speed!

Slide 21

Slide 21 text

Proprietary and Confidential • When code “never” changes (e.g. production) • Extra 20-25% performance increase (similar to apc.stat = 0) • Spends extra time on caching/JITing for maximum performance Repo Authoritative Mode

Slide 22

Slide 22 text

HHVM Setup

Slide 23

Slide 23 text

Proprietary and Confidential login.php HHVM Setup Nginx php-fpm mysql,pgsql,mongo,
 gearman,redis, etc. index.php

Slide 24

Slide 24 text

Proprietary and Confidential login.php HHVM Setup Nginx mysql,pgsql,mongo,
 gearman,redis, etc. index.php HHVM

Slide 25

Slide 25 text

Proprietary and Confidential server { server_name _; root /var/www; index index.php; location ~ \.php$ { fastcgi_pass unix:/var/run/hhvm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /var/www$fastcgi_script_name; include fastcgi_param; } } HHVM Setup

Slide 26

Slide 26 text

Proprietary and Confidential hhvm.server.file_socket = /var/run/hhvm.sock hhvm.server.type = fastcgi hhvm.server.source_root = /var/www hhvm.log.level = Error hhvm.log.user_log_file = true hhvm.log.file = /var/log/hhvm-error.log hhvm.log.access.0.file = /var/log/hhvm-access.log hhvm.log.access.0.format=%h %l %u %t \"%r\" %>s %b HHVM Setup $ hhvm -m daemon -c /etc/hhvm/hhvm.ini -u www-data

Slide 27

Slide 27 text

Long Term Support

Slide 28

Slide 28 text

Proprietary and Confidential Long Term Support Version name Intended release date LTS? End of support 3.3 11 19 Sep 2014 yes 13 Aug 2015 3.4 6 Nov 2014 3.5 1 Jan 2015 3.6 26 Feb 2015 yes 28 Jan 2016 3.7 23 Apr 2015 3.8 18 Jun 2015 3.9 13 Aug 2015 yes 14 Jul 2016 3.10 8 Oct 2015 3.11 3 Dec 2015 3.12 28 Jan 2016 yes 29 Dec 2016 3.13 24 Mar 2016 3.14* 19 May 2016 3.15* 14 Jul 2016 yes 15 Jun 2017

Slide 29

Slide 29 text

Hack A better PHP

Slide 30

Slide 30 text

Proprietary and Confidential • Not a new language • Runs through the same HHVM runtime • Strongly typed… but thrown away at run time (type erasure) • Super-fast static analysis • Strict typing informs the runtime to enable better performance Hack A primary goal of hack is to not [negatively] impact the developers workflow — especially the REPL; whereby we can edit code and refresh our browser to immediately see changes. “ ” - Davey Shafik

Slide 31

Slide 31 text

Editor Support

Slide 32

Slide 32 text

Editor Support Supports any editor (so long it’s vim or emacs)

Slide 33

Slide 33 text

Coming Soon: phpStorm Yay!

Slide 34

Slide 34 text

File Semantics

Slide 35

Slide 35 text

Proprietary and Confidential • To promote best practices, you cannot mix Hack with HTML (or other non-code text) • All hack files must start with

Slide 36

Slide 36 text

Hack Modes

Slide 37

Slide 37 text

Partial Mode

Slide 38

Slide 38 text

Proprietary and Confidential • Default • Gradual Typing • Types are strictly adhered to however: • Not everything must be typed • May call into regular PHP code without error Partial Mode

Slide 39

Slide 39 text

Strict Mode

Slide 40

Slide 40 text

Proprietary and Confidential • All code must be typed • Cannot call into non-Hack code • No top-level code • This means your codebase cannot be 100% strict • Arrays must be type hinted • Collections (Vector, Set, Map, Tuple) are preferred Strict Mode

Slide 41

Slide 41 text

Declarations Mode AKA Decl

Slide 42

Slide 42 text

Proprietary and Confidential • Type hints are trusted but not required Declarations Mode

Slide 43

Slide 43 text

Ignoring Errors

Slide 44

Slide 44 text

Proprietary and Confidential • You can ignore errors by marking code as UNSAFE • Applied from the comment to the end of the current block: typically the next curly brace “}” • Should be the last resort • May result in run-time errors due to the lack of validation Ignoring Errors // UNSAFE

Slide 45

Slide 45 text

Type Hints

Slide 46

Slide 46 text

Proprietary and Confidential • Method Arguments • Return Values • Class Properties Type Hints

Slide 47

Slide 47 text

Proprietary and Confidential Types Type bool Boolean true/false Type Name int Integer numbers float Floating Point numbers string Strings array Arrays (that can be typed) resource Resources (e.g. file streams) Class/Interface Name An object type-hint

Slide 48

Slide 48 text

Proprietary and Confidential Types (Cont.) Type Name mixed Any (not recommended) Vector Numerical contiguously indexed Arrays Map A typed (both keys and values) associative array Set An unindexed collection of typed unique values Tuple A fixed size set of typed values Pair A fixed size set of typed values restricted to two values, indexed as 0 and 1.

Slide 49

Slide 49 text

Proprietary and Confidential • void — for functions with no return value • this — always refers to $this Special Types

Slide 50

Slide 50 text

Nullable Types

Slide 51

Slide 51 text

Proprietary and Confidential • Allows for nulls to be passed in addition to the specified type • Prefix the type with a ? • e.g. ?int or ?\DateTime. Nullable Types

Slide 52

Slide 52 text

Soft Types

Slide 53

Slide 53 text

Proprietary and Confidential • You can denote the a type-failure should not error by using soft types. • This is great for migrating codebases • To do this precede the type with an @ • e.g. @int or @\DateTime. Soft Types add("1", "2");

Slide 54

Slide 54 text

Custom Types

Slide 55

Slide 55 text

Proprietary and Confidential • Type Aliases (type) • Opaque Types (newtype) • Only used for static analysis. Custom Types

Slide 56

Slide 56 text

Proprietary and Confidential $status = Map { self::OK => "200 OK", self::FOUND => "302 Found", self::NOT_FOUND => "404 Not Found", }; public function send(HTTPStatusCode $code): bool { if (isset($this->status[$code])) { header('HTTP/1.1 ' .$this->status[$code]); return true; } return false; } }

Slide 57

Slide 57 text

Proprietary and Confidential send(404); }

Slide 58

Slide 58 text

Proprietary and Confidential • Allows you to give more appropriate names to existing types • e.g. unixtime for int Type Aliases

Slide 59

Slide 59 text

Proprietary and Confidential • Opaque types hide their underlying implementation outside of the file in which the type is defined. • This means they become immutable except when called in code defined in that file • This restriction is not enforced at runtime Opaque Types

Slide 60

Slide 60 text

Proprietary and Confidential newtype HTTPStatusCode = int;

Slide 61

Slide 61 text

Proprietary and Confidential send(HTTPStatus::NOT_FOUND); }

Slide 62

Slide 62 text

Constructor Argument Promotion

Slide 63

Slide 63 text

Proprietary and Confidential Constructor Property Assignment left = $left; $this->right = $right; } }

Slide 64

Slide 64 text

Proprietary and Confidential • Automatically create properties from constructor arguments • Just precede the argument with a visibility keyword: public, private, protected Constructor Argument Promotion left + $this->right; } } $adder = new Adder(1, 3); $result = $adder->get(); // 4

Slide 65

Slide 65 text

Collections

Slide 66

Slide 66 text

Proprietary and Confidential • Arrays — must be typed in strict mode • Tuples — typed arrays • Pairs — can only contain 2 pieces of data • Vectors — numerically, consecutively keyed only • Maps — ordered dictionaries that allow int or string keys • Sets — unordered collection of unique values • Immutable variants Collections

Slide 67

Slide 67 text

Arrays

Slide 68

Slide 68 text

Proprietary and Confidential • array — Untyped (only allowed in partial mode) • array<[type]> — [type] typed values, with integer keys • array<[type1], [type2]> — [type1] typed keys, with [type2] typed values. Arrays { return array(1, 2, 3); }

Slide 69

Slide 69 text

Tuples

Slide 70

Slide 70 text

Proprietary and Confidential • Internally identical to arrays • Fixed size • Implicitly Type hinted by the values used to define it or • Explicitly Type hinted using the literal syntax Tuples

Slide 71

Slide 71 text

Pairs

Slide 72

Slide 72 text

Proprietary and Confidential • Can contain only two values, keyed as 0 and 1 • Immutable Pairs { return Pair { "C039D17D", "checkPing" }; }

Slide 73

Slide 73 text

Vectors

Slide 74

Slide 74 text

Proprietary and Confidential • Vectors can only use integer keys Vectors { return Vector {"Davey", "PJ", "You?"}; }

Slide 75

Slide 75 text

Maps

Slide 76

Slide 76 text

Proprietary and Confidential • Maps are an ordered dictionary, which can have integer or string keys. • Must specify both key and values types when type hinting. Maps { return Map {"php" => "PHP", "hack" => "Hack"}; }

Slide 77

Slide 77 text

Sets

Slide 78

Slide 78 text

Proprietary and Confidential • Unordered Collection with no keys • Unique values { return Set { "php", "hack", "hhvm" }; }

Slide 79

Slide 79 text

Immutability

Slide 80

Slide 80 text

Proprietary and Confidential • Simply prefix the class name with Imm Immutability { $map = ImmMap {"php" => "PHP", "hack" => "Hack"}; $map["hhvm"] = "HHVM"; } |13 col 6 error| You cannot mutate this |12 col 13 error| This is an object of type ImmMap

Slide 81

Slide 81 text

Appending Elements

Slide 82

Slide 82 text

Proprietary and Confidential • Only Vectors allow $foo[] = "bar" syntax • Pairs and Tuples do not allow additional elements • Maps allow appending of Pairs. First value is key, second value is value Appending Elements "foo", 1 => "bar" }; $m[] = Pair { 5, "bat" }; var_dump($m); }

Slide 83

Slide 83 text

Object Oriented Interface

Slide 84

Slide 84 text

Proprietary and Confidential • Based on the SPL • Allows adding/removing/manipulation methods • Allows you to use them as objects, rather than just “better” arrays Object Oriented Interface

Slide 85

Slide 85 text

Breaking Iteration

Slide 86

Slide 86 text

Proprietary and Confidential • Because collections are objects, you cannot modify them during iteration. Breaking Iteration Fatal error: Uncaught exception 'InvalidOperationException' with message 'Collection was modified during iteration' in

Slide 87

Slide 87 text

Shapes

Slide 88

Slide 88 text

Proprietary and Confidential • Tuples with a pre-defined structure • Can be used as a form of validation • Ensures integrity Shapes newtype HTTPRequest = shape( 'status' => HTTPStatusCode, 'headers' => Map, 'data' => shape ( 'GET' => ?Map, 'POST' => ?Map, 'COOKIE' => ?Map, 'SERVER' => Map ), 'body' => ?string );

Slide 89

Slide 89 text

Anonymous Functions

Slide 90

Slide 90 text

Proprietary and Confidential • Like closures but they inherit parent scope • Much more concise • Multiple Expressions Anonymous Functions $fn = $args ==> expression; $fn = ($arg1, $arg2) ==> { expression; return ...; }; $list =
    ; array_walk($items, $item ==> $list->appendChild(
  • {$item}
  • ); echo $list;

    Slide 91

    Slide 91 text

    XHP — XML Fragments as Expressions

    Slide 92

    Slide 92 text

    Proprietary and Confidential • Makes XML syntax a top-level syntax • No longer strings • Auto-escapes for security • Allows for OO semantics, for composable widgets, for tempting • Must be XML, e.g.
    XHP — XML Fragments as Expression echo

    Hello World

    ;

    Slide 93

    Slide 93 text

    Proprietary and Confidential • Classes are defined by prefixing the class name with a colon • Classes extend the :x:element base class which has DOM-like methods: • appendChild() • prependChild() • replaceChildren() • getChildren() • getFirstChild() • getLastChild() • getAttribute(), getAttributes() • setAttribute(), setAttributes() • isAttributeSet() • removeAttribute() XHP (Cont.)

    Slide 94

    Slide 94 text

    Proprietary and Confidential The PHP Way '; foreach ($items as $item) { echo '
  • '; echo htmlentities($item, ENT_QUOTES, 'UTF-8'); echo '
  • '; } echo ''; ?>

    Slide 95

    Slide 95 text

    Proprietary and Confidential The Hack Way ; foreach ($items as $item) { $list->appendChild(
  • {$item}
  • ); }

    Slide 96

    Slide 96 text

    Proprietary and Confidential XHP-Bootstrap Dropdown Foo Bar Disabled ;

    Slide 97

    Slide 97 text

    Proprietary and Confidential XHP-Bootstrap

    Slide 98

    Slide 98 text

    Proprietary and Confidential • Validation — invalid tags are errors, attribute values (e.g. class names) are validated • Semantic Markup — tags are more descriptive • Encapsulation — create re-usable complex components • Future Proof — Change the underlying implementation XHP-Bootstrap

    Slide 99

    Slide 99 text

    Other Features

    Slide 100

    Slide 100 text

    Proprietary and Confidential • Async MySQL, memcached and Curl (3.6+) Other Features

    Slide 101

    Slide 101 text

    Command Line Tools

    Slide 102

    Slide 102 text

    Static Analysis

    Slide 103

    Slide 103 text

    hh_server

    Slide 104

    Slide 104 text

    Proprietary and Confidential • Monitors files for changes using inotify • Validates the files using static analysis • Analyses .php and .hh files with the

    Slide 105

    Slide 105 text

    hh_client

    Slide 106

    Slide 106 text

    Proprietary and Confidential • Starts hh_server if necessary • Retrieves the results of the static analysis from hh_server • Displays them in the CLI • Integrates with Vim/Emacs Static Analysis

    Slide 107

    Slide 107 text

    Proprietary and Confidential 1.

    Slide 108

    Slide 108 text

    Proprietary and Confidential 1.

    Slide 109

    Slide 109 text

    Proprietary and Confidential Static Analysis

    Slide 110

    Slide 110 text

    Proprietary and Confidential Vim Integration

    Slide 111

    Slide 111 text

    Refactoring

    Slide 112

    Slide 112 text

    Proprietary and Confidential • hh_client check --refactor • Can rename classes, functions, or methods • Does not yet support namespaces :( • Static analysis makes these changes much less prone to error Refactoring $ hh_client check --refactor WARNING: This tool will only refactor references in typed, hack code. Its results should be manually verified. Namespaces are not yet supported. What would you like to refactor: 1 - Class 2 - Function 3 - Method Enter 1, 2, or 3: 2 Enter function name: sayHello Enter a new name for this function: sayHi Rewrote 2 files.

    Slide 113

    Slide 113 text

    Hackificating

    Slide 114

    Slide 114 text

    Converting from PHP to Hack

    Slide 115

    Slide 115 text

    Proprietary and Confidential – Change the opening tag – Add soft type hints – Run the code with soft type hints and gather the logs – Feed the logs back into HHVM to remove invalid hints (ensures there is no invalid inference) – Harden the type hints Hackificating

    Slide 116

    Slide 116 text

    Proprietary and Confidential • Hackificator changes the opening tag from PHP to Hack: • $ hackificator . Hackificator

    Slide 117

    Slide 117 text

    Proprietary and Confidential • Uses static analysis to figure out and add soft type hints: • $ hh_server --convert ./ ./ Add Soft Type Hints public static function makeBarcode(
 $barcode, 
 $barcodeConfig = array()
 ) public static function makeBarcode(
 @?string $barcode, 
 @array $barcodeConfig = array()
 ) : @\Zend\Barcode\Object\ObjectInterface

    Slide 118

    Slide 118 text

    Proprietary and Confidential • Run the code (tests suites are great for this!) • Capture the hhvm log file Verify Soft Type Hints

    Slide 119

    Slide 119 text

    Proprietary and Confidential • Feed the log file into hack_remove_soft_types to remove invalid types: • $ hack_remove_soft_types --delete-from-log hhvm.log • Note: This tool is dumb and requires paths to be identical Remove Invalid Soft Type Hints

    Slide 120

    Slide 120 text

    Proprietary and Confidential • Finally: Harden all the left over types • $ hack_remove_soft_types --harden FILE • Run it over all files in a directory: • Harden Soft Types $ find ./ -type f -name '*.php' -exec hack_remove_soft_types --harden '{}' ';'

    Slide 121

    Slide 121 text

    Proprietary and Confidential • Hack Lang: http://hacklang.org • HHVM: http://hhvm.com • Building a Better PHP: https://blog.engineyard.com/2014/hhvm-hack (Engine Yard Blog) Resources

    Slide 122

    Slide 122 text

    Proprietary and Confidential Feedback & Questions: 
 Feedback: https://joind.in/
 Twitter: @dshafik Email: [email protected] Slides: http://daveyshafik.com/slides 14540