1. lithium
use lithiumcoreObject;
Friday, February 17, 12 1
2. the agenda
• introductions
• Lithium’s goals
• the framework today
• examples!
• poster children
• it’s all over
Friday, February 17, 12 2
3. introductions
var_dump($this);
Friday, February 17, 12 3
4. introduction - john anderson
• first web related work was in 1995 (perl/html/js)
• b.s. in information tech @ byu
• cakephp core team
• director of technology at (media)rain
• lithium core team, founding member
• software engineer, adobe systems
Friday, February 17, 12 4
5. introduction - lithium
• started as some test scripts on early 5.3 builds
• namespacing, closures, lsb, __magic(), PHAR
• released as “cake3” in july ’09
• released as “lithium” (li3) in oct ’09
• based on 5 years of learning on a high-adoption
framework (cakephp).
Friday, February 17, 12 5
6. lithium today
new lithiumcoreObject(time());
Friday, February 17, 12 6
7. lithium today
• 130 plugins on github
• 350 commits from 40 contributors since 0.10
• 60 commits to the manual since 0.10 (woot)
• 250 closed github issues
• latest additions:
• csrf protection, cookie signing, error handler, ...
Friday, February 17, 12 7
8. goals
abstract class Lithium {}
Friday, February 17, 12 8
9. lithium sucks
• Not like this -->
Friday, February 17, 12 9
10. lithium sucks
• Like this:
• there’s code in there you don’t use.
• complexity overhead.
• you didn’t write it.
• it’s a framework.
Friday, February 17, 12 10
11. we try to suck less
• Do things the php way
• no paradigm/pattern hubris
• great architecture
• as simple as possible
Friday, February 17, 12 11
12. the php way
• example: sf dependency injection (Zend mailer)
• Starts like this:
1 <?php
2
3 $transport = new Zend_Mail_Transport_Smtp('smtp.gmail.com', array(
4 'auth' => 'login',
5 'username' => 'foo',
6 'password' => 'bar',
7 'ssl' => 'ssl',
8 'port' => 465,
9 ));
10
11 $mailer = new Zend_Mail();
12 $mailer->setDefaultTransport($transport);
* examples taken from http://components.symfony-project.org/dependency-injection/documentation
Friday, February 17, 12 12
13. the php way
• ends up like this:
• (This doesn’t include the xml service descriptor)
1 <?php
2
3 class Container extends sfServiceContainer
4 {
5 static protected $shared = array();
6
7 protected function getMailTransportService()
8 {
9 return new Zend_Mail_Transport_Smtp('smtp.gmail.com', array(
10 'auth' => 'login',
11 'username' => $this['mailer.username'],
12 'password' => $this['mailer.password'],
13 'ssl' => 'ssl',
14 'port' => 465,
15 ));
16 }
17
18 protected function getMailerService()
19 {
20 if (isset(self::$shared['mailer']))
21 {
22 return self::$shared['mailer'];
23 }
24
25 $class = $this['mailer.class'];
26
27 $mailer = new $class();
28 $mailer->setDefaultTransport($this->getMailTransportService());
29
30 return self::$shared['mailer'] = $mailer;
31 }
32 }
Friday, February 17, 12 13
14. the php way
1 <?php
2
3 mail(...);
Friday, February 17, 12 14
20. Unified simple construction
• objects use a unified constructor
• single $config param, automatically sets whitelisted
properties
• automatically calls init
• allows for very light construction
• leaves init to its own (optional!) method
Friday, February 17, 12 20
21. unified simple construction
1 <?php
2 namespace app/extensions;
3
4 use lithiumnethttpService;
5
6 class Foo extends lithiumcoreObject {
7 public $service;
8
9 public function __construct(array $config = array()) {
10 $defaults = array(
11 'foo' => 'bar'
12 );
13 parent::__construct($config + $defaults);
14 }
15
16 public function _init() {
17 parent::_init();
18 $this->service = new Service();
19 }
20
21 public function baz() {
22 echo $this->_config['foo'];
23 }
24 }
25 ?>
Friday, February 17, 12 21
23. Aop filters
• allow you to easily wrap your logic before or after
core class methods
• original logic is wrapped in a closure
• all logic is chained and run in sequence
• filters allow you to inject logic into the chain
Friday, February 17, 12 23
24. Aop filters
• no more before+x, after+x in the api
• allows many more methods to be filterable
• no more stomping on callbacks in extended classes
• allows you to inject logic into the chain multiple times,
or from different places
• much easier to address and organize “cross-cutting”
concerns
Friday, February 17, 12 24
25. model filter example
1 <?php
2
3 Users::applyFilter('save', function($self, $params, $chain) {
4 // For newly created users:
5 if (!$params['entity']->exists() && $params['entity']->validates()) {
6
7 // Hash new user passwords and set 'created' date
8 $params['entity']->password = Password::hash($params['entity']->password);
9 $params['entity']->created_at = new MongoDate();
10 $params['entity']->created_by = $user['email'];
11 }
12
13 // Set modified info
14 $params['entity']->modified_at = new MongoDate();
15 $params['entity']->modified_by = $user['email'];
16
17 return $chain->next($self, $params, $chain);
18 });
Friday, February 17, 12 25
28. dependency injection
• these aren’t the droids you’re looking for
• long story short - allows you to pick and choose your
dependencies at runtime rather than at compile time
• For instance, rather than hard-coding a logger class
that a user model will use, allow di to switch that out
at runtime
• i.e. = woo now we gots growl notifications
Friday, February 17, 12 28
29. dependency injection
• remember the di example we started with?
• the logic
• and its container
• and its service container parent
• and its xml service description
• li3 uses class properties instead.
Friday, February 17, 12 29
30. di made simple
1 <?php
2
3 class Service extends lithiumcoreObject {
4 protected $_classes = array(
5 'request' => 'lithiumnethttpRequest',
6 'response' => 'lithiumnethttpResponse',
7 );
8 }
9
10 $service = new Service(array('classes' => array(
11 'request' => 'foobarRequest'
12 )))
Friday, February 17, 12 30
31. adaptable
• allows for configuration of main class purposes
• adaptable classes:
• auth (form, http)
• cache (memcached, apc, file...)
• logger (growl, syslog, file...)
• session (cookie, php, memory...)
Friday, February 17, 12 31
32. adaptable
• consistent class configuration
1 <?php
2
3 use lithiumstorageCache;
4
5 Cache::config(array(
6 'default' => array( // configuration name
7 'development' => array( // environment name
8 'adapter' => 'Apc',
9 ),
10 'production' => array( // woo another environment name
11 'adapter' => 'Memcached',
12 'servers' => array('127.0.0.1'), // custom vars handed to adapter constructor
13 )
14 )
15 ));
Friday, February 17, 12 32
33. poster children
$this->horn->toot();
Authority::appealTo();
Friday, February 17, 12 33
34. • sean coates
• ed finkler
• chris shiflett
• mongodb
gimmebar
Friday, February 17, 12 34
35. • chris shiflett
• Andrei Zmievski
totsy
Friday, February 17, 12 35
36. Quotes
“After looking at Lithium, I’ve come to
realize how far ahead it is compared to
other frameworks from a technologist’s
point of view.”
—David Coallier, President of PEAR, CTO for Orchestra.IO (now Engine Yard)
Friday, February 17, 12 36
37. Quotes
“It’s the F****** epiphany of modern!”
—Helgi Þormar Þorbjörnsson, PEAR Core DEV
Friday, February 17, 12 37
38. Quotes
“I believe the future is in lithium. Give it
time to grow, and the developers behind
it are awesome.”
—Fahad Ibnay Heylaal, Creator Croogo (CakePHP) CMS
Friday, February 17, 12 38
40. contact Me
@raisinbread
anderson.johnd@gmail.com
learn more
@unionofrad
github.com/UnionOfRAD
lithify.me
#li3 on Freenode
Friday, February 17, 12 40