3. 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
5. 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
7. Instantiate
Create an instance of 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',
]);
11. 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
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 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>';
17. 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
19. 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();
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 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
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',
]);
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'
);
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 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();
}
38. 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;
}
40. 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
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);
44. 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
45. 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();
48. Instantiate and Add Handler
$signal = require '/path/Aura.Signal/scripts/instance.php';
$signal->handler(
'VendorPackageExample',
'example_signal',
function ($arg) { echo $arg; }
);
49. 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);
}
}
53. namespace ExamplePackage;
abstract class Model
{
protected $db;
public function __construct(Database $db)
{
$this->db = $db;
}
}
class BlogModel extends Model
{
// ...
}
new BlogModel( new Database( params ) );
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));
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 clone git@github.com:auraphp/system.git
cd system
php update.php
point to web/index.php
63. Thank You
Rate it at http://joind.in/6279
Barcamp : http://joind.in/event/view/928