SlideShare une entreprise Scribd logo
1  sur  64
Télécharger pour lire hors ligne
Solar for PHP 5
                                Paul M. Jones
                              ConFoo, Montréal
                                09 Mar 2011

                             http://joind.in/2814
                                      1
Wednesday, March 9, 2011
Read This




                               2
Wednesday, March 9, 2011
About Me
                 •     Developer to VP Engineering

                 •     PHP since 1999 (PHP 3)

                 •     Savant Template System
                       (phpsavant.com)

                 •     PEAR Group (2007-2008)

                 •     Zend Framework

                 •     ZCE Advisory Board

                 •     Web framework benchmarks

                                                3
Wednesday, March 9, 2011
“Another Framework?”
              • http://solarphp.com
              • The first E_STRICT framework for PHP 5
              • Pre-dates Zend Framework
              • Portions of ZF based on early Solar work
                     (DB, DB_Select, DB_Table/Row/Rowset,
                     View,View_Helper, and others)


                                        4
Wednesday, March 9, 2011
Overview

                   • Foundational concepts and techniques
                   • Dispatch cycle
                   • Package highlights
                   • Project architecture
                   • Performance indicators
                                       5
Wednesday, March 9, 2011
Foundations



                                6
Wednesday, March 9, 2011
PEAR Standards

                   • pear.php.net
                   • 10+ years of public usage and vetting
                   • Coding style guide
                   • Class-to-file naming convention (PSR-0)
                           <?php class Vendor_Foo_Bar {
                             // Vendor/Foo/Bar.php
                           }
                                        7
Wednesday, March 9, 2011
Class-to-File Effects
                   •       Consistent and predictable
                           (autoloader)

                   •       Low cognitive friction on
                           structure and organization

                   •       Adaptable to change and
                           integration

                   •       Support files in parallel

                   •       Works in every project

                                                      8
Wednesday, March 9, 2011
Techniques

                   • Unified constructor
                   • Unified configuration
                   • Unified factory
                   • Lazy-loading registry
                   • Dependency management
                                    9
Wednesday, March 9, 2011
Typical Constructor
                            class Foo {
                              protected $_foo;
                              protected $_bar;
                              protected $_baz;
                              public function __construct(
                                $foo = null,
                                $bar = "dib",
                                $baz = "gir"
                              ) {
                                $this->_foo = $foo;
                                $this->_bar = $bar;
                                $this->_baz = $baz;
                              }
                            }
                                          10
Wednesday, March 9, 2011
Unified Constructor
               class Vendor_Foo {
                 protected $_Vendor_Foo = array(
                     "foo" => null,
                     "bar" => "baz",
                     "dib" => "gir",
                 );
                 protected $_foo;
                 protected $_bar;
                 protected $_baz;
                 public function __construct($config = array())
                 {
                   $config = array_merge($this->_Vendor_Foo, $config);
                   $this->_foo = $config["foo"];
                   $this->_bar = $config["bar"];
                   $this->_baz = $config["baz"];
                 }
               }

                                          11
Wednesday, March 9, 2011
Typical Config File

             webhost                  = www.example.com
             database.adapter         = pdo_mysql
             database.params.host     = db.example.com
             database.params.username = dbuser
             database.params.password = secret
             database.params.dbname   = dbname

             # what class uses them?
             # what if different classes use "database" as their key?




                                        12
Wednesday, March 9, 2011
Solar Config File
                 <!-- /path/to/config.php -->
                 <?php
                 $values = array();
                 $values["Solar_Sql"] = array(
                   "adapter" => "Solar_Sql_Adapter_Mysql",
                   "host"    => "db.example.com",
                   "user"    => "dbuser",
                   "pass"    => "secret",
                   "name"    => "dbname",
                 );

                 return $values;
                 ?>

                 <!-- capture return value from include -->
                 <?php $config = include "/path/to/config.php"; ?>

                                         13
Wednesday, March 9, 2011
Unified Configuration
       • Given unique class names, and unified constructor ...
       • ... configuration keys map directly to class names ...
       • ... unified configuration mechanism for all classes.
                   $config = array(
                     "Vendor_Foo" => array(
                       "foo" => "zim",
                     ),
                   );

                   // default values from config file
                   $foo = new Vendor_Foo($config['Vendor_Foo']);

                                         14
Wednesday, March 9, 2011
Unified Factory
          • Solar::factory() instead of `new` keyword
      // non-adapter
      $foo = Solar::factory("Vendor_Foo"); // Vendor_Foo with config

      // adapter: assume that the config file has set the value ...
      // $config["Solar_Sql"]["host"] = "db1.example.com";
      $sql = Solar::factory("Solar_Sql");

      // factory a new instance with instance-time config
      $sql_other = Solar::factory("Solar_Sql", array(
        "host" => "db2.example.com",
      ));




                                     15
Wednesday, March 9, 2011
Typical Registry
               // populate registry entries
               $db = new DB::factory('mysql');
               Registry::set('db', $db);

               // later, elsewhere
               $db = Registry::get('db');




                                  16
Wednesday, March 9, 2011
Lazy-Loading Registry

     // lazy, using default adapter and configs.
     Solar_Registry::set("sql", "Solar_Sql");

     // lazy, via config file
     $config["Solar"]["registry_set"]["sql"] = "Solar_Sql";

     // instantiation
     $sql = Solar_Registry::get("sql");




                               17
Wednesday, March 9, 2011
Dependency
                                 Management
       • How to maintain dependencies on other objects?
       • How to configure, replace, or test the other object?
       • “Dependency injection” or “service locator”
                           // typical dependency creation
                           public function __construct() {
                             $this->db = new DB();
                           }
                                            18
Wednesday, March 9, 2011
Dependency Injection
                  // constructor-based dependency injection.
                  // $db = DB::getAdapter();
                  // $foo = new Foo($db);
                  public function __construct($db) {
                    $this->db = $db;
                  }

                  // setter-based dependency injection.
                  // $foo = new Foo();
                  // $db = DB::getAdapter();
                  // $foo->setDb($db);
                  public function setDb($db) {
                    $this->db = $db;
                  }
                                       19
Wednesday, March 9, 2011
Service Locator
                   // static locator.
                   // $db = DB::getAdapter();
                   // Locator::set("db", $db);
                   public function __construct() {
                     $this->db = Locator::get("db");
                   }

                   // instance locator as dependency injection.
                   // $locator = new Locator();
                   // $db = DB::getAdapter();
                   // $locator->set("db", $db);
                   // $foo = new Foo($locator);
                   public function __construct($locator) {
                     $this->db = $locator->get("db");
                   }
                                        20
Wednesday, March 9, 2011
Solar::dependency()

                   • Combined service locator and dependency injector
                   • Uses a registry key (which may be lazy-loaded) ...
                   • ... or a directly-passed dependency object.

      Solar::dependency($class_hint, $specification);



                                           21
Wednesday, March 9, 2011
Solar::dependency()
                class Vendor_Foo extends Solar_Base {
                  public function _postConstruct() {
                    parent::_postConstruct();
                    $this->_sql = Solar::dependency(
                      "Solar_Sql",
                      $this->_config["sql"]
                    );
                  }
                }

                // inject an object
                $sql = Solar::factory("Solar_Sql");
                $foo = Solar::factory("Vendor_Foo", array("sql" => $sql));

                // locate via registry key "sql"
                Solar_Registry::set("sql", "Solar_Sql");
                $foo = Solar::factory("Vendor_Foo", array("sql" => "sql"));


                                           22
Wednesday, March 9, 2011
Dependency Config
               <!-- /path/to/config.php -->
               <?php
               // lazy-load Solar_Sql instance as "sql" 
               $config["Solar"]["registry_set"]["sql"] = "Solar_Sql";

               // use "sql" registry key for Vendor_Foo dependency
               $config["Vendor_Foo"]["sql"] => "sql";
               ?>

               <!-- script file -->
               <?php
               // now Vendor_Foo locates the "sql" entry automatically
               $foo = Solar::factory("Vendor_Foo");




                                          23
Wednesday, March 9, 2011
Dynamic Dispatch Cycle



                           24
Wednesday, March 9, 2011
Web Server + PHP
                                    Framework
                           Boot   Front   Page   Action   View




                                           25
Wednesday, March 9, 2011
Bootstrap
               $system = dirname(dirname(__FILE__));
               set_include_path("$system/include");

               require "Solar.php";

               $config = "$system/config.php";
               Solar::start($config);

               $front = Solar_Registry::get("controller_front");
               $front->display();

               Solar::stop();



                                       26
Wednesday, March 9, 2011
Web App Controllers

                   • Independent front and page controllers
                   • URI default format of
                     /controller/action/param/param/param

                   • Front controller determines only the page
                           controller class, not the action or params



                                              27
Wednesday, March 9, 2011
Front Controller


                   • Stack of class prefixes, e.g. Vendor_App
                   • /foo/bar/baz   => Vendor_App_Foo




                                       28
Wednesday, March 9, 2011
Front Controller
                   • Dynamic rewriter
                   • Static routing
                  $config["Solar_Controller_Front"]["replace"] = array(
                    "{:alnum}" => "([a-zA-Z0-9]+)",
                  );

                  $config["Solar_Controller_Front"]["rewrite"] = array(
                    "page/{:alnum}/edit" => "page/edit/$1",
                  );

                  $config["Solar_Controller_Front"]["routing"] = array(
                    "page" => "Other_App_Zim",
                  );

                                            29
Wednesday, March 9, 2011
Front Controller
                   • Named actions
                  <?php
                  $config["Solar_Controller_Front"]["rewrite"]["edit-page"] = array(
                      'pattern' => 'page/{:id}/edit',
                      'rewrite' => 'page/edit/$1',
                      'replace' => array(
                          '{:id}' => '(d+)',
                      ),
                      'default' => array(
                          '{:id}' => 88,
                      );
                  );

                  // then in a view:
                  echo $this->namedAction('edit-page', array('id' => 70));



                                                   30
Wednesday, March 9, 2011
Page Controller

     •      Looks at remaining portion of URI path and picks action
     • /foo/bar/baz => Vendor_App_Foo
     • public function actionBar($param)
     • preRun(), preAction(), postAction(),
            postRun(), preRender(), postRender()



                                     31
Wednesday, March 9, 2011
Package Highlights



                                   32
Wednesday, March 9, 2011
• SQL adapters
                   • ORM system
                   • Form generation
                   • CLI tooling
                   • Auth, Role, Access

                                          33
Wednesday, March 9, 2011
SQL Adapters
           • Adapters for Mysql, Pgsql, Sqlite, Sqlite2, Oracle
           • PDO-based, multiple fetch*() styles
           • Standardized insert(), update(), delete()
           • Abstracted LIMIT, column types, table creation,
                  index creation, sequences, auto-increment,
                  column description, index description


                                        34
Wednesday, March 9, 2011
Prepared Statements
                   • Named placeholders and bound values
            $sql = Solar::factory("Solar_Sql");

            $stmt = "SELECT * FROM students WHERE name = :name";

            $bind = array(
              "name"  => "Bob'; DROP TABLE students;--",
            );

            $list = $sql->fetchAll($stmt, $bind);



                                      35
Wednesday, March 9, 2011
Query Builder
        • Programmatically build complex SELECT statements
               $select = Solar::factory("Solar_Sql_Select");
               $select->from("table", array("col", "col", ...))
                      ->join()      // leftJoin(), innerJoin()
                      ->where("col = ?", $value)
                      ->group()
                      ->having()
                      ->union()     // unionAll()
                      ->order()
                      ->limit()     // page(), paging()
                      ->fetchAll(); // fetchOne(), fetchPairs(), etc



                                         36
Wednesday, March 9, 2011
MysqlReplicated
                   • Adapter picks master or slave
                   • Switch to/from non-replicated with no code changes
                   • Automatic “gap” (GET-after-POST) management
                   $config["Solar_Sql_Adapter_MysqlReplicated"] = array(
                     "host" => "master.db.example.com",
                     // ...
                     "slaves" => array(
                       0 => array("host" => "slave1.db.example.com"),
                       1 => array("host" => "slave2.db.example.com"),
                     ),
                   );

                                             37
Wednesday, March 9, 2011
ORM System
                       • TableDataGateway + DataMapper
                           Model objects
                       • Record objects (with relateds)
                       • Collection of Record objects
                       • Relationship definition objects
                       • Catalog for model objects
                       • Uses underlying SQL layers
                                           38
Wednesday, March 9, 2011
Model Setup
               class Vendor_Model_Invaders extends Solar_Sql_Model {
                 protected function _setup() {
                   $this->_table_name = "invaders"; // default
                   
                   // reads columns from table, or can be stored in:
                   // $this->_table_cols = array(...);
                   
                   // each record has these relateds:
                   $this->_belongsTo("irk");
                   $this->_hasOne("robot");
                   $this->_hasMany("weapons");
                   $this->_hasMany("invasions");
                   $this->_hasManyThrough("planets", "invasions");
                 }
               }


                                         39
Wednesday, March 9, 2011
Relationship Definitions
    'merge'          => merge data at 'server' (DB) or 'client'  (PHP)
    'native_by'      => 'wherein' or 'select' when matching natives
    'native_col'     => native col to match against foreign col
    'foreign_class'  => class name of the foreign model
    'foreign_alias'  => alias of the foreign table name
    'foreign_col'    => foreign col to match against the native col
    'cols'           => fetch these foreign cols
    'conditions'     => where or join-on conditions
    'foreign_key'    => magic shorthand for the foreign key col
    'order'          => how to order related rows

    ... plus fetch-time params and eager-fetch params.




                                     40
Wednesday, March 9, 2011
Fetching
               $model = Solar_Registry::get("model_catalog");

               $collection = $model->invaders->fetchAll(array(
                 "where"   => array("type = ?" => "short"),
                 "group"   => ...
                 "order"   => ...
                 "page"    => ...
                 "paging"  => ...
                 "eager"   => array("weapons", "robot", "planets"),
                 ...
               ));

               $array  = $model->invaders->fetchAllAsArray(array(...));

               $record = $model->invaders->fetchOne(array(...));



                                          41
Wednesday, March 9, 2011
Records
               $zim = $model->invaders->fetchOne(array(
                 "where" = array("name = ?" => "Zim")
               ));

               echo $zim->doom;
               $zim->enemy = "Dib";

               foreach ($zim->weapons as $weapon) {
                 echo $weapon->name;
               }

               $zim->weapons->appendNew(array("name" => "raygun"));

               $zim->save();



                                         42
Wednesday, March 9, 2011
Record Filters
                   •       Solar_Filter, Solar_Filter_Validate*, Solar_Filter_Sanitize*
                           as generally-available classes, not regular expressions

                   •       Vendor_Model_* will use Vendor_Filter_* automatically

                   •       Applied on $record->save() automatically
                  <?php
                  class Vendor_Model_Invaders extends Solar_Sql_Model_Record
                  {
                    protected function _setup() {
                      // ...
                      $this->_addFilter("bar", "validateAlnum");
                      $this->_addFilter("foo", "validateInList", array(
                          "one", "two", "three",
                      ));
                      $this->_addFilter("baz", "validateCustomThing");
                    }
                  }

                                                      43
Wednesday, March 9, 2011
Form Generation

               $zim  = $model->invaders->fetch($id);
               $form = $zim->newForm(); // Solar_Form object

               $view = Solar::factory("Solar_View");
               $html = $view->form()
                            ->auto($form)
                            ->addProcessGroup("save", "cancel");

               echo $html;

               // automatic CSRF protection


                                       44
Wednesday, March 9, 2011
Much More Model
                   • Single-table inheritance
                   • Calculated and virtual columns
                   • Auto serializing of columns (arrays)
                   • Auto XML structs (EAV)
                   • Auto creation of tables and indexes
                   • Auto count-pages at fetch time
                                        45
Wednesday, March 9, 2011
CLI Tooling
     $ ./script/solar make-vendor Vendor

     $ ./script/solar make-model Vendor_Model_Invaders

     $ ./script/solar make-app Vendor_App_Zim --model-name=invaders

     # make-docs, make-tests, run-tests, link-public, ...




                                   46
Wednesday, March 9, 2011
CLI Controllers
                   • Independent “console” (front) and
                           “command” (page) controllers
                   • Direct output with _out(), _outln(),
                     _err(), _errln()

                   • VT100 escape codes built in
                   • Vendor-specific invocation
                           • ./script/vendor     command-name

                                            47
Wednesday, March 9, 2011
Auth, Role, Access

                   • Auth adapters (SQL, LDAP, email, etc.)
                   • Role adapters (File, SQL)
                   • Access adapters (File, SQL)
                   • User class is composed of these

                                        48
Wednesday, March 9, 2011
Project Architecture



                                    49
Wednesday, March 9, 2011
System Directories
               system/
                 config.php    # config file
                 config/       # config support
                 docroot/      # vhost document root
                   index.php   # bootstrap
                   public/     # copies or symlinks to public assets
                 include/      # symlinks to PHP files
                 script/       # command-line scripts
                 source/       # actual PHP and support files
                 sqlite/       # sqlite databases
                 tmp/          # sessions, logs, caches, etc




                                         50
Wednesday, March 9, 2011
Source vs. Include
               include/       # single include-path for PHP files
                 Solar/       # symlink to source/solar/Solar
                 Solar.php    # symlink to source/solar/Solar.php
                 Vendor/      # symlink to source/vendor/Vendor
                 some.php     # symlink to source/other/some.php
                 else.php     # symlink to source/other/else.php

               source/        # all "real" files for a vendor
                 solar/       # solar files
                   config/
                   Solar.php
                   Solar/
                     ...
                 vendor/      # vendor files
                   Vendor/
                 other/       # random assortments of 3rd-party libs
                   some.php
                   else.php


                                             51
Wednesday, March 9, 2011
Typical Page and View
                     framework/             # libraries
                     application/           # separate include path
                       controllers/
                         FooController.php  # actions "bar" and "dib"
                         ZimController.php  # extends Foo
                       views/
                         foo/
                           bar.php
                           dib.php
                         zim/
                           bar.php
                           dib.php
                       layouts/
                         default.php
                       public/



                                             52
Wednesday, March 9, 2011
Solar Page And View
                Solar/               # libraries
                Vendor/              # same include path
                  App/
                    Foo.php          # actions "bar" and "dib"
                    Foo/
                      Layout/
                        default.php
                      Public/
                      View/
                        bar.php
                        dib.php
                    Zim.php          # extends Foo
                    Zim/
                      View/          # inherits Foo views
                        dib.php      # override view


                                         53
Wednesday, March 9, 2011
Performance Indicators



                           54
Wednesday, March 9, 2011
Benchmarks

                   • Google “web framework benchmarks”
                   • Amazon EC2 “Large” instance
                   • Apache, mod_php 5.3.2, APC
                   • 10 concurrent users, no sessions
                   • 5 runs of 1 minute each, pre-warmed cache
                                       55
Wednesday, March 9, 2011
Results Table
                 Framework                | relative | average
                 ---------------------    | -------- | --------
                 baseline/html            |   1.2823 | 3220.56
                 baseline/php             |   1.0000 | 2511.54
                 lithium/0.9.9            |   0.0827 |   207.62
                 solar/1.1.1              |   0.1609 |   404.17
                 symfony/1.4.8            |   0.0784 |   196.91
                 symfony/2.0.0pr4         |   0.0897 |   225.22
                 yii/1.1.5                |   0.1891 |   474.82
                 zend/1.10.2-minapp       |   0.1136 |   285.28
                 zend/1.10.2-project      |   0.0832 |   208.84


                                         56
Wednesday, March 9, 2011
Results Graph
                            lithium/0.9.9            0.08
                              solar/1.1.1                          0.16
                           symfony/1.4.8             0.08
                     symfony/2.0.0pr4                 0.09
                                yii/1.1.5                                 0.19
               zend/1.10.2-minapp                           0.11
                 zend/1.10.2-project                 0.08

                                            0   0.05        0.10   0.15          0.20
                                                57
Wednesday, March 9, 2011
• Be suspicious of benchmarks
                   • Only one data-point in decision making
                   • Measures only what you test
                   • https://github.com/pmjones/php-
                           framework-benchmarks



                                           58
Wednesday, March 9, 2011
Conclusion
                   • Foundational concepts and techniques
                   • Dispatch cycle
                   • Package highlights
                   • Project architecture
                   • Performance indicators
                   • Stable, mature, proven
                                       59
Wednesday, March 9, 2011
Aura Project
                           for PHP 5.3+
                            aka Solar version 2.0

                                     60
Wednesday, March 9, 2011
Changes
                   • Aura (Solar vs Solr)
                   • PHP 5.3+ (namespaces, closures, etc)
                   • DI proper instead of combo SL/DI
                   • Extract Solar functionality
                   • Independent library packages
                   • “System” package to create a framework
                                       61
Wednesday, March 9, 2011
Packages
                   •       Autoloader
                   •       DI (constructor/setter)
                   •       Signal slots / event handler
                   •       Web router
                   •       CLI controllers
                   •       “System”
                   •       Next: web controllers and views

                                                 62
Wednesday, March 9, 2011
Where?

                   • https://github.com/auraphp
                   • http://groups.google.com/group/auraphp
                   • #auraphp on Freenode

                                       63
Wednesday, March 9, 2011
Thanks!
            http://solarphp.com
         http://auraphp.github.com

                  http://joind.in/2814




                                         64
Wednesday, March 9, 2011

Contenu connexe

Similaire à The Solar Framework for PHP

The Solar Framework for PHP 5 (2010 Confoo)
The Solar Framework for PHP 5 (2010 Confoo)The Solar Framework for PHP 5 (2010 Confoo)
The Solar Framework for PHP 5 (2010 Confoo)Paul Jones
 
잘 알려지지 않은 Php 코드 활용하기
잘 알려지지 않은 Php 코드 활용하기잘 알려지지 않은 Php 코드 활용하기
잘 알려지지 않은 Php 코드 활용하기형우 안
 
Decoupled Libraries for PHP
Decoupled Libraries for PHPDecoupled Libraries for PHP
Decoupled Libraries for PHPPaul Jones
 
international PHP2011_ilia alshanetsky_Hidden Features of PHP
international PHP2011_ilia alshanetsky_Hidden Features of PHPinternational PHP2011_ilia alshanetsky_Hidden Features of PHP
international PHP2011_ilia alshanetsky_Hidden Features of PHPsmueller_sandsmedia
 
Development Approach
Development ApproachDevelopment Approach
Development Approachalexkingorg
 
Rails ORM De-mystifying Active Record has_many
Rails ORM De-mystifying Active Record has_manyRails ORM De-mystifying Active Record has_many
Rails ORM De-mystifying Active Record has_manyBlazing Cloud
 
Spring dependency injection
Spring dependency injectionSpring dependency injection
Spring dependency injectionsrmelody
 
Taking eZ Find beyond full-text search
Taking eZ Find beyond  full-text searchTaking eZ Find beyond  full-text search
Taking eZ Find beyond full-text searchPaul Borgermans
 
Writing Plugged-in Java EE Apps: Jason Lee
Writing Plugged-in Java EE Apps: Jason LeeWriting Plugged-in Java EE Apps: Jason Lee
Writing Plugged-in Java EE Apps: Jason Leejaxconf
 
Zend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingZend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingTricode (part of Dept)
 
Backbone.js - Michał Taberski (PRUG 2.0)
Backbone.js - Michał Taberski (PRUG 2.0)Backbone.js - Michał Taberski (PRUG 2.0)
Backbone.js - Michał Taberski (PRUG 2.0)ecommerce poland expo
 
Deploying on the cutting edge
Deploying on the cutting edgeDeploying on the cutting edge
Deploying on the cutting edgeericholscher
 
Intro to Joomla Development
Intro to Joomla DevelopmentIntro to Joomla Development
Intro to Joomla DevelopmentAlex Andreae
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionNate Abele
 
MongoDB at Sailthru: Scaling and Schema Design
MongoDB at Sailthru: Scaling and Schema DesignMongoDB at Sailthru: Scaling and Schema Design
MongoDB at Sailthru: Scaling and Schema DesignDATAVERSITY
 

Similaire à The Solar Framework for PHP (20)

The Solar Framework for PHP 5 (2010 Confoo)
The Solar Framework for PHP 5 (2010 Confoo)The Solar Framework for PHP 5 (2010 Confoo)
The Solar Framework for PHP 5 (2010 Confoo)
 
잘 알려지지 않은 Php 코드 활용하기
잘 알려지지 않은 Php 코드 활용하기잘 알려지지 않은 Php 코드 활용하기
잘 알려지지 않은 Php 코드 활용하기
 
Decoupled Libraries for PHP
Decoupled Libraries for PHPDecoupled Libraries for PHP
Decoupled Libraries for PHP
 
international PHP2011_ilia alshanetsky_Hidden Features of PHP
international PHP2011_ilia alshanetsky_Hidden Features of PHPinternational PHP2011_ilia alshanetsky_Hidden Features of PHP
international PHP2011_ilia alshanetsky_Hidden Features of PHP
 
55j7
55j755j7
55j7
 
Development Approach
Development ApproachDevelopment Approach
Development Approach
 
Rails ORM De-mystifying Active Record has_many
Rails ORM De-mystifying Active Record has_manyRails ORM De-mystifying Active Record has_many
Rails ORM De-mystifying Active Record has_many
 
Spring dependency injection
Spring dependency injectionSpring dependency injection
Spring dependency injection
 
Taking eZ Find beyond full-text search
Taking eZ Find beyond  full-text searchTaking eZ Find beyond  full-text search
Taking eZ Find beyond full-text search
 
Writing Plugged-in Java EE Apps: Jason Lee
Writing Plugged-in Java EE Apps: Jason LeeWriting Plugged-in Java EE Apps: Jason Lee
Writing Plugged-in Java EE Apps: Jason Lee
 
Zend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingZend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching logging
 
2012 03 08_dbi
2012 03 08_dbi2012 03 08_dbi
2012 03 08_dbi
 
Spring 3.1
Spring 3.1Spring 3.1
Spring 3.1
 
Backbone.js - Michał Taberski (PRUG 2.0)
Backbone.js - Michał Taberski (PRUG 2.0)Backbone.js - Michał Taberski (PRUG 2.0)
Backbone.js - Michał Taberski (PRUG 2.0)
 
Deploying on the cutting edge
Deploying on the cutting edgeDeploying on the cutting edge
Deploying on the cutting edge
 
Intro to Joomla Development
Intro to Joomla DevelopmentIntro to Joomla Development
Intro to Joomla Development
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
 
MongoDB at Sailthru: Scaling and Schema Design
MongoDB at Sailthru: Scaling and Schema DesignMongoDB at Sailthru: Scaling and Schema Design
MongoDB at Sailthru: Scaling and Schema Design
 
Spring introduction
Spring introductionSpring introduction
Spring introduction
 
Fatc
FatcFatc
Fatc
 

Plus de ConFoo

Debugging applications with network security tools
Debugging applications with network security toolsDebugging applications with network security tools
Debugging applications with network security toolsConFoo
 
The business behind open source
The business behind open sourceThe business behind open source
The business behind open sourceConFoo
 
Security 202 - Are you sure your site is secure?
Security 202 - Are you sure your site is secure?Security 202 - Are you sure your site is secure?
Security 202 - Are you sure your site is secure?ConFoo
 
OWASP Enterprise Security API
OWASP Enterprise Security APIOWASP Enterprise Security API
OWASP Enterprise Security APIConFoo
 
Opensource Authentication and Authorization
Opensource Authentication and AuthorizationOpensource Authentication and Authorization
Opensource Authentication and AuthorizationConFoo
 
Introduction à la sécurité des WebServices
Introduction à la sécurité des WebServicesIntroduction à la sécurité des WebServices
Introduction à la sécurité des WebServicesConFoo
 
Le bon, la brute et le truand dans les nuages
Le bon, la brute et le truand dans les nuagesLe bon, la brute et le truand dans les nuages
Le bon, la brute et le truand dans les nuagesConFoo
 
Décrire un projet PHP dans des rapports
Décrire un projet PHP dans des rapportsDécrire un projet PHP dans des rapports
Décrire un projet PHP dans des rapportsConFoo
 
Server Administration in Python with Fabric, Cuisine and Watchdog
Server Administration in Python with Fabric, Cuisine and WatchdogServer Administration in Python with Fabric, Cuisine and Watchdog
Server Administration in Python with Fabric, Cuisine and WatchdogConFoo
 
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+ConFoo
 
Think Mobile First, Then Enhance
Think Mobile First, Then EnhanceThink Mobile First, Then Enhance
Think Mobile First, Then EnhanceConFoo
 
Metaprogramming in Ruby
Metaprogramming in RubyMetaprogramming in Ruby
Metaprogramming in RubyConFoo
 
Scalable Architecture 101
Scalable Architecture 101Scalable Architecture 101
Scalable Architecture 101ConFoo
 
As-t-on encore besoin d'un framework web ?
As-t-on encore besoin d'un framework web ?As-t-on encore besoin d'un framework web ?
As-t-on encore besoin d'un framework web ?ConFoo
 
Pragmatic Guide to Git
Pragmatic Guide to GitPragmatic Guide to Git
Pragmatic Guide to GitConFoo
 
Building servers with Node.js
Building servers with Node.jsBuilding servers with Node.js
Building servers with Node.jsConFoo
 
An Overview of Flash Storage for Databases
An Overview of Flash Storage for DatabasesAn Overview of Flash Storage for Databases
An Overview of Flash Storage for DatabasesConFoo
 
Android Jump Start
Android Jump StartAndroid Jump Start
Android Jump StartConFoo
 
Develop mobile applications with Flex
Develop mobile applications with FlexDevelop mobile applications with Flex
Develop mobile applications with FlexConFoo
 
WordPress pour le développement d'aplications web
WordPress pour le développement d'aplications webWordPress pour le développement d'aplications web
WordPress pour le développement d'aplications webConFoo
 

Plus de ConFoo (20)

Debugging applications with network security tools
Debugging applications with network security toolsDebugging applications with network security tools
Debugging applications with network security tools
 
The business behind open source
The business behind open sourceThe business behind open source
The business behind open source
 
Security 202 - Are you sure your site is secure?
Security 202 - Are you sure your site is secure?Security 202 - Are you sure your site is secure?
Security 202 - Are you sure your site is secure?
 
OWASP Enterprise Security API
OWASP Enterprise Security APIOWASP Enterprise Security API
OWASP Enterprise Security API
 
Opensource Authentication and Authorization
Opensource Authentication and AuthorizationOpensource Authentication and Authorization
Opensource Authentication and Authorization
 
Introduction à la sécurité des WebServices
Introduction à la sécurité des WebServicesIntroduction à la sécurité des WebServices
Introduction à la sécurité des WebServices
 
Le bon, la brute et le truand dans les nuages
Le bon, la brute et le truand dans les nuagesLe bon, la brute et le truand dans les nuages
Le bon, la brute et le truand dans les nuages
 
Décrire un projet PHP dans des rapports
Décrire un projet PHP dans des rapportsDécrire un projet PHP dans des rapports
Décrire un projet PHP dans des rapports
 
Server Administration in Python with Fabric, Cuisine and Watchdog
Server Administration in Python with Fabric, Cuisine and WatchdogServer Administration in Python with Fabric, Cuisine and Watchdog
Server Administration in Python with Fabric, Cuisine and Watchdog
 
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
 
Think Mobile First, Then Enhance
Think Mobile First, Then EnhanceThink Mobile First, Then Enhance
Think Mobile First, Then Enhance
 
Metaprogramming in Ruby
Metaprogramming in RubyMetaprogramming in Ruby
Metaprogramming in Ruby
 
Scalable Architecture 101
Scalable Architecture 101Scalable Architecture 101
Scalable Architecture 101
 
As-t-on encore besoin d'un framework web ?
As-t-on encore besoin d'un framework web ?As-t-on encore besoin d'un framework web ?
As-t-on encore besoin d'un framework web ?
 
Pragmatic Guide to Git
Pragmatic Guide to GitPragmatic Guide to Git
Pragmatic Guide to Git
 
Building servers with Node.js
Building servers with Node.jsBuilding servers with Node.js
Building servers with Node.js
 
An Overview of Flash Storage for Databases
An Overview of Flash Storage for DatabasesAn Overview of Flash Storage for Databases
An Overview of Flash Storage for Databases
 
Android Jump Start
Android Jump StartAndroid Jump Start
Android Jump Start
 
Develop mobile applications with Flex
Develop mobile applications with FlexDevelop mobile applications with Flex
Develop mobile applications with Flex
 
WordPress pour le développement d'aplications web
WordPress pour le développement d'aplications webWordPress pour le développement d'aplications web
WordPress pour le développement d'aplications web
 

The Solar Framework for PHP

  • 1. Solar for PHP 5 Paul M. Jones ConFoo, Montréal 09 Mar 2011 http://joind.in/2814 1 Wednesday, March 9, 2011
  • 2. Read This 2 Wednesday, March 9, 2011
  • 3. About Me • Developer to VP Engineering • PHP since 1999 (PHP 3) • Savant Template System (phpsavant.com) • PEAR Group (2007-2008) • Zend Framework • ZCE Advisory Board • Web framework benchmarks 3 Wednesday, March 9, 2011
  • 4. “Another Framework?” • http://solarphp.com • The first E_STRICT framework for PHP 5 • Pre-dates Zend Framework • Portions of ZF based on early Solar work (DB, DB_Select, DB_Table/Row/Rowset, View,View_Helper, and others) 4 Wednesday, March 9, 2011
  • 5. Overview • Foundational concepts and techniques • Dispatch cycle • Package highlights • Project architecture • Performance indicators 5 Wednesday, March 9, 2011
  • 6. Foundations 6 Wednesday, March 9, 2011
  • 7. PEAR Standards • pear.php.net • 10+ years of public usage and vetting • Coding style guide • Class-to-file naming convention (PSR-0) <?php class Vendor_Foo_Bar {   // Vendor/Foo/Bar.php } 7 Wednesday, March 9, 2011
  • 8. Class-to-File Effects • Consistent and predictable (autoloader) • Low cognitive friction on structure and organization • Adaptable to change and integration • Support files in parallel • Works in every project 8 Wednesday, March 9, 2011
  • 9. Techniques • Unified constructor • Unified configuration • Unified factory • Lazy-loading registry • Dependency management 9 Wednesday, March 9, 2011
  • 10. Typical Constructor class Foo {   protected $_foo;   protected $_bar;   protected $_baz;   public function __construct( $foo = null, $bar = "dib", $baz = "gir" ) {     $this->_foo = $foo;     $this->_bar = $bar;     $this->_baz = $baz;   } } 10 Wednesday, March 9, 2011
  • 11. Unified Constructor class Vendor_Foo {   protected $_Vendor_Foo = array(       "foo" => null,       "bar" => "baz",       "dib" => "gir",   );   protected $_foo;   protected $_bar;   protected $_baz;   public function __construct($config = array())   {     $config = array_merge($this->_Vendor_Foo, $config);     $this->_foo = $config["foo"];     $this->_bar = $config["bar"];     $this->_baz = $config["baz"];   } } 11 Wednesday, March 9, 2011
  • 12. Typical Config File webhost                  = www.example.com database.adapter         = pdo_mysql database.params.host     = db.example.com database.params.username = dbuser database.params.password = secret database.params.dbname   = dbname # what class uses them? # what if different classes use "database" as their key? 12 Wednesday, March 9, 2011
  • 13. Solar Config File <!-- /path/to/config.php --> <?php $values = array(); $values["Solar_Sql"] = array(   "adapter" => "Solar_Sql_Adapter_Mysql",   "host"    => "db.example.com",   "user"    => "dbuser",   "pass"    => "secret",   "name"    => "dbname", ); return $values; ?> <!-- capture return value from include --> <?php $config = include "/path/to/config.php"; ?> 13 Wednesday, March 9, 2011
  • 14. Unified Configuration • Given unique class names, and unified constructor ... • ... configuration keys map directly to class names ... • ... unified configuration mechanism for all classes. $config = array(   "Vendor_Foo" => array(     "foo" => "zim",   ), ); // default values from config file $foo = new Vendor_Foo($config['Vendor_Foo']); 14 Wednesday, March 9, 2011
  • 15. Unified Factory • Solar::factory() instead of `new` keyword // non-adapter $foo = Solar::factory("Vendor_Foo"); // Vendor_Foo with config // adapter: assume that the config file has set the value ... // $config["Solar_Sql"]["host"] = "db1.example.com"; $sql = Solar::factory("Solar_Sql"); // factory a new instance with instance-time config $sql_other = Solar::factory("Solar_Sql", array(   "host" => "db2.example.com", )); 15 Wednesday, March 9, 2011
  • 16. Typical Registry // populate registry entries $db = new DB::factory('mysql'); Registry::set('db', $db); // later, elsewhere $db = Registry::get('db'); 16 Wednesday, March 9, 2011
  • 17. Lazy-Loading Registry // lazy, using default adapter and configs. Solar_Registry::set("sql", "Solar_Sql"); // lazy, via config file $config["Solar"]["registry_set"]["sql"] = "Solar_Sql"; // instantiation $sql = Solar_Registry::get("sql"); 17 Wednesday, March 9, 2011
  • 18. Dependency Management • How to maintain dependencies on other objects? • How to configure, replace, or test the other object? • “Dependency injection” or “service locator” // typical dependency creation public function __construct() {   $this->db = new DB(); } 18 Wednesday, March 9, 2011
  • 19. Dependency Injection // constructor-based dependency injection. // $db = DB::getAdapter(); // $foo = new Foo($db); public function __construct($db) {   $this->db = $db; } // setter-based dependency injection. // $foo = new Foo(); // $db = DB::getAdapter(); // $foo->setDb($db); public function setDb($db) {   $this->db = $db; } 19 Wednesday, March 9, 2011
  • 20. Service Locator // static locator. // $db = DB::getAdapter(); // Locator::set("db", $db); public function __construct() {   $this->db = Locator::get("db"); } // instance locator as dependency injection. // $locator = new Locator(); // $db = DB::getAdapter(); // $locator->set("db", $db); // $foo = new Foo($locator); public function __construct($locator) {   $this->db = $locator->get("db"); } 20 Wednesday, March 9, 2011
  • 21. Solar::dependency() • Combined service locator and dependency injector • Uses a registry key (which may be lazy-loaded) ... • ... or a directly-passed dependency object. Solar::dependency($class_hint, $specification); 21 Wednesday, March 9, 2011
  • 22. Solar::dependency() class Vendor_Foo extends Solar_Base {   public function _postConstruct() { parent::_postConstruct();     $this->_sql = Solar::dependency(       "Solar_Sql",       $this->_config["sql"]     );   } } // inject an object $sql = Solar::factory("Solar_Sql"); $foo = Solar::factory("Vendor_Foo", array("sql" => $sql)); // locate via registry key "sql" Solar_Registry::set("sql", "Solar_Sql"); $foo = Solar::factory("Vendor_Foo", array("sql" => "sql")); 22 Wednesday, March 9, 2011
  • 23. Dependency Config <!-- /path/to/config.php --> <?php // lazy-load Solar_Sql instance as "sql"  $config["Solar"]["registry_set"]["sql"] = "Solar_Sql"; // use "sql" registry key for Vendor_Foo dependency $config["Vendor_Foo"]["sql"] => "sql"; ?> <!-- script file --> <?php // now Vendor_Foo locates the "sql" entry automatically $foo = Solar::factory("Vendor_Foo"); 23 Wednesday, March 9, 2011
  • 24. Dynamic Dispatch Cycle 24 Wednesday, March 9, 2011
  • 25. Web Server + PHP Framework Boot Front Page Action View 25 Wednesday, March 9, 2011
  • 26. Bootstrap $system = dirname(dirname(__FILE__)); set_include_path("$system/include"); require "Solar.php"; $config = "$system/config.php"; Solar::start($config); $front = Solar_Registry::get("controller_front"); $front->display(); Solar::stop(); 26 Wednesday, March 9, 2011
  • 27. Web App Controllers • Independent front and page controllers • URI default format of /controller/action/param/param/param • Front controller determines only the page controller class, not the action or params 27 Wednesday, March 9, 2011
  • 28. Front Controller • Stack of class prefixes, e.g. Vendor_App • /foo/bar/baz => Vendor_App_Foo 28 Wednesday, March 9, 2011
  • 29. Front Controller • Dynamic rewriter • Static routing $config["Solar_Controller_Front"]["replace"] = array(   "{:alnum}" => "([a-zA-Z0-9]+)", ); $config["Solar_Controller_Front"]["rewrite"] = array(   "page/{:alnum}/edit" => "page/edit/$1", ); $config["Solar_Controller_Front"]["routing"] = array(   "page" => "Other_App_Zim", ); 29 Wednesday, March 9, 2011
  • 30. Front Controller • Named actions <?php $config["Solar_Controller_Front"]["rewrite"]["edit-page"] = array(     'pattern' => 'page/{:id}/edit',     'rewrite' => 'page/edit/$1',     'replace' => array(         '{:id}' => '(d+)',     ),     'default' => array(         '{:id}' => 88,     ); ); // then in a view: echo $this->namedAction('edit-page', array('id' => 70)); 30 Wednesday, March 9, 2011
  • 31. Page Controller • Looks at remaining portion of URI path and picks action • /foo/bar/baz => Vendor_App_Foo • public function actionBar($param) • preRun(), preAction(), postAction(), postRun(), preRender(), postRender() 31 Wednesday, March 9, 2011
  • 32. Package Highlights 32 Wednesday, March 9, 2011
  • 33. • SQL adapters • ORM system • Form generation • CLI tooling • Auth, Role, Access 33 Wednesday, March 9, 2011
  • 34. SQL Adapters • Adapters for Mysql, Pgsql, Sqlite, Sqlite2, Oracle • PDO-based, multiple fetch*() styles • Standardized insert(), update(), delete() • Abstracted LIMIT, column types, table creation, index creation, sequences, auto-increment, column description, index description 34 Wednesday, March 9, 2011
  • 35. Prepared Statements • Named placeholders and bound values $sql = Solar::factory("Solar_Sql"); $stmt = "SELECT * FROM students WHERE name = :name"; $bind = array(   "name"  => "Bob'; DROP TABLE students;--", ); $list = $sql->fetchAll($stmt, $bind); 35 Wednesday, March 9, 2011
  • 36. Query Builder • Programmatically build complex SELECT statements $select = Solar::factory("Solar_Sql_Select"); $select->from("table", array("col", "col", ...))        ->join()      // leftJoin(), innerJoin()        ->where("col = ?", $value)        ->group()        ->having()        ->union()     // unionAll()        ->order()        ->limit()     // page(), paging()        ->fetchAll(); // fetchOne(), fetchPairs(), etc 36 Wednesday, March 9, 2011
  • 37. MysqlReplicated • Adapter picks master or slave • Switch to/from non-replicated with no code changes • Automatic “gap” (GET-after-POST) management $config["Solar_Sql_Adapter_MysqlReplicated"] = array(   "host" => "master.db.example.com",   // ...   "slaves" => array(     0 => array("host" => "slave1.db.example.com"),     1 => array("host" => "slave2.db.example.com"),   ), ); 37 Wednesday, March 9, 2011
  • 38. ORM System • TableDataGateway + DataMapper Model objects • Record objects (with relateds) • Collection of Record objects • Relationship definition objects • Catalog for model objects • Uses underlying SQL layers 38 Wednesday, March 9, 2011
  • 39. Model Setup class Vendor_Model_Invaders extends Solar_Sql_Model {   protected function _setup() {     $this->_table_name = "invaders"; // default          // reads columns from table, or can be stored in:     // $this->_table_cols = array(...);          // each record has these relateds:     $this->_belongsTo("irk");     $this->_hasOne("robot");     $this->_hasMany("weapons");     $this->_hasMany("invasions");     $this->_hasManyThrough("planets", "invasions");   } } 39 Wednesday, March 9, 2011
  • 40. Relationship Definitions 'merge'          => merge data at 'server' (DB) or 'client'  (PHP) 'native_by'      => 'wherein' or 'select' when matching natives 'native_col'     => native col to match against foreign col 'foreign_class'  => class name of the foreign model 'foreign_alias'  => alias of the foreign table name 'foreign_col'    => foreign col to match against the native col 'cols'           => fetch these foreign cols 'conditions'     => where or join-on conditions 'foreign_key'    => magic shorthand for the foreign key col 'order'          => how to order related rows ... plus fetch-time params and eager-fetch params. 40 Wednesday, March 9, 2011
  • 41. Fetching $model = Solar_Registry::get("model_catalog"); $collection = $model->invaders->fetchAll(array(   "where"   => array("type = ?" => "short"),   "group"   => ...   "order"   => ...   "page"    => ...   "paging"  => ...   "eager"   => array("weapons", "robot", "planets"),   ... )); $array  = $model->invaders->fetchAllAsArray(array(...)); $record = $model->invaders->fetchOne(array(...)); 41 Wednesday, March 9, 2011
  • 42. Records $zim = $model->invaders->fetchOne(array(   "where" = array("name = ?" => "Zim") )); echo $zim->doom; $zim->enemy = "Dib"; foreach ($zim->weapons as $weapon) {   echo $weapon->name; } $zim->weapons->appendNew(array("name" => "raygun")); $zim->save(); 42 Wednesday, March 9, 2011
  • 43. Record Filters • Solar_Filter, Solar_Filter_Validate*, Solar_Filter_Sanitize* as generally-available classes, not regular expressions • Vendor_Model_* will use Vendor_Filter_* automatically • Applied on $record->save() automatically <?php class Vendor_Model_Invaders extends Solar_Sql_Model_Record {   protected function _setup() {     // ...     $this->_addFilter("bar", "validateAlnum");     $this->_addFilter("foo", "validateInList", array(         "one", "two", "three",     ));     $this->_addFilter("baz", "validateCustomThing");   } } 43 Wednesday, March 9, 2011
  • 44. Form Generation $zim  = $model->invaders->fetch($id); $form = $zim->newForm(); // Solar_Form object $view = Solar::factory("Solar_View"); $html = $view->form()              ->auto($form)              ->addProcessGroup("save", "cancel"); echo $html; // automatic CSRF protection 44 Wednesday, March 9, 2011
  • 45. Much More Model • Single-table inheritance • Calculated and virtual columns • Auto serializing of columns (arrays) • Auto XML structs (EAV) • Auto creation of tables and indexes • Auto count-pages at fetch time 45 Wednesday, March 9, 2011
  • 46. CLI Tooling $ ./script/solar make-vendor Vendor $ ./script/solar make-model Vendor_Model_Invaders $ ./script/solar make-app Vendor_App_Zim --model-name=invaders # make-docs, make-tests, run-tests, link-public, ... 46 Wednesday, March 9, 2011
  • 47. CLI Controllers • Independent “console” (front) and “command” (page) controllers • Direct output with _out(), _outln(), _err(), _errln() • VT100 escape codes built in • Vendor-specific invocation • ./script/vendor command-name 47 Wednesday, March 9, 2011
  • 48. Auth, Role, Access • Auth adapters (SQL, LDAP, email, etc.) • Role adapters (File, SQL) • Access adapters (File, SQL) • User class is composed of these 48 Wednesday, March 9, 2011
  • 49. Project Architecture 49 Wednesday, March 9, 2011
  • 50. System Directories system/   config.php    # config file   config/       # config support   docroot/      # vhost document root     index.php   # bootstrap     public/     # copies or symlinks to public assets   include/      # symlinks to PHP files   script/       # command-line scripts   source/       # actual PHP and support files   sqlite/       # sqlite databases   tmp/          # sessions, logs, caches, etc 50 Wednesday, March 9, 2011
  • 51. Source vs. Include include/       # single include-path for PHP files   Solar/       # symlink to source/solar/Solar   Solar.php    # symlink to source/solar/Solar.php   Vendor/      # symlink to source/vendor/Vendor   some.php     # symlink to source/other/some.php   else.php     # symlink to source/other/else.php source/        # all "real" files for a vendor   solar/       # solar files     config/     Solar.php     Solar/       ...   vendor/      # vendor files     Vendor/   other/       # random assortments of 3rd-party libs     some.php     else.php 51 Wednesday, March 9, 2011
  • 52. Typical Page and View framework/          # libraries application/           # separate include path   controllers/     FooController.php  # actions "bar" and "dib"     ZimController.php  # extends Foo   views/     foo/       bar.php       dib.php     zim/       bar.php       dib.php   layouts/     default.php   public/ 52 Wednesday, March 9, 2011
  • 53. Solar Page And View Solar/               # libraries Vendor/              # same include path   App/     Foo.php          # actions "bar" and "dib"     Foo/       Layout/         default.php       Public/       View/         bar.php         dib.php     Zim.php          # extends Foo     Zim/       View/          # inherits Foo views         dib.php      # override view 53 Wednesday, March 9, 2011
  • 54. Performance Indicators 54 Wednesday, March 9, 2011
  • 55. Benchmarks • Google “web framework benchmarks” • Amazon EC2 “Large” instance • Apache, mod_php 5.3.2, APC • 10 concurrent users, no sessions • 5 runs of 1 minute each, pre-warmed cache 55 Wednesday, March 9, 2011
  • 56. Results Table Framework | relative | average --------------------- | -------- | -------- baseline/html | 1.2823 | 3220.56 baseline/php | 1.0000 | 2511.54 lithium/0.9.9 | 0.0827 | 207.62 solar/1.1.1 | 0.1609 | 404.17 symfony/1.4.8 | 0.0784 | 196.91 symfony/2.0.0pr4 | 0.0897 | 225.22 yii/1.1.5 | 0.1891 | 474.82 zend/1.10.2-minapp | 0.1136 | 285.28 zend/1.10.2-project | 0.0832 | 208.84 56 Wednesday, March 9, 2011
  • 57. Results Graph lithium/0.9.9 0.08 solar/1.1.1 0.16 symfony/1.4.8 0.08 symfony/2.0.0pr4 0.09 yii/1.1.5 0.19 zend/1.10.2-minapp 0.11 zend/1.10.2-project 0.08 0 0.05 0.10 0.15 0.20 57 Wednesday, March 9, 2011
  • 58. • Be suspicious of benchmarks • Only one data-point in decision making • Measures only what you test • https://github.com/pmjones/php- framework-benchmarks 58 Wednesday, March 9, 2011
  • 59. Conclusion • Foundational concepts and techniques • Dispatch cycle • Package highlights • Project architecture • Performance indicators • Stable, mature, proven 59 Wednesday, March 9, 2011
  • 60. Aura Project for PHP 5.3+ aka Solar version 2.0 60 Wednesday, March 9, 2011
  • 61. Changes • Aura (Solar vs Solr) • PHP 5.3+ (namespaces, closures, etc) • DI proper instead of combo SL/DI • Extract Solar functionality • Independent library packages • “System” package to create a framework 61 Wednesday, March 9, 2011
  • 62. Packages • Autoloader • DI (constructor/setter) • Signal slots / event handler • Web router • CLI controllers • “System” • Next: web controllers and views 62 Wednesday, March 9, 2011
  • 63. Where? • https://github.com/auraphp • http://groups.google.com/group/auraphp • #auraphp on Freenode 63 Wednesday, March 9, 2011
  • 64. Thanks! http://solarphp.com http://auraphp.github.com http://joind.in/2814 64 Wednesday, March 9, 2011