PHP 5.3 and Lithium: the most rad php framework

18,304 views
18,143 views

Published on

Presentation given to the Orange County PHP meetup on Feb 24 2010. The presentation covers the new features in php 5.3 and goes on to show how they are used in Lithium, the most rad php framework.

Published in: Technology
2 Comments
25 Likes
Statistics
Notes
No Downloads
Views
Total views
18,304
On SlideShare
0
From Embeds
0
Number of Embeds
2,420
Actions
Shares
0
Downloads
214
Comments
2
Likes
25
Embeds 0
No embeds

No notes for slide

PHP 5.3 and Lithium: the most rad php framework

  1. 1. Wednesday, February 24, 2010
  2. 2. PHP 5.3 Wednesday, February 24, 2010
  3. 3. Why? • Speed & Memory • Phar • Namespaces • ext/intl • Anonymous Functions • ext/fileinfo • Late Static Binding • ext/sqlite3 • Syntax enhancements • mysqlnd • SPL Wednesday, February 24, 2010
  4. 4. Speed & Memory Drupal 20% faster Qdig 2% faster typo3 30% faster wordpress 15% faster xoops 10% faster http://news.php.net/php.internals/36484 http://sebastian-bergmann.de/archives/745-Benchmark-of-PHP-Branches-3.0-through-5.3-CVS.html gc_enable() : New Garbage Collector Wednesday, February 24, 2010
  5. 5. Namespaces http://php.net/manual/en/language.namespaces.php • Autoloading made easy • lithiumcoreLibraries • li3_docscontrollersBrowserController • http://groups.google.com/group/php- standards/web/psr-0-final-proposal Wednesday, February 24, 2010
  6. 6. Namespaces Example <?php namespace app; use appmodelsPost; class PostsController extends lithiumactionController { public function index() { $posts = Post::all(); return compact(‘posts’); } } ?> Wednesday, February 24, 2010
  7. 7. Autoloading http://groups.google.com/group/php-standards/web/psr-0-final-proposal <?php function __autoload($className) { $className = ltrim($className, ''); $fileName = ''; $namespace = ''; if ($lastNsPos = strripos($className, '')) { $namespace = substr($className, 0, $lastNsPos); $className = substr($className, $lastNsPos + 1); $fileName = str_replace('', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR; } $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; require $fileName; } ?> Wednesday, February 24, 2010
  8. 8. Anonymous Functions http://php.net/manual/en/functions.anonymous.php • Lambda • assigned to a variable • useful for recursion and multiple calls • Closure • added as a method parameter • use() the parent scope Wednesday, February 24, 2010
  9. 9. Lambda Example <?php $cube = function ($value) { return ($value * $value * $value); }; $result = array_map($cube, array(1, 2, 3)); var_dump($result); /* array 0 => int 1 1 => int 8 2 => int 27 */ ?> Wednesday, February 24, 2010
  10. 10. Another Lambda $multiply = function ($value, $times) use (&$multiply) { return ($times > 0) ? $multiply($value * $value, --$times) : $value; }; var_dump($multiply(2, 3)); /* int 256 */ Wednesday, February 24, 2010
  11. 11. Closure Example <?php $data = 'string'; $result = array_filter(array(1, 2, 'string'), function ($value) use ($data) { return ($value !== $data); }); var_dump($result); /* array 0 => int 1 1 => int 2 */ ?> Wednesday, February 24, 2010
  12. 12. Crazy Example <?php function Y($F) { return current(array(function($f) { return $f($f); }))->__invoke(function($f) use ($F) { return $F(function($x) use ($f) { return $f($f)->__invoke($x); }); }); } $factorial = Y(function($fact) { return function($n) use ($fact) { return ($n <= 1) ? 1 : $n * $fact($n - 1); }; }); var_dump($factorial(6)); /* int 720 */ ?> Wednesday, February 24, 2010
  13. 13. Why Static? • Promotes proper application design • Stateless • Easier to access Wednesday, February 24, 2010
  14. 14. Late Static Binding http://php.net/lsb <?php class A { public static function who() { return __CLASS__; } public static function test() { return static::who(); } } class B extends A { public static function who() { return __CLASS__; } } $result = B::test(); var_dump($result); /* string 'B' (length=1) */ Wednesday, February 24, 2010
  15. 15. Standard PHP Library (SPL) http://us.php.net/manual/en/book.spl.php • spl_autoload_register() • Iterators • Exceptions • File Handling • Observer/Subject • Stack, Queue, Heap, ObjectStorage Wednesday, February 24, 2010
  16. 16. Syntax Enhancements http://php.net/manual/en/language.oop5.magic.php • PHP 5 < 5.3 • PHP 5.3 • __set()/__get() • __callStatic() • __isset()/__unset() • __invoke() • __call() • ?: Wednesday, February 24, 2010
  17. 17. Phar • PHP archives • includable (include 'phar:///path/to/myphar.phar/file.php') • stream accessible • distributable Wednesday, February 24, 2010
  18. 18. ext/intl • Collator • Locale • IntlDateFormatter • NumberFormatter Wednesday, February 24, 2010
  19. 19. ext/fileinfo <?php $info = new finfo(FILEINFO_MIME); $result = $info->file(__FILE__); var_dump($result); /* string 'text/x-php; charset=us-ascii' (length=28) */ $result = finfo_file(finfo_open(FILEINFO_MIME), __FILE__); var_dump($result); /* string 'text/x-php; charset=us-ascii' (length=28) */ ?> Wednesday, February 24, 2010
  20. 20. ext/sqlite3 • SQLite is a in-process library that implements a self-contained, serverless, zero-configuration, transactional SQL database engine (http://www.sqlite.org/ about.html) • A more compact format for database files. • Support for both UTF-8 and UTF-16 text. • Manifest typing and BLOB support. • New API via Sqlite3 class or sqlite3 functions Wednesday, February 24, 2010
  21. 21. mysqlnd • mysql native driver • faster • easier to compile • transparent client, same old mysql/mysqli Wednesday, February 24, 2010
  22. 22. Lithium the most rad php framework Wednesday, February 24, 2010
  23. 23. In Lithium • Namespaces • Anonymous Functions • Late Static Binding • Syntax Enhancements • SPL • Phar • Sqlite3 Wednesday, February 24, 2010
  24. 24. Lithium Namespaces • action • security • analysis • storage • console • template • core • test • g11n • tests • net • util Wednesday, February 24, 2010
  25. 25. Namespace Example <?php namespace appextensionshelper; class Form extends lithiumtemplatehelperForm { public function config(array $config = array()) { .... } } Wednesday, February 24, 2010
  26. 26. Anonymous Functions Example <?php Validator::add('role', function ($value, $format, $options) { return (in_array($value, array('admin', 'editor', 'user'))); }); ?> Wednesday, February 24, 2010
  27. 27. LSB Example <?php namespace lithiumcore; class StaticObject { ... } <?php ?> namespace lithiumdata; class Model extends lithiumcoreStaticObject { ... } ?> <?php namespace appmodels; class Post extends lithiumdataModel { } ?> Wednesday, February 24, 2010
  28. 28. __callStatic <?php namespace lithiumdata; class Model extends lithiumcoreStaticObject { public static function __callStatic($method, $params) { ... } ?> <?php namespace appcontrollers use appmodelsPost; class PostsController extends lithiumactionController { public function index() { $posts = Post::all(); return compact('posts') } } ?> Wednesday, February 24, 2010
  29. 29. __invoke <?php namespace lithiumaction; class Controller extends lithiumcoreObject { public function __invoke($request, $dispatchParams, array $options = array()) { ... } } <?php ?> namespace lithiumaction; class Dispatcher extends lithiumcoreStaticObject { protected static function _call($callable, $request, $params) { ... if (is_callable($callable = $params['callable'])) { return $callable($params['request'], $params['params']); } throw new Exception('Result not callable'); ... } } ?> Wednesday, February 24, 2010
  30. 30. SPL Iterators <?php protected function _cleanUp($path = null) { $path = $path ?: LITHIUM_APP_PATH . '/resources/tmp/tests'; $path = $path[0] !== '/' ? LITHIUM_APP_PATH . '/resources/tmp/' . $path : $path; if (!is_dir($path)) { return; } $dirs = new RecursiveDirectoryIterator($path); $iterator = new RecursiveIteratorIterator($dirs, RecursiveIteratorIterator::CHILD_FIRST); foreach ($iterator as $item) { if ($item->getPathname() === "{$path}/empty") continue; ($item->isDir()) ? rmdir($item->getPathname()) : unlink($item->getPathname()); } } ?> Wednesday, February 24, 2010
  31. 31. SPL Interfaces <?php /* * @link http://us.php.net/manual/en/class.arrayaccess.php * @link http://us.php.net/manual/en/class.iterator.php * @link http://us.php.net/manual/en/class.countable.php */ class Collection extends lithiumcoreObject implements ArrayAccess, Iterator, Countable { ... } ?> Wednesday, February 24, 2010
  32. 32. SPL autoloader <?php namespace lithiumcore; class Libraries { ... public static function add($name, $config = array()) { ... if (!empty($config['loader'])) { spl_autoload_register($config['loader']); } ... } ... } ?> Wednesday, February 24, 2010
  33. 33. Phar <?php namespace lithiumconsolecommand; use Phar; class Library extends lithiumconsoleCommand { public function archive() { .... $archive = new Phar("{$path}.phar"); $from = $this->_toPath($from); $result = (boolean) $archive->buildFromDirectory($from, $this->filter); ... $archive->compress(Phar::GZ); return true; } } ?> Wednesday, February 24, 2010
  34. 34. Sqlite3 <?php Connections::add('default', array( 'type' => 'database', 'adapter' => 'Sqlite3', 'database' => LITHIUM_APP_PATH . '/resources/db/sqlite.db' )); ?> Wednesday, February 24, 2010
  35. 35. By Lithium • Simple, Uniform API • Unified Constructor • Adaptable • Filters (Aspect Oriented Programming) • $_classes (Dependency Injection) • Collections Wednesday, February 24, 2010
  36. 36. Simple Uniform API • logical namespaces and classes • simple method names • <= 3 params per method • $config • $options Wednesday, February 24, 2010
  37. 37. Unified Constructor • $config • always an array • check for $_autoConfig • _init() and __init() Wednesday, February 24, 2010
  38. 38. Adaptable • securityAuth • storageSession • storageCache • g11nCatalog • dataConnections • analysisLogger Wednesday, February 24, 2010
  39. 39. Filters • Aspect Oriented Programming secondary or supporting functions are isolated from the main program's business logic...increase modularity by allowing the separation of cross-cutting concerns... (http://en.wikipedia.org/wiki/Aspect-oriented_programming) • modify core functionality without extending a class • define your own callbacks • @filter Wednesday, February 24, 2010
  40. 40. Routes Filter <?php use lithiumactionDispatcher; Dispatcher::applyFilter('run', function($self, $params, $chain) { include __DIR__ . '/routes.php'; return $chain->next($self, $params, $chain); }); ?> Wednesday, February 24, 2010
  41. 41. Asset Filter <?php use lithiumactionDispatcher; use lithiumcoreLibraries; use lithiumnethttpMedia; Dispatcher::applyFilter('_callable', function($self, $params, $chain) { list($plugin, $asset) = explode('/', $params['request']->url, 2) + array("", ""); if ($asset && $library = Libraries::get($plugin)) { $asset = "{$library['path']}/webroot/{$asset}"; if (file_exists($asset)) { return function () use ($asset) { $info = pathinfo($asset); $type = Media::type($info['extension']); header("Content-type: {$type['content']}"); return file_get_contents($asset); }; } } return $chain->next($self, $params, $chain); }); ?> Wednesday, February 24, 2010
  42. 42. Xhprof Filter <?php use lithiumactionDispatcher; Dispatcher::applyFilter('run', function($self, $params, $chain) { xhprof_enable(); $data = $chain->next($self, $params, $chain); $xhprof_data = xhprof_disable(); $XHPROF_ROOT = '/usr/local/php/5.3.1/lib/xhprof'; include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_lib.php"; include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_runs.php"; $xhprof_runs = new XHProfRuns_Default(); $run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_lithium"); return $data; }); ?> Wednesday, February 24, 2010
  43. 43. Save Filter <?php namespace appmodels; class Paste extends lithiumdataModel { public static function __init(array $options = array()) { parent::__init($options); static::applyFilter('save', function($self, $params, $chain) { $document = $params['record']; if (!$document->id) { $document->created = date('Y-m-d h:i:s'); } if (!empty($params['data'])) { $document->set($params['data']); } $document->parsed = $self::parse($document->content, $document->language); $document->preview = substr($document->content, 0, 100); $document->modified = date('Y-m-d h:i:s'); $params['record'] = $document; return $chain->next($self, $params, $chain); }); } } ?> Wednesday, February 24, 2010
  44. 44. $_classes • Dependency Injection a technique for supplying an external dependency (i.e. a reference) to a software component - that is, indicating to a part of a program which other parts it can use... (http://en.wikipedia.org/wiki/Dependency_injection) • modify core functionality without extending a class Wednesday, February 24, 2010
  45. 45. $_classes Example <?php namespace lithiumconsole; class Library extends lithiumconsoleCommand { ... protected $_classes = array( 'service' => 'lithiumnethttpService', 'response' => 'lithiumconsoleResponse' ); ... } ?> Wednesday, February 24, 2010
  46. 46. $_classes Example <?php namespace lithiumtestscasesconsole; use lithiumconsoleRequest; class LibraryTest extends lithiumtestUnit { ... public function setUp() { ... $this->classes = array( 'service' => 'lithiumtestsmocksconsolecommandMockLibraryService', 'response' => 'lithiumtestsmocksconsoleMockResponse' ); ... } ... public function testArchiveNoLibrary() { ... $app = new Library(array( 'request' => new Request(), 'classes' => $this->classes )); $expected = true; $result = $app->archive(); $this->assertEqual($expected, $result); } ... } ?> Wednesday, February 24, 2010
  47. 47. Collections • lithiumutilCollection • lithiumdataCollection • lithiumdatacollectionRecordSet • lithiumdatacollectionDocument • lithiumtestGroup Wednesday, February 24, 2010
  48. 48. Collections Example <?php use lithiumutilCollection; $coll = new Collection(array('items' => array(0, 1, 2, 3, 4))); $coll->first(); // 1 (the first non-empty value) $coll->current(); // 0 $coll->next(); // 1 $coll->next(); // 2 $coll->next(); // 3 <?php $coll->prev(); // 2 $coll->rewind(); // 0 use lithiumtestGroup; $coll->each(function($value) { return $value + 1; $group = new Group(array('items' => array( }); 'lithiumtestscasescoreLibraries', $coll->to('array'); // array(1, 2, 3, 4, 5) 'lithiumtestscasescoreObject', )) ?> $resul = $group->tests()->run(); ?> Wednesday, February 24, 2010
  49. 49. More Lithium • Integrated Test Suite for fast TDD • Command Line Framework • Document Based Data Sources • Object based Record Sets with access to non static model methods • Transparent content type rendering Wednesday, February 24, 2010
  50. 50. Still More Lithium • Automatic output escaping • Http Services • g11n for internationalized applications • Authentication • Session/Cookie Handling • Authorization (1.0) Wednesday, February 24, 2010
  51. 51. Even More Lithium • Validator • Logging • Debugger • Parser • Inspector • Sockets Wednesday, February 24, 2010
  52. 52. Lithium Integrations • Use 3rd party libraries • Easy to add with Libraries class • Especially simple when PSR-0 is followed • Access classes in a standard way Wednesday, February 24, 2010
  53. 53. Using Zend http://rad-dev.org/lithium/wiki/guides/using/zend <?php Libraries::add("Zend", array( "prefix" => "Zend_", 'path' => '/htdocs/libraries/Zend/trunk/library/Zend', "includePath" => '/htdocs/libraries/Zend/trunk/library', "bootstrap" => "Loader/Autoloader.php", "loader" => array("Zend_Loader_Autoloader", "autoload"), "transform" => function($class) { return str_replace("_", "/", $class) . ".php"; } )); ?> <?php namespace appcontrollers; use Zend_Mail_Storage_Pop3; class EmailController extends lithiumactionController { public function index() { $mail = new Zend_Mail_Storage_Pop3(array( 'host' => 'localhost', 'user' => 'test', 'password' => 'test' )); return compact('mail'); } } ?> Wednesday, February 24, 2010
  54. 54. Plugins • namespaces allow for a true plugin system • modify application with filters • add extensions • share your handy work Wednesday, February 24, 2010
  55. 55. Some Plugins • li3_docs • li3_oauth • li3_bot • li3_doctrine • li3_lab Wednesday, February 24, 2010
  56. 56. Wednesday, February 24, 2010
  57. 57. lithium_qa • http://rad-dev.org/lithium/wiki/standards • Check syntax of your code • Shows rules violations in your code • Automate the process with SCM hooks Wednesday, February 24, 2010
  58. 58. Lithium the most rad php framework • http://lithify.me • http://rad-dev.org/lithium/wiki • http://www.ohloh.net/p/lithium • http://twitter.com/UnionOfRAD • irc://irc.freenode.net/#li3 • http://search.twitter.com/search?q=%23li3 Wednesday, February 24, 2010

×