Slide 1

Slide 1 text

PHP 5.5 The New Bits

Slide 2

Slide 2 text

•Engineer at Engine Yard on the Orchestra PHP Platform •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, phpdoc, FRAPI and PHP internals •@dshafik Davey Shafik

Slide 3

Slide 3 text

About These Slides

Slide 4

Slide 4 text

About These Slides • Two slides per “slide” • Title Slide (for when I’m talking) • Details slide (for later) • Nobody likes it when you can read the slide just as well as the speaker can • I like slides that are useful 4

Slide 5

Slide 5 text

The Small Stuff

Slide 6

Slide 6 text

The Small Stuff • PCRE (Perl Compatible Regular Expression) /e (eval) pattern modifier deprecated • ext/mysql is now officially deprecated • mcrypt_ecb(), mcrypt_cbc(), mcrypt_cfb() and mcrypt_ofb() deprecated • Drop Windows XP and 2003 support • Remove php_logo_guid(), php_egg_logo_guid(), php_real_logo_guid(), zend_logo_guid() • Return previous handler when passing NULL to set_error_handler() and set_exception_handler() • Added optional second argument for assert() to specify custom message • Added boolval() • Added support for PBKDF2: hash_pbkdf2() 6

Slide 7

Slide 7 text

The Small Stuff (Cont.) intlcal_get_keyword_values_for_locale() intlcal_get_now() intlcal_get_available_locales() intlcal_get() intlcal_get_time() intlcal_set_time() intlcal_add() intlcal_set_time_zone() intlcal_after() intlcal_before() intlcal_set() intlcal_roll() intlcal_clear() intlcal_field_difference() intlcal_get_actual_maximum() intlcal_get_actual_minimum() intlcal_get_day_of_week_type() intlcal_get_first_day_of_week() intlcal_get_greatest_minimum() intlcal_get_least_maximum() intlcal_get_locale() intlcal_get_maximum() intlcal_get_minimal_days_in_first_week() intlcal_get_minimum() intlcal_get_time_zone() intlcal_get_type() intlcal_get_weekend_transition() intlcal_in_daylight_time() intlcal_is_equivalent_to() intlcal_is_lenient() intlcal_is_set() intlcal_is_weekend() intlcal_set_first_day_of_week() intlcal_set_lenient() intlcal_equals() intlcal_get_repeated_wall_time_option() intlcal_get_skipped_wall_time_option() intlcal_set_repeated_wall_time_option() intlcal_set_skipped_wall_time_option() intlcal_from_date_time() intlcal_to_date_time() intlcal_get_error_code() intlcal_get_error_message() intlgregcal_create_instance() intlgregcal_set_gregorian_change() intlgregcal_get_gregorian_change() intlgregcal_is_leap_year() intltz_create_time_zone() intltz_create_default() intltz_get_id() intltz_get_gmt() intltz_get_unknown() intltz_create_enumeration() intltz_count_equivalent_ids() intltz_create_time_zone_id_enumeration() intltz_get_canonical_id() intltz_get_region() intltz_get_tz_data_version() intltz_get_equivalent_id() intltz_use_daylight_time() intltz_get_offset() intltz_get_raw_offset() intltz_has_same_rules() intltz_get_display_name() intltz_get_dst_savings() intltz_from_date_time_zone() intltz_to_date_time_zone() intltz_get_error_code() intltz_get_error_message() datefmt_format_object() datefmt_get_calendar_object() datefmt_get_timezone() datefmt_set_timezone() datefmt_get_calendar_object() intlcal_create_instance() Tons of new ext/intl changes (75 new functions!)

Slide 8

Slide 8 text

boolval()

Slide 9

Slide 9 text

More on boolval() • Identical to: (bool) $var • Returns false for empty arrays and strings, and zero. • Everything else returns true (except false!) 9 var_dump(boolval([])); bool(false) var_dump(boolval("")); bool(false) var_dump(boolval(new stdClass())); bool(true) var_dump(boolval(["foo", "bar"]); bool(true)

Slide 10

Slide 10 text

NULL with set_(error|exception)_handler

Slide 11

Slide 11 text

More on set_(error|exception)_handler 11 • Passing NULL sets the handler to default var_dump(set_error_handler(function()2{2})); 22NULL 2 var_dump(set_error_handler(null)); 22object(Closure)#1#(0)#{ 22} 2 var_dump(set_error_handler(null)); 22NULL

Slide 12

Slide 12 text

assert() Descriptions

Slide 13

Slide 13 text

More on assert() • New argument to provide a description of failure 13 assert_options(ASSERT_ACTIVE, IS_ASSERT_ACTIVE); function foo($bar, $bat) { assert( $bar < $bat, "Second arg is more than first" );' } foo(2, 1); Warning: assert(): Second arg is less than first failed in on line <#>

Slide 14

Slide 14 text

list() support in foreach

Slide 15

Slide 15 text

list() support in foreach 15 • Allows assignment of nested array values (1st level) to multiple variables, within the foreach declaration $result = [ [ 'name' => 'Davey Shafik', 'email' => '[email protected]', ], [ 'name' => 'Helgi Þormar Þorbjörnsson', 'email' => '[email protected]', ] ]; foreach ($result as list($name, $email)) { echo $name, ': ', $email . PHP_EOL; }

Slide 16

Slide 16 text

empty() supports any expression

Slide 17

Slide 17 text

empty() supports any expression 17 • Prior to 5.5, empty() only allowed variables as input. Now it can be called on any expression, e.g. function calls if (empty(some_function()) { // Do something }

Slide 18

Slide 18 text

String/Array Dereferencing

Slide 19

Slide 19 text

String/Array Dereferencing 19 • PHP 5.4 added support for function dereferencing, 5.5 adds the same feature to constant strings and arrays // Added in PHP 5.4: someFunction()[$key]; // Now available in PHP 5.5 "somestring"[$key]; // And: ["foo", "bar", "baz"][$key]; // Note: $key can be any valid expression!

Slide 20

Slide 20 text

“finally” keyword

Slide 21

Slide 21 text

“finally” keyword 21 • Code within a finally block always is run after either of the try, or catch blocks. try { // Try something } catch (\Exception $exception) { // Handle exception } finally { // Whatever happened, do this }

Slide 22

Slide 22 text

Fully Qualified Classname Constant

Slide 23

Slide 23 text

Fully Qualified Classname Constant 23 • Easy access to the fully qualified class name via a simple constant. Allows for easy dynamic creation of class (think: Reflection, Unit Testing) namespace App { class Config { } $className = "Config"; new $className; // Fatal error: Class 'Config' not found // Instead: $className = "App\Config"; new $className; // Works // Added in 5.5: $className = Config::class; // = App\Config new $className; }

Slide 24

Slide 24 text

Simple Password Hashing

Slide 25

Slide 25 text

Simple Password Hashing • Makes password hashing super easy • Purpose: to make sure everyone uses safe password storage • Uses the excellent bcrypt (currently) • No salting is required • The hash itself identifies the algorithm, salt and options options when passed to password_verify() • You may pass an array with salt and cost as third argument to password_hash() 25

Slide 26

Slide 26 text

Simple Password Hashing (cont.) 26 $options = [ 'cost' => 20, 'salt' => 'bcryptuses22characters' ]; $hash = password_hash("testing", PASSWORD_DEFAULT, $options); $hash = password_hash("testing", PASSWORD_DEFAULT); if (password_verify("testing", $hash)) { // valid } Specify Options:

Slide 27

Slide 27 text

Simple Password Hashing (cont.) • Also provides two helper functions: • password_needs_rehash() will determine if the hash uses the current algorithm, cost and salt, returning true if it doesn’t match. • password_get_info() returns an array providing information about a hash such as algorithm, cost and salt. 27

Slide 28

Slide 28 text

More on password security

Slide 29

Slide 29 text

More on password security • A strong salt makes a dictionary attack much more difficult • A high cost means it takes a long time (say, 1/10th second) to generate a single password, making brute force attacks too slow to be effective • The cost is what makes SHA-1 and MD5 poor options because they are designed to be fast, this is the enemy of security. • Additionally, MD5 suffers from too many easy collisions (e.g. two different strings that create the same hash) 29 Goal: Make both dictionary and brute force attacks difficult.

Slide 30

Slide 30 text

Generators

Slide 31

Slide 31 text

Generators • Introduces new yield keyword - execution is handed back to the iterating mechanism (e.g. foreach) and then continues from, the yield • Functions and methods are automatically return generators when yield is found within them • Generators are just simple ways to implement iterators; without having to duplicate a bunch of boilerplate code • Technically implemented using the Generator class, similar to the magic Closure class. 31

Slide 32

Slide 32 text

Anatomy of Generator Flow 32 function helloGenerator($who) { // First iteration starts here $greeting = ["Hello", "Hi", "Hola", "Bonjour"][rand(0, 3)]; yield $greeting; // Control passed back to foreach // Next iteration starts here yield " "; // Control passed back to foreach // Third iteration starts here yield ucfirst($who) . "!\n"; // Control passed back to foreach } $generator = helloGenerator("world"); // No code is executed yet foreach ($generator as $value) { echo $value; } Output: $RandomGreeting World!\n

Slide 33

Slide 33 text

Anatomy of Generator Flow (Cont.) function MyGenerator() { // First iteration starts here for ($i = 0; $i < 5; $i++) { yield $i; // Control passed back to foreach // Second iteration starts here // The for iteration completes, and goes to the next loop } } 0: 0 1: 5 2: 10 3: 15 4: 20 Output

Slide 34

Slide 34 text

Anatomy of Generator Flow (Cont.) • A return; (note: a return with a value is a parse error) • An exception is thrown (and not caught within the generator) • There are no more yields 34 Generators will return true for valid() until:

Slide 35

Slide 35 text

Sending Data into a Generator

Slide 36

Slide 36 text

Sending data into a Generator • You can send any data into a generator • It is used as an expression, rather than a statement • This also advances the generator • You can send and receive at the “same time” 36 function logger($fileName) { $fileHandle = fopen($fileName, 'a'); while (true) { fwrite($fileHandle, yield . PHP_EOL); } } $logger = logger(__DIR__ . '/log'); $logger->send('Foo'); $logger->send('Bar');

Slide 37

Slide 37 text

Confession Time

Slide 38

Slide 38 text

• My first implementation for the next slide didn’t work how I expected! • Neither did the 2nd, 3rd or 4th... • In fact, I thought I found a bug • Then I created a test case, and thing started to make sense • I still don’t think there’s any reasonable use-case for this functionality! 38

Slide 39

Slide 39 text

Test Case 39 function2gen()2{ 2222$i2=20; 2222while2(true)2{ 22222222file_put_contents("./log",2 222222222222myDate()2.'2'. 222222222222(yield6$i++)2.2'2'2. 222222222222PHP_EOL 22222222,2FILE_APPEND); 2222} } 2 function2myDate()2{ 2222return2date("YPmPd2H:i:s"); } 2 $gen2=2gen(); var_dump($gen=>send("First2Call"));2//#1 sleep(3); var_dump($gen=>send("Second2Call"));2//#2 Log File 2013-02-04 03:39:51 First Call 2013-02-04 03:39:51 Second Call

Slide 40

Slide 40 text

Iteration 1 40

Slide 41

Slide 41 text

Iteration 1 40

Slide 42

Slide 42 text

Iteration 1 40

Slide 43

Slide 43 text

Iteration 1 40

Slide 44

Slide 44 text

Iteration 1 40

Slide 45

Slide 45 text

Iteration 1 40

Slide 46

Slide 46 text

Iteration 1 40

Slide 47

Slide 47 text

Iteration 1 40

Slide 48

Slide 48 text

Iteration 1 40

Slide 49

Slide 49 text

Iteration 1 40

Slide 50

Slide 50 text

Iteration 1 40

Slide 51

Slide 51 text

Iteration 1 40

Slide 52

Slide 52 text

Iteration 1 40

Slide 53

Slide 53 text

Iteration 2 41

Slide 54

Slide 54 text

Iteration 2 41

Slide 55

Slide 55 text

Iteration 2 41

Slide 56

Slide 56 text

Iteration 2 41

Slide 57

Slide 57 text

Iteration 2 41

Slide 58

Slide 58 text

Iteration 2 41

Slide 59

Slide 59 text

Iteration 2 41

Slide 60

Slide 60 text

Iteration 2 41

Slide 61

Slide 61 text

Iteration 2 41

Slide 62

Slide 62 text

Iteration 2 41

Slide 63

Slide 63 text

Sending Exceptions into Generators

Slide 64

Slide 64 text

Sending Exceptions into Generators • Sends an exception into the Generator • Throws the exception at the yield • The actual yielded value isn’t returned 43

Slide 65

Slide 65 text

44 function gen() { echo "Foo\n"; try { while (true) { yield "bat"; } } catch (Exception $e) { echo "Exception: {$e->getMessage()}\n"; } echo "Bar\n"; } $gen = gen(); var_dump($gen->current()); // echos "Foo" and dumps string (3) "bat" $gen->throw(new Exception('Test')); // echos "Exception: Test" and "Bar" var_dump($gen->valid()); // dumps bool(false)

Slide 66

Slide 66 text

Thank You Feedback: http://joind.in/8005 Twitter: @dshafik Email: [email protected] Slides: http://daveyshafik.com/slides