Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Can't Miss Features of PHP 5.3 and 5.4

Jeff Carouth
September 27, 2011

Can't Miss Features of PHP 5.3 and 5.4

This presentation highlights features in PHP versions 5.3 and 5.4 that are new to the language and help improve how applications are built. We'll look at lambda functions, traits, closures, and more.

Jeff Carouth

September 27, 2011
Tweet

More Decks by Jeff Carouth

Other Decks in Programming

Transcript

  1. Senior Developer at Texas A&M Author of several magazine articles

    (php|architect) Infrequent (lazy) blogger at carouth.com Lover of progress, innovation, and improvement. Developing with PHP since ~2003 Hi! I am Jeff 2 2
  2. About you? New to PHP? Using PHP 5.3? Used PHP

    yesterday? this afternoon? 3 3
  3. Cleanup autoloading code. That’s about it. __DIR__ usefulness include_once dirname(__FILE__)

    . "/../myfile.php"; include_once __DIR__ . "/../myfile.php"; 7 7
  4. You say semantics? No. There is a difference. 14 (But

    I’ll step off my soapbox for now. Feel free to ping me later.) 14
  5. function() { print 'Hello'; }; $myhello = function() { print

    "Hello!"; }; $myhello(); $myhelloname = function($name) { print "Hello, " . $name . "!"; }; $myhelloname('BCSPHP'); 15 15
  6. $myhelloclosure is said to “close over” the $person variable which

    is within its defined scope. 16 function get_closure($name) { $person = new stdclass(); $person->name = $name; return function() use($person) { print "Hello, " . $person->name . "!"; }; } $myhelloclosure = get_closure('Gernonimo'); $myhelloClosure(); // Output: "Hello, Geronimo!" 16
  7. 18 $fabrics= array( array('color' => 'blue'), array('color' => 'red'), array('color'

    => 'green'), array('color' => 'maroon') ); usort($fabrics, function($a, $b) { return strcmp($a['color'], $b['color']); }); 18
  8. // filter based on dynamic criteria define('MINUTE', 60); define('HOUR', 3600);

    define('DAY', 86400); define('WEEK', 604800); $accounts = array( array('id' => 1, 'lastActivity' => time()-2*WEEK), array('id' => 2, 'lastActivity' => time()-3*DAY), array('id' => 3, 'lastActivity' => time()-45*MINUTE), array('id' => 4, 'lastActivity' => time()-2*HOUR-5*MINUTE), array('id' => 5, 'lastActivity' => time()-5), array('id' => 6, 'lastActivity' => time()-3*MINUTE-20), array('id' => 7, 'lastActivity' => time()-2*WEEK-3*DAY), array('id' => 8, 'lastActivity' => time()-HOUR-33*MINUTE), array('id' => 9, 'lastActivity' => time()-5*MINUTE), ); 19 19
  9. $results = array(); $oneweek = time()-WEEK; foreach ($accounts as $account)

    { if ($account['lastActivity'] > $oneweek) { $results[] = $account; } } $results = array_filter( $accounts, function($account) { return $account['lastActivity'] > time()-WEEK; } ); 20 20
  10. 21 $getfilterfunc = function($lower, $upper = 0) { $lowerTime =

    time() - $lower; $upperTime = time() - $upper; return function($account) use($lowerTime, $upperTime) { return $account['lastActivity'] >= $lowerTime && $account['lastActivity'] <= $upperTime; } } $pastWeekResults = array_filter( $accounts, $getfilterfunc(WEEK)); $previousWeekResults = array_filter( $accounts, $getFilterFunc(2*WEEK, WEEK)); 21
  11. MOAR PRACTICAL Caching. Typically you have a load() and save()

    method. Perhaps even a load(), start(), and end() method. 23 23
  12. class SimpleCache { private $_data = array(); public function load($key)

    { if (!array_key_exists($key, $this->_data)) { return false; } return $this->_data[$key]; } public function save($key, $data) { $this->_data[$key] = $data; } } $cache = new SimpleCache(); if (($data = $cache->load(‘alltags’)) === false) { $service = new ExpensiveLookupClass(); $data = $service->findAllTags(); $cache->save(‘alltags’, $data); } 24 24
  13. class SimpleCacheWithClosures { protected $_data = array(); public function load($key,

    $callback) { if (!array_key_exists($key, $this->_data)) { $this->_data[$key] = $callback(); } return $this->_data[$key]; } } $cache = new SimpleCacheWithClosures(); $service = new ExpensiveLookupClass(); $data = $cache->load('alltags', function() use($service) { return $service->findAllTags(); }); 25 25
  14. 28 class Send { private function _broadcast() { return 'Message

    sent.'; } public function __invoke() { return $this->_broadcast(); } } $send = new Send(); debug_log($send()); 28
  15. Namespaces All the cool languages have them. or perhaps PHP

    just wants to be JAVA with all its package glory after all, we do have PHARs 29 29
  16. Namespace Benefits Organization. Both file and code. Reduce conflicts with

    other libraries. Shorten class names. Readability. 32 32
  17. define("LIBRARYDIR", __DIR__); class Tamu_Cas_Adapter { function auth() { } }

    function tamu_cas_create_client() { return new Tamu_Http_Client(); } namespace Tamu\Cas; use Tamu\Http\Client as HttpClient; const LIBRARYDIR = __DIR__; class Adapter { function auth() { } } function create_client() { return new HttpClient(); } 33 33
  18. Namespace organization namespace Tamu; In /path/to/Tamu.php: namespace Tamu\Dmc; In /path/to/Tamu/Dmc.php

    namespace Tamu\Auth\Adapter; class Cas { } In /path/to/Tamu/Auth/Adapter/Cas.php 34 34
  19. Conflict Resolution namespace My; function str_split($string, $split_len = 2) {

    return "Nope. I don't like to split strings."; } $splitstr = str_split('The quick brown fox'); // $splitstr = "Nope. I don't like to split strings." $splitstr = \str_split('The quick brown fox'); // $splitstr = array('T', 'h', 'e', ..., 'o', 'x'); 35 35
  20. Class name shortening class Zend_Application_Resource_Cachemanager extends Zend_Application_Resource_ResourceAbstract { //... }

    namespace Zend\Application\Resource; class Cachemanager extends ResourceAbstract { //... } 36 36
  21. Readability by Namespace require_once "Zend/Http/Client.php"; $client = new Zend_Http_Client(); use

    Zend\Http; $client = new Client(); use Zend\Http\Client as HttpClient; $httpClient = new HttpClient(); 37 37
  22. PHP 5.4 alpha3 was used for demos beta going to

    be packaged on Sep 14 (source:php-internals) 39 39
  23. New Features Closures support $this keyword Short Array Syntax Array

    Dereferencing Traits (Debug webserver) 40 40
  24. Closures and $this class HelloWorldPrinter { public function __construct($name) {

    $this->_name = $name; } public function getPrinter() { return function() { return "Hello, " . $this->_name . "!"; }; } } $instance = new HelloWorldPrinter('BCSPHP'); $printer = $instance->getPrinter(); echo $printer(); 41 41
  25. Prior to PHP 5.4 Fatal error: Using $this when not

    in object context in / Users/jcarouth/Documents/code-bcsphp-092011/ php54closurethis.php on line 14 PHP 5.4.0alpha3 (built Aug 5, 2011) Hello, BCSPHP! 42 42
  26. Short Array Syntax Saving you a few keystrokes and compute

    cycles when switching from JavaScript 43 43
  27. //empty array $arr = []; //simple array $arr = [1,

    2, 3]; //"dictionary" array $arr = ['name' => 'jeff', 'language' => 'php']; //multi-dimensional $arr = [['orange', 'blue'], ['black', 'gold']]; 45 45
  28. $array = array(1, 2, 3); $dereference = *$array; Sorry, no

    pointers. All the upset C++ wizards, go have some pizza. 47 47
  29. class UserDataSource { public function getDataForJeff() { return [ 'id'

    => 1, 'name' => 'Jeff Carouth', 'isAdmin' => true, ]; } } $jeff = $store->getDataForJeff(); if ($jeff['isAdmin'] === true) { //give him access to all the things } if ($store->getDataForJeff()['isAdmin']) { //shorter...but be mindful } PHP <= 5.3 PHP >= 5.4 48 48
  30. 49 Pitfalls Dereferencing a non-existent key produces a NOTICE. If

    the function does not return an array, unexpected behavior. 49
  31. Definition 51 Traits is a mechanism for code reuse in

    single inheritance languages such as PHP. A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies. The semantics of the combination of Traits and classes is defined in a way, which reduces complexity and avoids the typical problems associated with multiple inheritance and Mixins. 51
  32. 52 A bit much to take in The important bit

    is traits allow developers like you to increase code reuse and get around limitations of single- inheritance. 52
  33. 54 class SearchController { public function findBook(Book $b) { }

    private function log($message) { error_log($message); } } class AdminController { public function grant(User $u, Privilege $p) { } private function log($message) { error_log($message); } } 54
  34. 55 trait Logging { private function log($message) { error_log($message); }

    } class SearchController { use Logging; } class AdminController { use Logging; } 55
  35. 56 namespace TamuTimes\Models; class Story { public function setDataStore($store) {

    $this->_ds = $store; } public function getDataStore() { return $this->_ds; } } class User { public function setDataStore($store) { $this->_ds = $store; } public function getDataStore() { return $this->_ds; } } 56
  36. 57 namespace Tamu\Dmc\App; trait DataStore { public function setDataStore($store) {

    $this->_ds = $store; } public function getDataStore() { return $this->_ds; } } namespace TamuTimes\Models; use Tamu\Dmc\App\DataStore; class Story { use DataStore; } class User { use DataStore; } 57
  37. 58 namespace BCSPHP; trait MessageBroadcast { public function sendMessage() {

    } abstract private function _formatMessage(); } class MeetingNotification { use MessageBroadcast; private function _formatMessage() { return "Notice: BCSPHP Meeting " . $this->_date; } } 58
  38. 59 Traits are “just compiler assisted copy and paste.” -

    Stefan Marr, PHP Internals Mailing List, Nov 2010 59
  39. Caveat 62 Routing must be handled with a separate router.php

    script. if (file_exists(__DIR__ . '/' . $_SERVER['REQUEST_URI'])) { return false; // serve the requested resource as-is. } else { include_once 'index.php'; } if (php_sapi_name() == 'cli-server') { /* route static assets and return false */ } 62
  40. What you can do now: 63 (more like what you

    should do) Test PHP 5.4 — http://qa.php.net Run make test TEST YOUR APPS against PHP 5.4-alpha/beta/RC 63
  41. Resources Enygma’s PHP 5.3 example code http://bit.ly/q9Eu36 Elazar’s benchmarks of

    SPL features in PHP 5.3 http://bit.ly/nKsbvQ PHP documentation on the built-in web server http://bit.ly/rc26l0 66 66