Aura Project for PHP

63
Aura Project for PHP 5.4 Hari K T Bridge Global IT Staffing http://harikt.com http://auraphp.github.com

Transcript of Aura Project for PHP

Page 1: Aura Project for PHP

Aura Project for PHP 5.4

Hari K TBridge Global IT Staffing

http://harikt.com

http://auraphp.github.com

Page 2: Aura Project for PHP

Brought to you by @pmjonesPaul M Jones

Page 3: Aura Project for PHP

Aura?

Independent library packages for PHP 5.4

Second major version of Solar PHP

Packages can be used alone, in concert with each other, or combined into a full-stack framework of their own.

Groups : http://groups.google.com/group/auraphp

Source Code : https://github.com/auraphp

API & Docs : http://auraphp.github.com/Aura.<Package>

IRC #auraphp on freenode

Page 4: Aura Project for PHP

Current Components / LibraryAura.Autoload

Aura.Cli

Aura.Di

Aura.Http

Aura.Marshal

Aura.Router

Aura.Signal

Aura.Sql

Aura.View

Aura.Web

Page 5: Aura Project for PHP

Aura.Autoload

PSR-0 compliant SPL autoloader

Matches the interface proposed at https://wiki.php.net/rfc/splclassloader

Read more information on PSR-0 Autoload

http://bit.ly/yzJ8r6 from phpmaster.com

Page 6: Aura Project for PHP

Vendor.Package Structure├── config ( default.php , test.php )

├── meta ( authors.csv, changes.txt, description.txt )

├── scripts ( instance.php )

├── src

│ └── Aura

│ └── Autoload

│ ├── Exception

│ ├── Exception.php

│ └── Loader.php ( namespace Aura\Autoload )

├── src.php

├── tests

Page 7: Aura Project for PHP

Instantiate

Create an instance of the Loader and register it with SPL.

$loader = require '/path/to/Aura.Autoload/scripts/instance.php';

$loader->register();

Page 8: Aura Project for PHP

Class Prefix Usage

// look for all Vendor_* classes in this path:

$loader->add('Vendor_', '/path/to/lib');

// look for Vendor\Package classes in this path:

$loader->add('Vendor\Package\\', '/path/to/Vendor.Package/src');

// additionally, e.g. in testing modes, also look for Vendor\Package

// classes in this path as well:

$loader->add('Vendor\Package\\', '/path/to/Vendor.Package/tests');

Page 9: Aura Project for PHP

All in one

$loader->setPaths([

'Aura\Router\\' => '/path/Aura.Router/src/',

'Aura\Di\\' => '/path/Aura.Di/src/',

]);

$loader->setClasses([

'Vendor\Package\Foo' => '/path/to/Vendor/Package/Foo.php',

'Vendor\Package\Zim' => '/path/to/Vendor/Package/Zim.php',

]);

Page 10: Aura Project for PHP

Aura.Router

Page 11: Aura Project for PHP

Aura.Router

Aura Router is a PHP package that implements web routing

Given a URI path and a copy of $_SERVER, it will extract controller, action, and parameter values for a specific application route.

Inspired by Solar rewrite rules and http://routes.groovie.org

Page 12: Aura Project for PHP

Add Routes$map = require '/path/to/Aura.Router/scripts/instance.php';

$map->add('home', '/', [

'values' => ['controller' => 'hello', 'action' => 'world',],

]);

$map->add('read', '/blog/read/{:id}{:format}', [

'params' => [

'id' => '(\d+)',

'format' => '(\..+)?',

],

'values' => [

'controller' => 'blog', 'action' => 'read', 'format' => '.html',

],

));

Page 13: Aura Project for PHP

Matching a Route

// get the incoming request URI path

$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

// get the route based on the path and server

$route = $map->match($path, $_SERVER);

Page 14: Aura Project for PHP

if (! $route) {

echo "No application route was found for that URI path."; exit();

}

// does the route indicate a controller?

if (isset($route->values['controller'])) {

$controller = $route->values['controller']; // take the controller class directly from the route

} else {

$controller = 'Default'; // use a default controller

}

if (isset($route->values['action'])) { // does the route indicate an action?

$action = $route->values['action']; // take the action method directly from the route

} else {

$action = 'index'; // use a default action

}

$page = new $controller(); // instantiate the controller class

echo $page->$action($route->values); // invoke the action method with the route values

Page 15: Aura Project for PHP

Generating A Route Path

// $path => "/blog/read/42.atom"

$path = $map->generate('read', [

'id' => 42,

'format' => '.atom',

]);

$href = htmlspecialchars($path, 'UTF-8');

echo '<a href="$href">Atom feed for this blog entry</a>';

Page 16: Aura Project for PHP

Aura.Web

http://auraphp.github.com/Aura.Web/

https://github.com/auraphp/Aura.Web/

Page 17: Aura Project for PHP

Aura.Web

The Aura Web package provides tools to build web page controllers

includes an AbstractPage for action methods

a Context class for disovering the request environment

Response transfer object that describes the eventual HTTP response

Page 18: Aura Project for PHP

Creating Page controller

namespace Vendor\Package\Web;

use Aura\Web\AbstractPage;

class Page extends AbstractPage

{

protected function actionHello($noun = null)

{

$noun = htmlspecialchars($noun, ENT_QUOTES, 'UTF-8');

$content = "Hello, {$noun}!";

$this->response->setContent($content);

}

}

Page 19: Aura Project for PHP

The Execution Cycle

namespace Vendor\Package\Web;

use Vendor\Package\Web\Page;

use Aura\Web\Context;

use Aura\Web\Response;

$params = [

'action' => 'hello',

'format' => '.html',

];

$page = new Page(new Context, new Response, $params);

$response = $page->exec();

Page 20: Aura Project for PHP

Internally, the exec() cycle runsA preExec() hook to let you set up the object,

A preAction() hook to prepare for the action,

The action() method to invoke the method determined by the 'action' param value

A postAction() hook,

A preRender() hook to prepare for rendering,

The render() method to render a presentation (this is up to the developer to create),

A postRender() hook, and

A postExec() hook.

At the end returns a Response transfer object. Response object is not an HTTP response proper;

it is a data transfer object that has information on how to build an HTTP response.

Page 21: Aura Project for PHP

The Context Object

$this->context->

getQuery(): gets a $_GET value

getPost(): gets a $_POST value

getFiles(): gets a $_FILES value

getInput(): gets the raw php://input value

getJsonInput(): gets the raw php://input value and json_decode() it

getAccept(): gets the Accept headers, ordered by weight

isGet(), isPut(), isXhr(), etc.: Tells if the request method was GET, PUT, an Xml-HTTP-Request, etc.

Page 22: Aura Project for PHP

Rendering

render() method is empty by default.

this allows you to add in whatever presentation logic you want, from simply json_encode()-ing $this->data, to using a complex two-step or transform view.

Aura.View

Page 23: Aura Project for PHP

Aura.View

https://github.com/auraphp/Aura.View

http://auraphp.github.com/Aura.View

Page 24: Aura Project for PHP

Aura.View

Template View pattern

preceded by systems such as Savant, Zend_View, and Solar_View

Auto escaping [escaper branch] a work in progress

Page 25: Aura Project for PHP

Instantiation

$template = require '/path/to/Aura.View/scripts/instance.php';

OR

use Aura\View\Template;

use Aura\View\TemplateFinder;

use Aura\View\HelperLocator;

$template = new Template(new TemplateFinder, new HelperLocator);

echo $template->fetch('/path/to/tpl.php');

Page 26: Aura Project for PHP

Adding Data

$template->addData([

'foo' => 'Value of foo',

'bar' => 'Value of bar',

]);

// this will remove $var, $foo, and $bar from the template

$template->setData([

'baz' => 'Value of baz',

'dib' => 'Value of dib',

]);

Page 27: Aura Project for PHP

Template Composition

<?php $e = $this->getHelper('escape'); // template script ?>

<html>

<head>

<?php include $this->find('head'); ?>

</head>

<body>

<?php include $this->find('branding'); // branding.php ?>

<?php include $this->find('navigation'); ?>

<p>Hello, <?php echo $e($this->var); ?>!</p>

<?php include $this->find('footer'); ?>

</body>

</html>

Page 28: Aura Project for PHP

Template Finder

$finder = $template->getTemplateFinder();

// set the paths where templates can be found

$finder->setPaths([

'/path/to/templates/foo',

'/path/to/templates/bar',

'/path/to/templates/baz',

]);

Page 29: Aura Project for PHP

Writing Helpers

namespace Vendor\Package\View\Helper;

use Aura\View\Helper\AbstractHelper;

class Obfuscate extends AbstractHelper

{

public function __invoke($string)

{

return $this->escape(str_rot13($input));

}

}

Page 30: Aura Project for PHP

Calling

$hl = $template->getHelperLocator();

$hl->set('obfuscate', function() {

return new \Vendor\Package\View\Helper\Obfuscate;

});

echo $this->obfuscate('plain text');

Page 31: Aura Project for PHP

Aura.Sql

https://github.com/auraphp/Aura.Sql

http://auraphp.github.com/Aura.Sql

Page 32: Aura Project for PHP

Aura SQL

$adapter_factory = include '/path/to/Aura.Sql/scripts/instance.php';

$sql = $adapter_factory->newInstance(

// adapter name

'mysql',

// DSN elements for PDO; this can also be

// an array of key-value pairs

'host=localhost;dbname=database_name',

'username',

'password'

);

Page 33: Aura Project for PHP

Connecting

Lazy connection

Manually connect

$sql->connect()

Fetching Results

// returns all rows

$result = $sql->fetchAll('SELECT * FROM foo');

Page 34: Aura Project for PHP

Preventing SQL Injection

$text = 'SELECT * FROM foo WHERE id = :id AND bar IN(:bar_list)';

// values to bind to query placeholders

$data = [

'id' => 1,

'bar_list' => ['a', 'b', 'c'],

];

// returns all rows; the query ends up being

// "SELECT * FROM foo WHERE id = 1 AND bar IN('a', 'b', 'c')"

$result = $sql->fetchOne($text, $data);

Page 35: Aura Project for PHP

Inserting

$table = 'foo';

// the columns and values to insert

$cols = [

'bar' => 'value for column bar',

];

// perform the insert; result is number of rows affected

$result = $sql->insert($table, $cols);

// now get the last inserted ID

$id = $sql->lastInsertId(); // mysql

$id = $sql->lastInsertId($table, 'id'); // pgssql

Page 36: Aura Project for PHP

Updating$table = 'foo';

// the new column values to set

$cols = [

'bar' => 'a new value for column bar',

];

// a where condition to specify which rows to update

$cond = 'id = :id';

// additional data to bind to the query

$data = ['id' => 1];

// perform the update; result is number of rows affected

$result = $sql->update($table, $cols, $cond, $data);

Page 37: Aura Project for PHP

Transactions// turn off autocommit and start a transaction

$sql->beginTransaction();

try {

// ... perform some queries ...

// now commit to the database:

$sql->commit();

} catch (Exception $e) {

// there was an error, roll back the queries

$sql->rollBack();

}

Page 38: Aura Project for PHP

Profiling

$sql->getProfiler()->setActive(true);

// issue a query

$result = $sql->fetchAll('SELECT * FROM foo');

// now get the profiler information

foreach ($sql->getProfiler()->getProfiles() as $i => $profile) {

echo 'Query #' . $i + 1 . ' took ' . $profile->time . ' seconds.' . PHP_EOL;

}

Page 39: Aura Project for PHP

Aura.Marshal

https://github.com/auraphp/Aura.Marshal

http://auraphp.github.com/Aura.Marshal

Page 40: Aura Project for PHP

Aura.Marshal

Aura Marshal makes it easy to avoid the N+1 problem when working with a domain model. http://phpadvent.org/2011/a-stitch-in-time-saves-nine-by-paul-jones

it does not have a query-building facility

it will not issue queries on its own

it will not handle persistence for you

it will not lazy-load results from a data source

it will not read metadata or schemas from the datasource

Page 41: Aura Project for PHP

Defining Types and Relationships

Define Types

$manager->setType('posts', ['identity_field' => 'id']);

$manager->setType('comments', ['identity_field' => 'id']);

// posts have many comments

Define Relationship

$manager->setRelation('posts', 'comments', [

'relationship' => 'has_many',

'native_field' => 'id',

'foreign_field' => 'post_id'

]);

Page 42: Aura Project for PHP

Loading Data$result = $sql->fetchAll('SELECT * FROM posts LIMIT 10');

// load the results into the posts type object, and get back the

// identity (primary key) values for the loaded results.

$post_ids = $manager->posts->load($result);

// select and load all the comments on all the posts at once.

$result = $sql->fetchAll(

'SELECT * FROM comments WHERE post_id IN (:post_ids)',

[

'post_ids' => $post_ids,

]

);

$manager->comments->load($result);

Page 43: Aura Project for PHP

Aura.Cli

httpa://.github.com/auraphp/Aura.Clihttp://auraphp.github.com/Aura.Cli

Page 44: Aura Project for PHP

class ExampleCommand extends AbstractCommand {

protected $input = 'foo bar baz';

public function preExec() {

// perform object setup here }

public function preAction() {

$this->stdio->outln('The input is currently ' . $this->input);

}

public function action() {

$this->stdio->out('Please enter some text: ');

$this->input = $this->stdio->in();

}

public function postAction() {

$this->stdio->outln('The input was %r%2' . $this->input . '%n');

}

public function postExec() {

// perform object teardown here

}

Page 45: Aura Project for PHP

Instantiate

use Aura\Cli\Context;

use Aura\Cli\Getopt;

use Aura\Cli\OptionFactory;

use Aura\Cli\Stdio;

use Aura\Cli\Vt100;

$command = new ExampleCommand(

new Context($GLOBALS),

new Stdio( fopen('php://stdin', 'r'), fopen('php://stdout', 'w+'),

fopen('php://stderr', 'w+'), new Vt100 ),

new Getopt(new OptionFactory));

// execute

$command->exec();

Page 46: Aura Project for PHP

Aura.Signal

httpa://.github.com/auraphp/Aura.Signalhttp://auraphp.github.com/Aura.Signal

Page 47: Aura Project for PHP

Aura Signal

SignalSlots/EventHandler implementation

invoke handlers ("slots" or "hooks") whenever an object sends a signal ("notification" or "event") to the signal manager

Page 48: Aura Project for PHP

Instantiate and Add Handler

$signal = require '/path/Aura.Signal/scripts/instance.php';

$signal->handler(

'Vendor\Package\Example',

'example_signal',

function ($arg) { echo $arg; }

);

Page 49: Aura Project for PHP

use Aura\Signal\Manager as SignalManager;

class Example

{

protected $signal;

public function __construct(SignalManager $signal)

{

$this->signal = $signal;

}

public function doSomething($text)

{

echo $text;

$this->signal->send($this, 'example_signal', $text);

}

}

Page 50: Aura Project for PHP

Demo of Signal

Page 51: Aura Project for PHP

Aura.Di

https://.github.com/auraphp/Aura.Dihttp://auraphp.github.com/Aura.Di

Page 52: Aura Project for PHP

Dependency Injection

namespace Example\Package;

class Database

{

public function __construct($hostname, $username, $password)

{

// ... make the database connection

}

}

Page 53: Aura Project for PHP

namespace Example\Package;

abstract class Model

{

protected $db;

public function __construct(Database $db)

{

$this->db = $db;

}

}

class BlogModel extends Model

{

// ...

}

new BlogModel( new Database( params ) );

Page 54: Aura Project for PHP

Aura.Di

Dependecny Injection Container

Page 55: Aura Project for PHP

Instantiation

$di = require '/path/to/Aura.Di/scripts/instance.php';

or

use Aura\Di\Container;

use Aura\Di\Forge;

use Aura\Di\Config;

$di = new Container(new Forge(new Config));

Page 56: Aura Project for PHP

Eager Loading

$di->set('database', new \Example\Package\Database(

'localhost', 'user', 'passwd'

));

Instance created on a fly

Page 57: Aura Project for PHP

Lazy Loading

$di->set('database', function() {

return new \Example\Package\Database('localhost', 'user', 'passwd');

});

Page 58: Aura Project for PHP

Constructor Params

$di->set('database', function() use ($di) {

return $di->newInstance('Example\Package\Database', [

'hostname' => 'localhost',

'username' => 'user',

'password' => 'passwd',

]);

});

Page 59: Aura Project for PHP

Class Constructor Params

$di->params['Example\Package\Database'] = [

'hostname' => 'localhost',

'username' => 'user',

'password' => 'passwd',

];

$di->set('database', function() use ($di) {

return $di->newInstance('Example\Package\Database');

});

Page 60: Aura Project for PHP

Override Class Constructor Params

$di->params['Example\Package\Database'] = [

'hostname' => 'localhost',

'username' => 'user',

'password' => 'passwd',

];

$di->set('database', function() use ($di) {

return $di->newInstance('Example\Package\Database', [

'hostname' => 'example.com',

]);

});

Page 61: Aura Project for PHP

Getting Services

$db = $di->get('database');

Same object instance

lazyGet()

lazyNew()

there is more, have a look into https://github.com/auraphp/Aura.Di

Page 62: Aura Project for PHP

Aura Framework

git clone [email protected]:auraphp/system.git

cd system

php update.php

point to web/index.php

Page 63: Aura Project for PHP

Thank You

Rate it at http://joind.in/6279

Barcamp : http://joind.in/event/view/928