applications for the enterprise with php (cpeurope)

91
Applications for the Enterprise with PHP Solve complex problems with excellence and get back the joy of software development.

Upload: robert-lemke

Post on 19-May-2015

3.949 views

Category:

Technology


2 download

DESCRIPTION

Full video of this presentation: http://www.youtube.com/watch?v=iocO70tE-B4&feature=youtube_gdata_player For a long time PHP was not really considered for enterprise projects with a complex business logic. Other programming languages and their respective frameworks have a much longer history in tackling extensive domains in a reliable manner. With the release of PHP 5 and its successor versions the game changed significantly. True object-orientation and design patterns became en vogue among PHP developers. Shortly before that time, the TYPO3 Open Source project decided to start over and develop FLOW3, a new application framework which introduces successful patterns and techniques from other programming language into PHP. In this session you'll learn about FLOW3's approach is to deliver a whole-in-one concept for modern programming techniques and guiding developers to write excellent code. It introduces programming techniques such as Aspect-Oriented Programming and Domain-Driven Design to PHP, which were previously unseen in PHP projects. Finally you'll get an overview of FLOW3's key features and a good idea about if FLOW3 might be suitable for your next project.

TRANSCRIPT

Page 1: Applications for the Enterprise with PHP (CPEurope)

Applications for theEnterprise with PHP Solve complex problems with excellenceand get back the joy of software development.

Page 2: Applications for the Enterprise with PHP (CPEurope)

project founder of FLOW3 / TYPO3 Phoenix

co-founder of the TYPO3 Association

coach, coder, consultant

36 years old

lives in Lübeck, Germany

1 wife, 2 daughters, 1 espresso machine

likes drumming

@robertlemke

Page 3: Applications for the Enterprise with PHP (CPEurope)

PHP

Page 4: Applications for the Enterprise with PHP (CPEurope)

Java

Page 5: Applications for the Enterprise with PHP (CPEurope)

is_php_a_good_language() ?TRUE : FALSE;

Page 6: Applications for the Enterprise with PHP (CPEurope)

inconsistent($needle, $haystack);functional_toolbox::$lackingElegance;

Page 7: Applications for the Enterprise with PHP (CPEurope)

The programming languageis rarely the problem.

Page 8: Applications for the Enterprise with PHP (CPEurope)

I♥PHP

Page 9: Applications for the Enterprise with PHP (CPEurope)

I ���� PHP

Page 10: Applications for the Enterprise with PHP (CPEurope)

Let me focus on the fun part

Page 11: Applications for the Enterprise with PHP (CPEurope)
Page 12: Applications for the Enterprise with PHP (CPEurope)

10 Features

Page 13: Applications for the Enterprise with PHP (CPEurope)

Controller1

Page 14: Applications for the Enterprise with PHP (CPEurope)

modelviewcontroller

Page 15: Applications for the Enterprise with PHP (CPEurope)
Page 16: Applications for the Enterprise with PHP (CPEurope)

<?phpnamespace Acme\Demo\Controller;use TYPO3\FLOW3\Mvc\Controller\ActionController;

class HelloWorldController extends ActionController {

/** * @return string */ public function greetAction() { return '¡Hola mundo!'; }

}

Page 17: Applications for the Enterprise with PHP (CPEurope)

TEXT HERE

Page 18: Applications for the Enterprise with PHP (CPEurope)

<?phpnamespace Acme\Demo\Controller;use TYPO3\FLOW3\Mvc\Controller\ActionController;

class HelloWorldController extends ActionController {

/** * @param string $name The name to mention * @return string */ public function greetAction($name) { return "¡Hola $name!"; }

}

Page 19: Applications for the Enterprise with PHP (CPEurope)
Page 20: Applications for the Enterprise with PHP (CPEurope)
Page 21: Applications for the Enterprise with PHP (CPEurope)

<?phpnamespace Acme\Demo\Controller;use TYPO3\FLOW3\Mvc\Controller\ActionController;use Acme\Demo\Domain\Model\Person;

class HelloWorldController extends ActionController {

/** * @param Acme\Demo\Domain\Model\Person $person * @return string */ public function greetAction(Person $person) { return "¡Hola " . $person->getName() . "!"; }

Page 22: Applications for the Enterprise with PHP (CPEurope)
Page 23: Applications for the Enterprise with PHP (CPEurope)

HTTP2

Page 24: Applications for the Enterprise with PHP (CPEurope)

Network Working Group R. FieldingRequest for Comments: 2616 UC IrvineObsoletes: 2068 J. GettysCategory: 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 Official Protocol Standards" (STD 1) for the standardization state and status of this protocol. Distribution of this memo is unlimited.

Copyright Notice

Copyright (C) The Internet Society (1999). All Rights Reserved.

Abstract

The Hypertext Transfer Protocol (HTTP) is an application-level protocol for distributed, collaborative, hypermedia information systems. It is a generic, stateless, protocol which can be used for many tasks beyond its use for hypertext, such as name servers and distributed object management systems, through extension of its request methods, error codes and headers [47]. A feature of HTTP is the typing and negotiation of data representation, allowing systems to be built independently of the data being transferred.

HTTP has been in use by the World-Wide Web global information initiative since 1990. This specification defines the protocol referred to as "HTTP/1.1", and is an update to RFC 2068 [33].

Page 25: Applications for the Enterprise with PHP (CPEurope)

HTTP/1.1 has been designed to allow implementations of applications that do not depend on knowledge of ranges.

4 HTTP Message

4.1 Message Types

HTTP messages consist of requests from client to server and responses from server to client.

HTTP-message = Request | Response ; HTTP/1.1 messages

Request (section 5) and Response (section 6) messages use the generic message format of RFC 822 [9] for transferring entities (the payload 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 header fields, and possibly a message-body.

generic-message = start-line *(message-header CRLF) CRLF [ message-body ] start-line = Request-Line | Status-Line

In the interest of robustness, servers SHOULD ignore any empty line(s) received where a Request-Line is expected. In other words, if the server is reading the protocol stream at the beginning of a message and receives a CRLF first, it should ignore the CRLF.

Certain buggy HTTP/1.0 client implementations generate extra CRLF's after a POST request. To restate what is explicitly forbidden by the BNF, an HTTP/1.1 client MUST NOT preface or follow a request with an extra CRLF.

/** * Represents a HTTP request */class Request extends Message {

/** * @var string */ protected $method = 'GET';

/** * @var \TYPO3\FLOW3\Http\Uri */ protected $uri;

/** * @var \TYPO3\FLOW3\Http\Uri */ protected $baseUri;

/** * @var array */ protected $arguments;

/** * @var array<\TYPO3\FLOW3\Http\Cookie> */ protected $cookies;

/** * Data similar to that which is typically provided by $_SERVER * * @var array */ protected $server;

/** * The "http" settings * * @var array */ protected $settings;

/** * URI for the "input" stream wrapper which can be modified for testing purposes * * @var string */ protected $inputStreamUri = 'php://input';

/** * Constructs a new Request object based on the given environment data. * * @param array $get Data similar to that which is typically provided by $_GET * @param array $post Data similar to that which is typically provided by $_POST * @param array $files Data similar to that which is typically provided by $_FILES * @param array $server Data similar to that which is typically provided by $_SERVER

Page 26: Applications for the Enterprise with PHP (CPEurope)

$request->getHeader('User-Agent'); # C64

$request->setHeader('X-Coffee', 'too few');

Page 27: Applications for the Enterprise with PHP (CPEurope)

$now = new \DateTime();$response->setLastModified($now);

Page 28: Applications for the Enterprise with PHP (CPEurope)

$response->getHeaders()->setCacheControlDirective('s-max-age', 100);

Page 29: Applications for the Enterprise with PHP (CPEurope)

# set cookie in response:$response->setCookie(new Cookie('counter', 1));

# retrieve cookie on next request:$cookie = $request->getCookie('counter');

Page 30: Applications for the Enterprise with PHP (CPEurope)

Templating3

Page 31: Applications for the Enterprise with PHP (CPEurope)

<html lang="en"> <head> <title>Templating</title> </head> <body>

Our templating engineis called

Fluid </body></html>

Page 32: Applications for the Enterprise with PHP (CPEurope)

<?phpnamespace Acme\Demo\Controller;use TYPO3\FLOW3\Mvc\Controller\ActionController;

class HelloWorldController extends ActionController {

/** * @param string $name * @return void */ public function greetAction($name) { $this->view->assign('name', $name); }

}

Page 33: Applications for the Enterprise with PHP (CPEurope)

<html> <head> <title>Fluid Example</title> </head> <body> <p>Hello, {name}!</p> </body></html>

Page 34: Applications for the Enterprise with PHP (CPEurope)

<?phpnamespace Acme\Demo\Controller;use TYPO3\FLOW3\Mvc\Controller\ActionController;use Acme\Demo\Domain\Model\Book;

class BookController extends ActionController {

/** * @return void */ public function indexAction() { $book = new Book(); $book->setTitle('Manual del Guerrero de la Luz'); $books = array($book); $this->view->assign('books', $books); }

}

Page 35: Applications for the Enterprise with PHP (CPEurope)

<ul> <f:for each="{books}" as="book"> <li>{book.title}</li> </f:for> </ul>

Page 36: Applications for the Enterprise with PHP (CPEurope)

Model4

Page 37: Applications for the Enterprise with PHP (CPEurope)

public function createAction(Book $book) { if (!$this->securityManager->hasRole('BookAdmin')) { throw new \Exception('Not allowed.'); }

$statementHandle = $this->databaseHandle->prepare( 'INSERT INTO "books" ("identifier", "title", "isbn") ' . 'VALUES (?, ?, ?)' ); $result = $statementHandle->execute( array($book->getId(), $book->getTitle(), $book->getIsbn()) ); if ($result === FALSE) { throw new \Exception('Could not create book.'); }}

Page 38: Applications for the Enterprise with PHP (CPEurope)

class Book extends BaseModel { protected $id; protected $title; protected $isbn; … public function __construct() { $this->id = \TYPO3\FLOW3\Utility\Algorithms::generateUUID(); } … public function getSalesVolume() { if (!$this->securityManager->hasRole('Management')) { throw new \Exception('Access Denied'); }

$statementHandle = $this->databaseHandle->prepare( 'SELECT "identifier" FROM "orders" WHERE "date">? AND "submitted"=1'); $result = $statementHandle->execute(array(time() - 604800)); if ($result === FALSE) {

Page 39: Applications for the Enterprise with PHP (CPEurope)

Tackling the Heart of Software Development

Domain-Driven DesignA methodology which ...

• results in rich domain models

• provides a common language across the project team

• simplify the design of complex applications

FLOW3 is the first PHP framework tailored to Domain-Driven Design

/** * A Book * * @FLOW3\Scope(“prototype”) * @FLOW3\Entity */class Book {

/** * @var string */ protected $title;

/** * @var string */ protected $isbn;

/** * @var string */ protected $description;

/** * @var integer */ protected $price;

/** * @var \SplObjectStorage */ protected $materials;

/** * @var \Acme\Conference\Domain\Model\SessionType * @validate NotEmpty */ protected $proposedSessionType;

/** * Constructs a new Paper * * @author Robert Lemke <[email protected]> */ public function __construct() { $this->materials = new \SplObjectStorage; }

/** * Sets the author of this paper * * @param \Acme\Conference\Domain\Model\Participant $author * @return void * @author Robert Lemke <[email protected]> */ public function setAuthor(\Acme\Conference\Domain\Model\Participant $author) { $this->author = $author; }

/** * Getter for the author of this paper * * @return \Acme\Conference\Domain\Model\Participant * @author Robert Lemke <[email protected]> */ public function getAuthor() { return $this->author; }

/** * Setter for title * * @param string $title The title of this paper * @return void * @author Robert Lemke <[email protected]> */ public function setTitle($title) { $this->title = $title; }

/** * Getter for title * * @return string The title of this paper * @author Robert Lemke <[email protected]> */ public function getTitle() { return $this->title; }

/** * Setter for the short abstract * * @param string $shortAbstract The short abstract for this paper * @return void * @author Robert Lemke <[email protected]> */ public function setShortAbstract($shortAbstract) { $this->shortAbstract = $shortAbstract; }

/** * Getter for the short abstract * * @return string The short abstract * @author Robert Lemke <[email protected]> */ public function getShortAbstract() { return $this->shortAbstract; }

/** * Setter for abstract * * @param string $abstract The abstract of this paper * @return void * @author Robert Lemke <[email protected]> */ public function setAbstract($abstract) { $this->abstract = $abstract; }

/** * Getter for abstract * * @return string The abstract * @author Robert Lemke <[email protected]> */ public function getAbstract() { return $this->abstract; }

/** * Returns the materials attached to this paper * * @return \SplObjectStorage The materials * @author Robert Lemke <[email protected]> */ public function getMaterials() { return $this->materials; }

/** * Setter for the proposed session type * * @param \Acme\Conference\Domain\Model\SessionType $proposedSessionType The proposed session type * @return void * @author Robert Lemke <[email protected]> */ public function setProposedSessionType(\Acme\Conference\Domain\Model\SessionType $proposedSessionType) { $this->proposedSessionType = $proposedSessionType; }

/** * Getter for the proposed session type * * @return \Acme\Conference\Domain\Model\SessionType The proposed session type * @author Robert Lemke <[email protected]> */ public function getProposedSessionType() { return $this->proposedSessionType; }}?>

Page 40: Applications for the Enterprise with PHP (CPEurope)

namespace RoeBooks\Shop\Domain\Model;use TYPO3\FLOW3\Annotations as FLOW3;

/** * A Book * * @FLOW3\Entity */class Book {

/** * @var string */ protected $title;

/** * @var integer */ protected $price;

Page 41: Applications for the Enterprise with PHP (CPEurope)

/** * 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; }

Page 42: Applications for the Enterprise with PHP (CPEurope)

/** * Get the Book's Sales Volume * * @return integer The Book's sales volume */ public function getSalesVolume() { $time = new \DateTime('last month'); $total = $this->bookRepository->calculateTotalSalesSince($time); return $total; }

Page 43: Applications for the Enterprise with PHP (CPEurope)

interface RepositoryInterface {

/** * Adds an object to this repository. * @param object $object The object to add * @return void */ public function add($object);

/** * Removes an object from this repository. * @param object $object The object to remove * @return void */ public function remove($object);

/** * Returns all objects of this repository. * @return \TYPO3\FLOW3\Persistence\QueryResultInterface The query result */ public function findAll();

/** * Finds an object matching the given identifier.

Page 44: Applications for the Enterprise with PHP (CPEurope)

/** * A repository for Books * * @FLOW3\Scope("singleton") */class BookRepository extends Repository {

/** * Returns the total sales volume * * @param \DateTime $time */ public function calculateTotalSalesSince(\DateTime $time) { # implementation … }

}

Page 45: Applications for the Enterprise with PHP (CPEurope)

/** * Adds the given new book object to the book repository * * @param \Acme\Demo\Domain\Model\Book $newBook A new book to add * @return void */ public function createAction(Book $newBook) { $this->bookRepository->add($newBook); $this->redirect('index'); }

Page 46: Applications for the Enterprise with PHP (CPEurope)

TEXT HERE

Page 47: Applications for the Enterprise with PHP (CPEurope)

Resources5

Page 48: Applications for the Enterprise with PHP (CPEurope)

TEXT HERE

Page 49: Applications for the Enterprise with PHP (CPEurope)

TEXT HERE

Page 50: Applications for the Enterprise with PHP (CPEurope)

TEXT HERE

Page 51: Applications for the Enterprise with PHP (CPEurope)

TEXT HERE

Page 52: Applications for the Enterprise with PHP (CPEurope)

TEXT HERE

Page 53: Applications for the Enterprise with PHP (CPEurope)

DependencyInjection6

Page 54: Applications for the Enterprise with PHP (CPEurope)

class Foo { protected static $instance; public function getInstance() { if (self::$instance === NULL) { self::$instance = new self; } return self::$instance; }}

class Bar { public function action() { $foo = Foo::getInstance(); }}

Page 55: Applications for the Enterprise with PHP (CPEurope)

class ServiceLocator { protected static $services = array(); public function get($serviceName) { return self::$services[$serviceName]; }}

class Bar { public function action() { $foo = ServiceLocator::get('Foo'); }}

Page 56: Applications for the Enterprise with PHP (CPEurope)

class Bar { /** * @var Foo */ protected $foo; /** * @param Foo $foo */ public function __construct(Foo $foo) { $this->foo = $foo; } /** * @return string */ public function action() { $this->foo->doSomething(); }}

Page 57: Applications for the Enterprise with PHP (CPEurope)

class Bar { /** * @var Foo * @FLOW3\Inject */ protected $foo;

/** * @return string */ public function action() { $this->foo->doSomething(); }}

Page 58: Applications for the Enterprise with PHP (CPEurope)

Object Management

Page 59: Applications for the Enterprise with PHP (CPEurope)

Object Management

FLOW3's take on Dependency Injection

• one of the first PHP implementations(started in 2006, improved ever since)

Page 60: Applications for the Enterprise with PHP (CPEurope)

Object Management

FLOW3'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

Page 61: Applications for the Enterprise with PHP (CPEurope)

Object Management

FLOW3'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 gatered automatically (autowiring)

Page 62: Applications for the Enterprise with PHP (CPEurope)

Object Management

FLOW3'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 gatered automatically (autowiring)

• intuitive use and no bad magical surprises

Page 63: Applications for the Enterprise with PHP (CPEurope)

Object Management

FLOW3'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 gatered automatically (autowiring)

• intuitive use and no bad magical surprises

• fast! (like hardcoded or faster)

Page 64: Applications for the Enterprise with PHP (CPEurope)

Aspect-Oriented Programming7

Page 65: Applications for the Enterprise with PHP (CPEurope)

<?phpnamespace Acme\Demo\Controller;use TYPO3\FLOW3\Mvc\Controller\ActionController;

class HelloWorldController extends ActionController {

/** * @param string $name The name to mention * @return string */ public function greetAction($name) { return "¡Hola $name!"; }

}

Page 66: Applications for the Enterprise with PHP (CPEurope)
Page 67: Applications for the Enterprise with PHP (CPEurope)

namespace Acme\Demo\Aspect;

use TYPO3\FLOW3\Aop\JoinPoint;use TYPO3\FLOW3\Annotations\Around;

class BetterWorldAspect {

/** * Advice which tweaks the HelloWorld controller * * @param JoinPoint $joinPoint * @Around("method(.*Controller->greetAction())") */ public function someAdvice(JoinPoint $joinPoint) { $name = $joinPoint->getMethodArgument('name'); return sprintf("%s, you're running out of time!", $name); } }

Page 68: Applications for the Enterprise with PHP (CPEurope)

Robert, you’re running out of time!

Page 69: Applications for the Enterprise with PHP (CPEurope)

Security8

Page 70: Applications for the Enterprise with PHP (CPEurope)
Page 71: Applications for the Enterprise with PHP (CPEurope)

## Policy.yaml# resources: methods: DangerousMethods: 'method(.*Controller->(new|create|edit|update|delete)Action))'

roles: User: [] Administrator: [User]

acls: Administrator: methods: DangerousMethods: GRANT

Page 72: Applications for the Enterprise with PHP (CPEurope)
Page 73: Applications for the Enterprise with PHP (CPEurope)

TEXT HERE

Page 74: Applications for the Enterprise with PHP (CPEurope)

Sessions9

Page 75: Applications for the Enterprise with PHP (CPEurope)

TEXT HERE

Page 76: Applications for the Enterprise with PHP (CPEurope)

TEXT HERE

Page 77: Applications for the Enterprise with PHP (CPEurope)

TEXT HERE

Page 78: Applications for the Enterprise with PHP (CPEurope)

TEXT HERE

Page 79: Applications for the Enterprise with PHP (CPEurope)

Command Line10

Page 80: Applications for the Enterprise with PHP (CPEurope)
Page 81: Applications for the Enterprise with PHP (CPEurope)
Page 82: Applications for the Enterprise with PHP (CPEurope)
Page 83: Applications for the Enterprise with PHP (CPEurope)

/** * Kickstart a new action controller * * Generates an Action Controller with the given name in the specified package. * In its default mode it will create just the controller containing a sample * indexAction. * * By specifying the --generate-actions flag, this command will also create a * set of actions. If no model or repository exists which matches the * controller name (for example "CoffeeRepository" for "CoffeeController"), * an error will be shown. * * Likewise the command exits with an error if the specified package does not * exist. By using the --generate-related flag, a missing package, model or * repository can be created alongside, avoiding such an error. * * By specifying the --generate-templates flag, this command will also create * matching Fluid templates for the actions created. This option can only be * used in combination with --generate-actions. * * The default behavior is to not overwrite any existing code. This can be * overridden by specifying the --force flag.

Page 84: Applications for the Enterprise with PHP (CPEurope)

* By specifying the --generate-templates flag, this command will also create * matching Fluid templates for the actions created. This option can only be * used in combination with --generate-actions. * * The default behavior is to not overwrite any existing code. This can be * overridden by specifying the --force flag. * * @param string $packageKey The package key of the package for the new controller with an optional s * @param string $controllerName The name for the new controller. This may also be a comma separate * @param boolean $generateActions Also generate index, show, new, create, edit, update and delete actions. * @param boolean $generateTemplates Also generate the templates for each action. * @param boolean $generateRelated Also create the mentioned package, related model and repository if neccessary. * @param boolean $force Overwrite any existing controller or template code. Regardless of this flag,reposi * @return string * @see typo3.kickstart:kickstart:commandcontroller */ public function actionControllerCommand($packageKey, $controllerName, $generateActions = FALSE,

$subpackageName = ''; if (strpos('/', $packageKey) !== FALSE) { list($packageKey, $subpackageName) = explode('/', $packageKey, 2); } if (!$this->packageManager->isPackageKeyValid($packageKey)) {

Page 85: Applications for the Enterprise with PHP (CPEurope)
Page 86: Applications for the Enterprise with PHP (CPEurope)

Rossmann

• second biggest drug store in Germany

• 5,13 billion ! turnover

• 31,000 employees

Customer Database

Page 87: Applications for the Enterprise with PHP (CPEurope)

Amadeus

•world’s biggest e-ticket provider

• 217 markets

• 948 million billable transactions / year

• 2,7 billion ! revenue

Social Media Suite

Page 88: Applications for the Enterprise with PHP (CPEurope)

At a Glance

FLOW3 is a web application platform

• holistic concept for your apps

• modular, extensible, package based

• pedantically clean with focus on quality

• puts a smile on developer’s faces

• free & Open Source (LGPL v3)

• backed by one of the largest Open Source projects

Page 89: Applications for the Enterprise with PHP (CPEurope)

Foundation for the Next Generation CMS

TYPO3 “Phoenix” is the all-new Enterprise CMS

• content repository, workspaces, versions, i18n, modular UI ...

• powered by FLOW3

• compatible code base

• use TYPO3 features in FLOW3 standalone apps as you like

Page 90: Applications for the Enterprise with PHP (CPEurope)

FLOW3 1.1 Releasetomorrow!