Six years ago, the TYPO3 community was seeking for a framework as a foundation for their new CMS. There was none satisfying their wishlist of features and architecture and thus a new one was made - top notch, built without the pressure of day to day work. In the meantime TYPO3 Flow has become one of the “serious” PHP frameworks which is built on two paradigms: harness the complexity of enterprise applications but at the same time be concise and developer friendly. Or in short: Flow brings back the joy of development in PHP.
This session introduces some of the main features of TYPO3 Flow 2.0 and gives you an idea about how it relates to the well established frameworks on the market.
9. Network Working Group R. Fielding
Request for Comments: 2616 UC Irvine
Obsoletes: 2068 J. Gettys
Category: Standards Track Compaq/W3C
J. Mogul
Compaq
H. Frystyk
W3C/MIT
L. Masinter
Xerox
P. Leach
Microsoft
T. Berners-Lee
W3C/MIT
June 1999
Hypertext Transfer Protocol -- HTTP/1.1
Status of this Memo
This document specifies an Internet standards track protocol for the
Internet community, and requests discussion and suggestions for
improvements. Please refer to the current edition of the "Internet
10. HTTP/1.1 has been designed to allow implementations of applications
/**
that do not depend on knowledge of ranges.
* Represents a HTTP request
*/
4 HTTP Message
class Request extends Message {
4.1 Message Types
/**
* @var string
HTTP messages consist of requests from client to server and responses
*/
from server to client.
protected $method = 'GET';
HTTP-message = Request | Response ; HTTP/1.1 messages
/**
* @var TYPO3FlowHttpUri
Request (section 5) and Response (section 6) messages use the generic
*/
message format of RFC 822 [9] for transferring entities (the payload
protected $uri;
of the message). Both types of message consist of a start-line, zero
or more header fields (also known as "headers"), an empty line (i.e.,
/**
a line with nothing preceding the CRLF) indicating the end of the
* @var TYPO3FlowHttpUri
header fields, and possibly a message-body.
*/
protected $baseUri;
generic-message = start-line
*(message-header CRLF)
/**
CRLF
* @var array
[ message-body ]
*/
start-line = Request-Line | Status-Line
protected $arguments;
14. # set cookie in response:
$response->setCookie(new Cookie('counter', 1));
# on next request, retrieve cookie:
$cookie = $request->getCookie('counter');
18. Domain-Driven Design /**
* A Book
*
A methodology which ... * @FlowScope(“prototy
pe”)
* @FlowEntity
*/
• results in rich domain models class Book {
/**
• provides a common language across * @var string
the project team */
protected $title;
• simplify the design of complex /**
* @var string
applications */
protected $isbn;
/**
Flow is the first PHP framework tailored * @var string
*/
to Domain-Driven Design protected $description
;
/**
* @var integer
*/
protected $price;
19. /**
* A Book
*
* @FlowEntity
*/
class Book {
/**
* The title
* @var string
* @FlowValidate(type="StringLength", options={ "minimum"=1,
*/
protected $title;
/**
* The price
* @var integer
* @FlowValidate(type="NumberRange", options={ "minimum"=1,
*/
protected $price;
20. /**
* Get the Book's title
*
* @return string The Book's title
*/
public function getTitle() {
return $this->title;
}
/**
* Sets this Book's title
*
* @param string $title The Book's title
* @return void
*/
public function setTitle($title) {
$this->title = $title;
}
21. /**
* A repository for Books
*
* @FlowScope("singleton")
*/
class BookRepository extends Repository {
public function findBestSellers() {
...
}
}
22. # Add a book
$bookRepository->add($book);
# Remove a book
$bookRepository->remove($book);
# Update a book
$bookRepository->update($book);
23. # Find one specific book
$book = $bookRepository->findOneByTitle('Lord of the Rings');
# Find multiple books by property
$books = $bookRepository->findByCategory('Fantasy');
# Find books through custom find method
$bestsellingBooks = $bookRepository->findBestSellers();
29. /**
* An action which sends greetings to $name
*
* @param string $name The name to mention
* @return string
*/
public function greetAction($name) {
return "Hello $name!";
}
36. /**
* Displays a list of best selling books
*
* @return void
*/
public function indexAction() {
$books = $this->bookRepository->findBestSellers();
$this->view->assign('books', $books);
}
37. <ul>
<f:for each="{books}" as="book">
<li>{book.title} by {book.author.name}</li>
</f:for>
</ul>
40. /**
* Adds the given new book to the BookRepository
*
* @param AcmeDemoDomainModelBook $newBook
* @return void
*/
public function createAction(Book $newBook) {
$this->bookRepository->add($newBook);
$this->addFlashMessage('Created a new book.');
$this->redirect('index');
}
49. class SomeService {
protected static $instance;
public function getInstance() {
if (self::$instance === NULL) {
self::$instance = new self;
}
return self::$instance;
}
}
class SomeOtherController {
public function action() {
$service = SomeService::getInstance();
…
}
}
50. class ServiceLocator {
protected static $services = array();
public function getInstance($name) {
return self::$service[$name];
}
}
class SomeOtherController {
public function action() {
$service = ServiceLocate::getInstance("SomeService");
…
}
}
51. Flow's take on Dependency Injection
• one of the first PHP implementations
(started in 2006, improved ever since)
• object management for the whole lifecycle of all objects
• no unnecessary configuration if information can be
gathered automatically (autowiring)
• intuitive use and no bad magical surprises
• fast! (like hardcoded or faster)
52. class BookController extends ActionController {
/**
* @var BookRepository
*/
protected $bookRepository;
/**
* @param BookRepository $bookRepository
*/
public function __construct(BookRepository $bookRepository) {
$this->bookRepository = $bookRepository;
}
}
53. class BookController extends ActionController {
/**
* @var BookRepository
*/
protected $bookRepository;
/**
* @param BookRepository $bookRepository
*/
public function injectBookRepository(BookRepository
$bookRepository) {
$this->bookRepository = $bookRepository;
}
}
56. /**
* An action which sends greetings to $name
*
* @param string $name The name to mention
* @return string
*/
public function greetAction($name) {
return "Hello $name!";
}