Aura Project for PHP 5.4


Hari K T
Bridge Global IT Staffing
http://harikt.com
http://auraphp.github.com
Brought to you by @pmjones
         Paul M Jones
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
Current Components / Library
Aura.Autoload
Aura.Cli
Aura.Di
Aura.Http
Aura.Marshal
Aura.Router
Aura.Signal
Aura.Sql
Aura.View
Aura.Web
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
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 AuraAutoload )
├── src.php
├── tests
Instantiate
Create an instance of the Loader and register it
 with SPL.


$loader = require '/path/to/Aura.Autoload/scripts/
  instance.php';
$loader->register();
Class Prefix Usage
// look for all Vendor_* classes in this path:
$loader->add('Vendor_', '/path/to/lib');
// look for VendorPackage classes in this path:
$loader->add('VendorPackage',
  '/path/to/Vendor.Package/src');
// additionally, e.g. in testing modes, also look for
   VendorPackage
// classes in this path as well:
$loader->add('VendorPackage',
  '/path/to/Vendor.Package/tests');
All in one
$loader->setPaths([
      'AuraRouter' => '/path/Aura.Router/src/',
      'AuraDi'   => '/path/Aura.Di/src/',
]);
$loader->setClasses([
      'VendorPackageFoo' => '/path/to/Vendor/Package/Foo.php',
      'VendorPackageZim' => '/path/to/Vendor/Package/Zim.php',
]);
Aura.Router
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
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',
      ],
));
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);
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
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>';
Aura.Web
http://auraphp.github.com/Aura.Web/

https://github.com/auraphp/Aura.Web/
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
Creating Page controller
namespace VendorPackageWeb;
use AuraWebAbstractPage;
class Page extends AbstractPage
{
    protected function actionHello($noun = null)
    {
        $noun = htmlspecialchars($noun, ENT_QUOTES, 'UTF-8');
        $content = "Hello, {$noun}!";
        $this->response->setContent($content);
    }
}
The Execution Cycle
namespace VendorPackageWeb;
use VendorPackageWebPage;
use AuraWebContext;
use AuraWebResponse;
$params = [
     'action' => 'hello',
     'format' => '.html',
];
$page = new Page(new Context, new Response, $params);
$response = $page->exec();
Internally, the exec() cycle runs
A 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.
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.
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
Aura.View
https://github.com/auraphp/Aura.View

 http://auraphp.github.com/Aura.View
Aura.View
Template View pattern
preceded by systems such as Savant,
  Zend_View, and Solar_View
Auto escaping [escaper branch] a work in
 progress
Instantiation
$template = require
  '/path/to/Aura.View/scripts/instance.php';
     OR
use AuraViewTemplate;
use AuraViewTemplateFinder;
use AuraViewHelperLocator;
$template = new Template(new
  TemplateFinder, new HelperLocator);
echo $template->fetch('/path/to/tpl.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',
]);
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>
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',
]);
Writing Helpers
namespace VendorPackageViewHelper;
use AuraViewHelperAbstractHelper;


class Obfuscate extends AbstractHelper
{
    public function __invoke($string)
    {
        return $this->escape(str_rot13($input));
    }
}
Calling
$hl = $template->getHelperLocator();
$hl->set('obfuscate', function() {
   return new
  VendorPackageViewHelperObfuscate;
});
echo $this->obfuscate('plain text');
Aura.Sql
https://github.com/auraphp/Aura.Sql

 http://auraphp.github.com/Aura.Sql
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'
);
Connecting
Lazy connection
Manually connect
  $sql->connect()
Fetching Results
// returns all rows
$result = $sql->fetchAll('SELECT * FROM foo');
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);
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
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);
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();
}
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;
}
Aura.Marshal
https://github.com/auraphp/Aura.Marshal

  http://auraphp.github.com/Aura.Marshal
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-n
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
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'
]);
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);
Aura.Cli
httpa://.github.com/auraphp/Aura.Cli
 http://auraphp.github.com/Aura.Cli
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
Instantiate
use AuraCliContext;
use AuraCliGetopt;
use AuraCliOptionFactory;
use AuraCliStdio;
use AuraCliVt100;
$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();
Aura.Signal
httpa://.github.com/auraphp/Aura.Signal
 http://auraphp.github.com/Aura.Signal
Aura Signal
SignalSlots/EventHandler implementation
invoke handlers ("slots" or "hooks") whenever
  an object sends a signal ("notification" or
  "event") to the signal manager
Instantiate and Add Handler
$signal = require '/path/Aura.Signal/scripts/instance.php';
$signal->handler(
     'VendorPackageExample',
     'example_signal',
     function ($arg) { echo $arg; }
);
use AuraSignalManager 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);
    }
}
Demo of Signal
Aura.Di
https://.github.com/auraphp/Aura.Di
 http://auraphp.github.com/Aura.Di
Dependency Injection
namespace ExamplePackage;


class Database
{
    public function __construct($hostname, $username, $password)
    {
        // ... make the database connection
    }
}
namespace ExamplePackage;
abstract class Model
{
    protected $db;
    public function __construct(Database $db)
    {
        $this->db = $db;
    }
}
class BlogModel extends Model
{
    // ...
}
new BlogModel( new Database( params ) );
Aura.Di
Dependecny Injection Container
Instantiation
$di = require '/path/to/Aura.Di/scripts/instance.php';


or


use AuraDiContainer;
use AuraDiForge;
use AuraDiConfig;
$di = new Container(new Forge(new Config));
Eager Loading
$di->set('database', new ExamplePackageDatabase(
      'localhost', 'user', 'passwd'
));
Instance created on a fly
Lazy Loading
$di->set('database', function() {
      return new ExamplePackageDatabase('localhost', 'user',
      'passwd');
});
Constructor Params
$di->set('database', function() use ($di) {
      return $di->newInstance('ExamplePackageDatabase', [
            'hostname' => 'localhost',
            'username' => 'user',
            'password' => 'passwd',
      ]);
});
Class Constructor Params
$di->params['ExamplePackageDatabase'] = [
      'hostname' => 'localhost',
      'username' => 'user',
      'password' => 'passwd',
];


$di->set('database', function() use ($di) {
      return $di->newInstance('ExamplePackageDatabase');
});
Override Class Constructor
                     Params
$di->params['ExamplePackageDatabase'] = [
      'hostname' => 'localhost',
      'username' => 'user',
      'password' => 'passwd',
];
$di->set('database', function() use ($di) {
      return $di->newInstance('ExamplePackageDatabase', [
            'hostname' => 'example.com',
      ]);
});
Getting Services
$db = $di->get('database');
Same object instance
lazyGet()
lazyNew()
there is more, have a look into
  https://github.com/auraphp/Aura.Di
Aura Framework
git clone git@github.com:auraphp/system.git
cd system
php update.php


point to web/index.php
Thank You

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


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

Aura Project for PHP

  • 1.
    Aura Project forPHP 5.4 Hari K T Bridge Global IT Staffing http://harikt.com http://auraphp.github.com
  • 2.
    Brought to youby @pmjones Paul M Jones
  • 3.
    Aura? Independent library packagesfor 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
  • 4.
    Current Components /Library Aura.Autoload Aura.Cli Aura.Di Aura.Http Aura.Marshal Aura.Router Aura.Signal Aura.Sql Aura.View Aura.Web
  • 5.
    Aura.Autoload PSR-0 compliant SPLautoloader 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
  • 6.
    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 AuraAutoload ) ├── src.php ├── tests
  • 7.
    Instantiate Create an instanceof the Loader and register it with SPL. $loader = require '/path/to/Aura.Autoload/scripts/ instance.php'; $loader->register();
  • 8.
    Class Prefix Usage //look for all Vendor_* classes in this path: $loader->add('Vendor_', '/path/to/lib'); // look for VendorPackage classes in this path: $loader->add('VendorPackage', '/path/to/Vendor.Package/src'); // additionally, e.g. in testing modes, also look for VendorPackage // classes in this path as well: $loader->add('VendorPackage', '/path/to/Vendor.Package/tests');
  • 9.
    All in one $loader->setPaths([ 'AuraRouter' => '/path/Aura.Router/src/', 'AuraDi' => '/path/Aura.Di/src/', ]); $loader->setClasses([ 'VendorPackageFoo' => '/path/to/Vendor/Package/Foo.php', 'VendorPackageZim' => '/path/to/Vendor/Package/Zim.php', ]);
  • 10.
  • 11.
    Aura.Router Aura Router isa 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
  • 12.
    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', ], ));
  • 13.
    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);
  • 14.
    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
  • 15.
    Generating A RoutePath // $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>';
  • 16.
  • 17.
    Aura.Web The Aura Webpackage 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
  • 18.
    Creating Page controller namespaceVendorPackageWeb; use AuraWebAbstractPage; class Page extends AbstractPage { protected function actionHello($noun = null) { $noun = htmlspecialchars($noun, ENT_QUOTES, 'UTF-8'); $content = "Hello, {$noun}!"; $this->response->setContent($content); } }
  • 19.
    The Execution Cycle namespaceVendorPackageWeb; use VendorPackageWebPage; use AuraWebContext; use AuraWebResponse; $params = [ 'action' => 'hello', 'format' => '.html', ]; $page = new Page(new Context, new Response, $params); $response = $page->exec();
  • 20.
    Internally, the exec()cycle runs A 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.
  • 21.
    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.
  • 22.
    Rendering render() method isempty 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
  • 23.
  • 24.
    Aura.View Template View pattern precededby systems such as Savant, Zend_View, and Solar_View Auto escaping [escaper branch] a work in progress
  • 25.
    Instantiation $template = require '/path/to/Aura.View/scripts/instance.php'; OR use AuraViewTemplate; use AuraViewTemplateFinder; use AuraViewHelperLocator; $template = new Template(new TemplateFinder, new HelperLocator); echo $template->fetch('/path/to/tpl.php');
  • 26.
    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', ]);
  • 27.
    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>
  • 28.
    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', ]);
  • 29.
    Writing Helpers namespace VendorPackageViewHelper; useAuraViewHelperAbstractHelper; class Obfuscate extends AbstractHelper { public function __invoke($string) { return $this->escape(str_rot13($input)); } }
  • 30.
    Calling $hl = $template->getHelperLocator(); $hl->set('obfuscate',function() { return new VendorPackageViewHelperObfuscate; }); echo $this->obfuscate('plain text');
  • 31.
  • 32.
    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' );
  • 33.
    Connecting Lazy connection Manually connect $sql->connect() Fetching Results // returns all rows $result = $sql->fetchAll('SELECT * FROM foo');
  • 34.
    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);
  • 35.
    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
  • 36.
    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);
  • 37.
    Transactions // turn offautocommit 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(); }
  • 38.
    Profiling $sql->getProfiler()->setActive(true); // issue aquery $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; }
  • 39.
  • 40.
    Aura.Marshal Aura Marshal makesit easy to avoid the N+1 problem when working with a domain model. http://phpadvent.org/2011/a-stitch-in-time-saves-n 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
  • 41.
    Defining Types andRelationships 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' ]);
  • 42.
    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);
  • 43.
  • 44.
    class ExampleCommand extendsAbstractCommand { 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
  • 45.
    Instantiate use AuraCliContext; use AuraCliGetopt; useAuraCliOptionFactory; use AuraCliStdio; use AuraCliVt100; $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();
  • 46.
  • 47.
    Aura Signal SignalSlots/EventHandler implementation invokehandlers ("slots" or "hooks") whenever an object sends a signal ("notification" or "event") to the signal manager
  • 48.
    Instantiate and AddHandler $signal = require '/path/Aura.Signal/scripts/instance.php'; $signal->handler( 'VendorPackageExample', 'example_signal', function ($arg) { echo $arg; } );
  • 49.
    use AuraSignalManager asSignalManager; 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); } }
  • 50.
  • 51.
  • 52.
    Dependency Injection namespace ExamplePackage; classDatabase { public function __construct($hostname, $username, $password) { // ... make the database connection } }
  • 53.
    namespace ExamplePackage; abstract classModel { protected $db; public function __construct(Database $db) { $this->db = $db; } } class BlogModel extends Model { // ... } new BlogModel( new Database( params ) );
  • 54.
  • 55.
    Instantiation $di = require'/path/to/Aura.Di/scripts/instance.php'; or use AuraDiContainer; use AuraDiForge; use AuraDiConfig; $di = new Container(new Forge(new Config));
  • 56.
    Eager Loading $di->set('database', newExamplePackageDatabase( 'localhost', 'user', 'passwd' )); Instance created on a fly
  • 57.
    Lazy Loading $di->set('database', function(){ return new ExamplePackageDatabase('localhost', 'user', 'passwd'); });
  • 58.
    Constructor Params $di->set('database', function()use ($di) { return $di->newInstance('ExamplePackageDatabase', [ 'hostname' => 'localhost', 'username' => 'user', 'password' => 'passwd', ]); });
  • 59.
    Class Constructor Params $di->params['ExamplePackageDatabase']= [ 'hostname' => 'localhost', 'username' => 'user', 'password' => 'passwd', ]; $di->set('database', function() use ($di) { return $di->newInstance('ExamplePackageDatabase'); });
  • 60.
    Override Class Constructor Params $di->params['ExamplePackageDatabase'] = [ 'hostname' => 'localhost', 'username' => 'user', 'password' => 'passwd', ]; $di->set('database', function() use ($di) { return $di->newInstance('ExamplePackageDatabase', [ 'hostname' => 'example.com', ]); });
  • 61.
    Getting Services $db =$di->get('database'); Same object instance lazyGet() lazyNew() there is more, have a look into https://github.com/auraphp/Aura.Di
  • 62.
    Aura Framework git clonegit@github.com:auraphp/system.git cd system php update.php point to web/index.php
  • 63.
    Thank You Rate itat http://joind.in/6279 Barcamp : http://joind.in/event/view/928