Aura Project for PHP
-
Upload
hari-k-t -
Category
Technology
-
view
6.682 -
download
0
Transcript of Aura Project for PHP
Aura Project for PHP 5.4
Hari K TBridge Global IT Staffing
http://harikt.com
http://auraphp.github.com
Brought to you by @pmjonesPaul 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 / LibraryAura.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 Aura\Autoload )
├── 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 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');
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',
]);
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 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);
}
}
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();
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.
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 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');
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 Vendor\Package\View\Helper;
use Aura\View\Helper\AbstractHelper;
class Obfuscate extends AbstractHelper
{
public function __invoke($string)
{
return $this->escape(str_rot13($input));
}
}
Calling
$hl = $template->getHelperLocator();
$hl->set('obfuscate', function() {
return new \Vendor\Package\View\Helper\Obfuscate;
});
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-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
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.Clihttp://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 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();
Aura.Signal
httpa://.github.com/auraphp/Aura.Signalhttp://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(
'Vendor\Package\Example',
'example_signal',
function ($arg) { echo $arg; }
);
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);
}
}
Demo of Signal
Aura.Di
https://.github.com/auraphp/Aura.Dihttp://auraphp.github.com/Aura.Di
Dependency Injection
namespace Example\Package;
class Database
{
public function __construct($hostname, $username, $password)
{
// ... make the database connection
}
}
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 ) );
Aura.Di
Dependecny Injection Container
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));
Eager Loading
$di->set('database', new \Example\Package\Database(
'localhost', 'user', 'passwd'
));
Instance created on a fly
Lazy Loading
$di->set('database', function() {
return new \Example\Package\Database('localhost', 'user', 'passwd');
});
Constructor Params
$di->set('database', function() use ($di) {
return $di->newInstance('Example\Package\Database', [
'hostname' => 'localhost',
'username' => 'user',
'password' => 'passwd',
]);
});
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');
});
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',
]);
});
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 [email protected]: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