34. Dependency Injection
• Fixes the problem of static dependencies
• Ignores the problem of static relationships
• Same methods called on injected classes
• No way to introduce new relationships
• Higher overhead, more boilerplate code
35. Dependency Injection
• Various attempts at making DI work better:
• DI Container
• Using dynamic nature of PHP to your
advantage.
46. Design patterns
• Each pattern is only useful in a limited
context
• Layering many design patterns on top of
each other often indicates poor design
choices
• Mis-application arises from trying to run
before you can walk
51. Aspect-Oriented Design
• Separation of concerns
• Domain classes should not know or care about cross-
cutting concerns
• Examples:
• Caching
• Logging
• Access Control, etc.
52. Functional Programming
• Only possible when functions are first-class
citizens
• Referential transparency
• Functional purity
59. <?php
namespace applicationbar;
use lithiumutilString;
use lithiumutilCollection;
class Foo extends lithiumcoreObject {
protected $_classes = array(
'cache' => 'lithiumstorageCache',
'logger' => 'lithiumanalysisLogger'
);
public function __construct(array $config = array()) {
// ...
}
protected function _init() {
// ...
}
}
?>
60. public function __construct(array $config = array())
<?php
public function __construct(array $config = array())
namespace applicationbar;
public function __construct(array $config = array())
use public function __construct(array $config = array())
lithiumutilString;
use lithiumutilCollection;
public function __construct(array $config = array())
class Foo extends lithiumcoreObject {
public function __construct(array $config = array())
protected $_classes = array(
public function'lithiumstorageCache', = array())
'cache' => __construct(array $config
'logger' => 'lithiumanalysisLogger'
public function __construct(array $config = array())
);
public function __construct(array $config = array()) {
// ...
}
public function __construct(array $config = array())
protected function _init() {
public function __construct(array $config = array())
// ...
}
public function __construct(array $config = array())
}
public function __construct(array $config = array())
?>
public function __construct(array $config = array())
61. <?php
namespace applicationbar;
use lithiumutilString;
use lithiumutilCollection;
class Foo extends lithiumcoreObject {
protected $_classes = array(
'cache' => 'lithiumstorageCache',
'logger' => 'lithiumanalysisLogger'
);
public function __construct(array $config = array()) {
// ...
}
protected function _init() {
// ...
}
}
?>
62. <?php
<?php
namespace applicationbar;
class Foo extends lithiumcoreObject
use lithiumutilString; {
use lithiumutilCollection;
protected function _init() {
class Foo extends lithiumcoreObject {
$or = $some->highOverHead($operation);
$or()->otherwise(HARD_TO_TEST)->code();
protected $_classes = array(
'cache' => 'lithiumstorageCache',
}
'logger' => 'lithiumanalysisLogger'
}
);
?>
public function __construct(array $config = array()) {
// ...
}
protected function _init() {
// ...
2
}
}
?>
63. <?php
<?php
namespace applicationbar;
class Foo extends lithiumcoreObject
use lithiumutilString; {
use lithiumutilCollection;
protected function _init() {
class Foo extends lithiumcoreObject {
$or = $some->highOverHead($operation);
$or()->otherwise(HARD_TO_TEST)->code();
protected $_classes = array(
'cache' => 'lithiumstorageCache',
}
'logger' => 'lithiumanalysisLogger'
}
);
?>
public function __construct(array $config = array()) {
// ...
}
protected function _init() {
// ...
2
}
}
$foo = new Foo(array('init' => false));
?>
64. <?php
namespace applicationbar;
use lithiumutilString;
use lithiumutilCollection;
class Foo extends lithiumcoreObject {
protected $_classes = array(
'cache' => 'lithiumstorageCache',
'logger' => 'lithiumanalysisLogger'
);
public function __construct(array $config = array()) {
// ...
}
protected function _init() {
// ...
}
}
?>
65. <?php
namespace applicationbar; 3
use lithiumutilString;
use lithiumutilCollection;
new applicationbarFoo();
// loads app/bar/Foo.php
class Foo extends lithiumcoreObject {
protected $_classes = array(
'cache' => 'lithiumstorageCache',
'logger' => 'lithiumanalysisLogger'
);
public function __construct(array $config = array()) {
// ...
}
protected function _init() {
// ...
}
}
?>
66. <?php
namespace applicationbar;
4
use lithiumutilString;
use lithiumutilCollection;
class Foo extends lithiumcoreObject {
protected $_classes = array(
'cache' => 'lithiumstorageCache',
'logger' => 'lithiumanalysisLogger'
);
public function __construct(array $config = array()) {
// ...
}
protected function _init() {
// ...
}
}
?>
67. <?php
namespace applicationbar;
use lithiumutilString;
use lithiumutilCollection;
class Foo extends lithiumcoreObject {
protected $_classes = array(
'cache' => 'lithiumstorageCache',
'logger' => 'lithiumanalysisLogger' 5
);
public function __construct(array $config = array()) {
// ...
}
protected function _init() {
// ... = $this->_classes['cache'];
$cache
} $cache::write(__CLASS__, $this->_someGeneratedValue());
} }
}
?>
?>
68. <?php
namespace applicationbar;
use lithiumutilString;
use lithiumutilCollection;
class Foo extends lithiumcoreObject {
protected $_classes = array(
'cache' => 'lithiumstorageCache',
'logger' => 'lithiumanalysisLogger' 5
);
$foo = new Foo(array('classes' => array(
public function __construct(array $config = array()) {
'cache' => 'applicationextensionsCache'
// ...
)));
}
protected function _init() {
// ... = $this->_classes['cache'];
$cache
} $cache::write(__CLASS__, $this->_someGeneratedValue());
} }
}
?>
?>
69. <?php
namespace applicationbar;
use lithiumutilString;
use lithiumutilCollection;
class Foo extends lithiumcoreObject {
protected $_classes = array(
'cache' => 'lithiumstorageCache',
'logger' => 'lithiumanalysisLogger'
);
public function __construct(array $config = array()) {
// ...
}
protected function _init() {
// ... = $this->_classes['cache'];
$cache
} $cache::write(__CLASS__, $this->_someGeneratedValue());
} }
}
?>
?>
89. Zoom?
• Performance vs. speed of development is a
series of trade-offs
• Large-scale apps don’t use stock framework
infrastructure, and that’s a good thing
• A generalized framework will never be as
fast as hand-tuned code
90. Zoom!
• Choice is good
• Use native extensions (PECL) whenever
possible.
• Don’t like a class? Change it. At runtime.
• Profiled at every step of the way with
XHProf and XDebug cachegrinds.
106. Databases
• 1st-class support for document-oriented
databases
• MongoDB & CouchDB: production ready
• Relational databases in beta
• Cassandra/Redis/Riak in the works, too
112. Databases
• Adapter based, plugin aware
• Will ship with MySQL, SQLite & PostgreSQL
• SQL Server support via plugin
• Query API
113. The Query API
• Flexible data container
• Allows each backend data store to only worry
about features it implements
• Keeps model API separate from backend data
sources
116. The Query API
• Run simple queries via the Model API
• Build your own complex queries with the
Query API
• Create your own adapter, or drop in a
custom query optimizer
118. Plays nice with others
• Easily load & use libraries from other
frameworks:
• Zend Framework, Solar, Symfony, PEAR,
etc.
• PSR-0 Class-loading standard