applications for the enterprise with php (cpeurope)

Post on 19-May-2015

3.945 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

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

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

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

PHP

Java

is_php_a_good_language() ?TRUE : FALSE;

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

The programming languageis rarely the problem.

I♥PHP

I ���� PHP

Let me focus on the fun part

10 Features

Controller1

modelviewcontroller

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

class HelloWorldController extends ActionController {

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

}

TEXT HERE

<?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!"; }

}

<?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() . "!"; }

HTTP2

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].

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

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

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

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

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

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

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

Templating3

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

Our templating engineis called

Fluid </body></html>

<?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); }

}

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

<?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); }

}

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

Model4

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.'); }}

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) {

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 <robert@typo3.org> */ 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 <robert@typo3.org> */ 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 <robert@typo3.org> */ public function getAuthor() { return $this->author; }

/** * Setter for title * * @param string $title The title of this paper * @return void * @author Robert Lemke <robert@typo3.org> */ public function setTitle($title) { $this->title = $title; }

/** * Getter for title * * @return string The title of this paper * @author Robert Lemke <robert@typo3.org> */ 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 <robert@typo3.org> */ public function setShortAbstract($shortAbstract) { $this->shortAbstract = $shortAbstract; }

/** * Getter for the short abstract * * @return string The short abstract * @author Robert Lemke <robert@typo3.org> */ public function getShortAbstract() { return $this->shortAbstract; }

/** * Setter for abstract * * @param string $abstract The abstract of this paper * @return void * @author Robert Lemke <robert@typo3.org> */ public function setAbstract($abstract) { $this->abstract = $abstract; }

/** * Getter for abstract * * @return string The abstract * @author Robert Lemke <robert@typo3.org> */ public function getAbstract() { return $this->abstract; }

/** * Returns the materials attached to this paper * * @return \SplObjectStorage The materials * @author Robert Lemke <robert@typo3.org> */ 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 <robert@typo3.org> */ 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 <robert@typo3.org> */ public function getProposedSessionType() { return $this->proposedSessionType; }}?>

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;

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

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

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.

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

}

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

TEXT HERE

Resources5

TEXT HERE

TEXT HERE

TEXT HERE

TEXT HERE

TEXT HERE

DependencyInjection6

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(); }}

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

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

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(); }}

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

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

Object Management

Object Management

FLOW3's take on Dependency Injection

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

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

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)

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

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)

Aspect-Oriented Programming7

<?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!"; }

}

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); } }

Robert, you’re running out of time!

Security8

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

roles: User: [] Administrator: [User]

acls: Administrator: methods: DangerousMethods: GRANT

TEXT HERE

Sessions9

TEXT HERE

TEXT HERE

TEXT HERE

TEXT HERE

Command Line10

/** * 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.

* 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)) {

Rossmann

• second biggest drug store in Germany

• 5,13 billion ! turnover

• 31,000 employees

Customer Database

Amadeus

•world’s biggest e-ticket provider

• 217 markets

• 948 million billable transactions / year

• 2,7 billion ! revenue

Social Media Suite

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

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

FLOW3 1.1 Releasetomorrow!

top related