SlideShare a Scribd company logo
1 of 65
Download to read offline
Solar for PHP 5
The Best Framework You’ve Never Heard Of

             Paul M. Jones
           ConFoo, Montréal
             11 Mar 2010

           http://joind.in/1350
Read This
About Me
•   Web Architect

•   PHP since 1999 (PHP 3)

•   Savant Template System
    (phpsavant.com)

•   PEAR: DB_Table, Text_Wiki

•   PEAR Group (2007-2008)

•   Zend Framework

•   Web framework benchmarks
“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)
• Built to be configurable, adaptable, scalable
Library/Framework
             Progression
                         Zend
               PEAR   Framework         Solar

Lib                                                 FW


      PhpClasses              Lithium      Cake,
                                          Symfony
Overview

• Foundational concepts and techniques
• Dispatch cycle
• Package highlights
• Project architecture
• Performance indicators
Foundations
PEAR Standards
• pear.php.net
• 10 years of public usage and vetting
• Coding style guide
• Vendor- or name-spaces
• Class-to-file naming convention
      <?php class Vendor_Foo_Bar {
        // Vendor/Foo/Bar.php
      }
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
Techniques

• Unified constructor
• Unified configuration
• Unified factory
• Lazy-loading registry
• Dependency management
Typical Constructor
class Foo {
  protected $_foo;
  public function __construct($foo = null)
  {
    $this->_foo = $foo;
  }
}
Typical Constructor
class Bar extends Foo {
  protected $_bar;
  protected $_baz;
  public function __construct($foo = null,
    $bar = "dib", $baz = "gir")
  {
    parent::__construct($foo)
    $this->_bar = $bar;
    $this->_baz = $baz;
  }
}
Unified Constructor
class Vendor_Foo {
  
  protected $_default = array("foo" => null);
  
  protected $_foo;
  
  public function __construct($config = array())
   {
    $config = array_merge($this->_default, $config);
    $this->_foo = $config["foo"];
  }
}
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?
Solar Config File
<!-- /path/to/config.php -->
<?php
$config = array();
$config["Solar_Sql"] = array(
  "adapter" => "Solar_Sql_Adapter_Mysql",
  "host"    => "db.example.com",
  "user"    => "dbuser",
  "pass"    => "secret",
  "name"    => "dbname",
);

return $config;
?>

<!-- capture return value from include -->
<?php $array = include "/path/to/config.php"; ?>
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();

     // instance-time values
     $foo = new Vendor_Foo(array(
         'foo' => 'irk',
     ));
Config Inheritance
class Vendor_Foo extends Solar_Base {
  protected $_Vendor_Foo = array("foo" => null);
}

class Vendor_Bar extends Vendor_Foo {
  protected $_Vendor_Bar = array(
      "bar" => "dib",
      "baz" => "gir",
  );
}

// Vendor_Bar will magically have all the default
// config values of Vendor_Foo
Typical Adapter Pattern
• Typical adapter instantiation makes it difficult to apply
  automatic configuration

• Different instantiation (static method instead of new)
• You need to remember if its an adapter or not
• Class limited
  // typical adapter pattern for a new instance
  $db = DB::getAdapter("mysql"); // DB_Adapter_Mysql

  // or by pre-configured singleton
  $db = DB::getInstance(); // DB_Adapter_Mysql
Unified Factory
 • Solar::factory() intercepts and recognizes
    adapter calls
// non-adapter
$bar = Solar::factory("Vendor_Bar"); // Vendor_Bar

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

// factory a new instance with instance-time config
$sql_other = Solar::factory("Solar_Sql", array(
  "adapter" => "Solar_Sql_Adapter_Mysql",
));
Typical Registry
// populate registry entries
$db = new DB::factory('mysql');
Registry::set('db', $db);

// later, elsewhere
$db = Registry::get('db');
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");
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 = DB::getAdapter();
      }
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;
}
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");
}
Solar::dependency()
    • Combined service locator and dependency injector
    • Uses a registry key (which may be lazy-loaded) ...
    • ... or a directly-passed dependency object ...
    • ... or creates the dependency object internally.
Solar::dependency($class_hint, $specification);
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"));

// create instance inside the target
$foo = Solar::factory("Vendor_Foo", array("sql" => null));
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");
Dynamic Dispatch Cycle
Web Server + PHP
         Framework
Boot   Front   Page   Action   View
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();
Web App Controllers

• Independent front and page controllers
• URIs always in format of
  /controller/action/param/param/param

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


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

• Multiple prefixes? Uses first one.
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",
);
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));
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()
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/
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
Package Highlights
• SQL adapters
• ORM system
• Form generation
• CLI tooling
• Auth, Role, Access
SQL Adapters
• Adapters for Mysql, Pgsql, Sqlite, Sqlite2, Oracle ...
  Mssql forthcoming
• PDO-based, multiple fetch*() styles
• Standardized insert(), update(), delete()
• Abstracted LIMIT, column types, table creation,
  index creation, sequences, auto-increment,
  column description, index description
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);
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
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"),
  ),
);
ORM System
• TableDataGateway + DataMapper
  Model objects
• Rowset Collection objects
• Row-and-relateds Record objects
• Relationship definition objects
• Catalog for model objects
• Uses underlying SQL layers
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");
  }
}
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.
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(...));
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();
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");
  }
}
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
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
• Auto caching and cache-versioning
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, ...
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
Auth, Role, Access

• Auth adapters (SQL, LDAP, email, etc.)
• Role adapters (File, SQL)
• Access adapters (File, SQL)
• User class is composed of these
Project Architecture
System Directories
project-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
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
Performance Indicators
Benchmarks

• Google “web framework benchmarks”
• Amazon EC2 “Large” instance
• Apache, mod_php 5.3.2, APC
• 10 concurrent users, session enabled
• 5 runs of 1 minute each, pre-warmed cache
Results Table
framework                  |      rel |      avg
------------------------   | -------- | --------
baseline-html              |   1.1644 | 5366.99
baseline-php               |   1.0000 | 4609.12
lithium-0.6                |   0.0913 |   420.61
solar-1.0.0                |   0.1178 |   543.15
symfony-2.0.0alpha1        |   0.1351 |   622.88
zend-1.10.2                |   0.0523 |   241.17
solar-1.0.0-preload        |   0.1619 |   746.30
zend-1.10.2-min            |   0.0832 |   383.30
Results Graph
          lithium 0.6
          solar-1.0.0
symfony-2.0.0alpha1
         zend-1.10.2
 solar-1.0.0-preload
            zend-min
                        0   200   400   600   800
• Be suspicious of benchmarks
• Only one data-point in decision making
• Measures only what you test
Conclusion

• Foundational concepts and techniques
• Dispatch cycle
• Package highlights
• Project architecture
• Performance indicators
Solar is Stable!
Thanks!

http://solarphp.com

  http://joind.in/1350

More Related Content

What's hot

Ruby on Rails 101 - Presentation Slides for a Five Day Introductory Course
Ruby on Rails 101 - Presentation Slides for a Five Day Introductory CourseRuby on Rails 101 - Presentation Slides for a Five Day Introductory Course
Ruby on Rails 101 - Presentation Slides for a Five Day Introductory Coursepeter_marklund
 
Ruby on Rails Security
Ruby on Rails SecurityRuby on Rails Security
Ruby on Rails Securityamiable_indian
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Fabien Potencier
 
Yapc10 Cdt World Domination
Yapc10   Cdt World DominationYapc10   Cdt World Domination
Yapc10 Cdt World DominationcPanel
 
Drupal 8 - Core and API Changes
Drupal 8 - Core and API ChangesDrupal 8 - Core and API Changes
Drupal 8 - Core and API ChangesShabir Ahmad
 
Building and managing java projects with maven part-III
Building and managing java projects with maven part-IIIBuilding and managing java projects with maven part-III
Building and managing java projects with maven part-IIIprinceirfancivil
 
When Sightly Meets Slice by Tomasz Niedźwiedź
When Sightly Meets Slice by Tomasz NiedźwiedźWhen Sightly Meets Slice by Tomasz Niedźwiedź
When Sightly Meets Slice by Tomasz NiedźwiedźAEM HUB
 
Building and Managing Projects with Maven
Building and Managing Projects with MavenBuilding and Managing Projects with Maven
Building and Managing Projects with MavenKhan625
 
How to learn to build your own PHP framework
How to learn to build your own PHP frameworkHow to learn to build your own PHP framework
How to learn to build your own PHP frameworkDinh Pham
 
Staying Sane with Drupal (A Develper's Survival Guide)
Staying Sane with Drupal (A Develper's Survival Guide)Staying Sane with Drupal (A Develper's Survival Guide)
Staying Sane with Drupal (A Develper's Survival Guide)Oscar Merida
 
Spring framework
Spring frameworkSpring framework
Spring frameworkAircon Chen
 
Sightly - AEM6 UI Development using JS and JAVA
Sightly - AEM6 UI Development using JS and JAVASightly - AEM6 UI Development using JS and JAVA
Sightly - AEM6 UI Development using JS and JAVAYash Mody
 
Spring Framework - MVC
Spring Framework - MVCSpring Framework - MVC
Spring Framework - MVCDzmitry Naskou
 

What's hot (20)

Ruby on Rails 101 - Presentation Slides for a Five Day Introductory Course
Ruby on Rails 101 - Presentation Slides for a Five Day Introductory CourseRuby on Rails 101 - Presentation Slides for a Five Day Introductory Course
Ruby on Rails 101 - Presentation Slides for a Five Day Introductory Course
 
Ruby on Rails Security
Ruby on Rails SecurityRuby on Rails Security
Ruby on Rails Security
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3
 
Yapc10 Cdt World Domination
Yapc10   Cdt World DominationYapc10   Cdt World Domination
Yapc10 Cdt World Domination
 
Drupal 8 - Core and API Changes
Drupal 8 - Core and API ChangesDrupal 8 - Core and API Changes
Drupal 8 - Core and API Changes
 
Wt unit 1 ppts web development process
Wt unit 1 ppts web development processWt unit 1 ppts web development process
Wt unit 1 ppts web development process
 
Building and managing java projects with maven part-III
Building and managing java projects with maven part-IIIBuilding and managing java projects with maven part-III
Building and managing java projects with maven part-III
 
When Sightly Meets Slice by Tomasz Niedźwiedź
When Sightly Meets Slice by Tomasz NiedźwiedźWhen Sightly Meets Slice by Tomasz Niedźwiedź
When Sightly Meets Slice by Tomasz Niedźwiedź
 
Building and Managing Projects with Maven
Building and Managing Projects with MavenBuilding and Managing Projects with Maven
Building and Managing Projects with Maven
 
Wt unit 3 server side technology
Wt unit 3 server side technologyWt unit 3 server side technology
Wt unit 3 server side technology
 
How to learn to build your own PHP framework
How to learn to build your own PHP frameworkHow to learn to build your own PHP framework
How to learn to build your own PHP framework
 
HTML5 Refresher
HTML5 RefresherHTML5 Refresher
HTML5 Refresher
 
Staying Sane with Drupal (A Develper's Survival Guide)
Staying Sane with Drupal (A Develper's Survival Guide)Staying Sane with Drupal (A Develper's Survival Guide)
Staying Sane with Drupal (A Develper's Survival Guide)
 
20jsp
20jsp20jsp
20jsp
 
Maven
MavenMaven
Maven
 
Spring framework
Spring frameworkSpring framework
Spring framework
 
10 jsp-scripting-elements
10 jsp-scripting-elements10 jsp-scripting-elements
10 jsp-scripting-elements
 
Sightly - AEM6 UI Development using JS and JAVA
Sightly - AEM6 UI Development using JS and JAVASightly - AEM6 UI Development using JS and JAVA
Sightly - AEM6 UI Development using JS and JAVA
 
Spring Framework - MVC
Spring Framework - MVCSpring Framework - MVC
Spring Framework - MVC
 
Laravel 5
Laravel 5Laravel 5
Laravel 5
 

Viewers also liked

How Do We Get The Deficit To Zero?
How Do We Get The Deficit To Zero?How Do We Get The Deficit To Zero?
How Do We Get The Deficit To Zero?Paul Jones
 
Same Thing Happens Every Time
Same Thing Happens Every TimeSame Thing Happens Every Time
Same Thing Happens Every TimePaul Jones
 
All You Jokers
All You JokersAll You Jokers
All You JokersPaul Jones
 
Framework and Application Benchmarking
Framework and Application BenchmarkingFramework and Application Benchmarking
Framework and Application BenchmarkingPaul Jones
 
Decoupled Libraries for PHP
Decoupled Libraries for PHPDecoupled Libraries for PHP
Decoupled Libraries for PHPPaul Jones
 
How To Train Your Manager
How To Train Your ManagerHow To Train Your Manager
How To Train Your ManagerPaul Jones
 
Action-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
Action-Domain-Responder: A Web-Specific Refinement of Model-View-ControllerAction-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
Action-Domain-Responder: A Web-Specific Refinement of Model-View-ControllerPaul Jones
 
Career and Life Management
Career and Life ManagementCareer and Life Management
Career and Life ManagementPaul Jones
 

Viewers also liked (8)

How Do We Get The Deficit To Zero?
How Do We Get The Deficit To Zero?How Do We Get The Deficit To Zero?
How Do We Get The Deficit To Zero?
 
Same Thing Happens Every Time
Same Thing Happens Every TimeSame Thing Happens Every Time
Same Thing Happens Every Time
 
All You Jokers
All You JokersAll You Jokers
All You Jokers
 
Framework and Application Benchmarking
Framework and Application BenchmarkingFramework and Application Benchmarking
Framework and Application Benchmarking
 
Decoupled Libraries for PHP
Decoupled Libraries for PHPDecoupled Libraries for PHP
Decoupled Libraries for PHP
 
How To Train Your Manager
How To Train Your ManagerHow To Train Your Manager
How To Train Your Manager
 
Action-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
Action-Domain-Responder: A Web-Specific Refinement of Model-View-ControllerAction-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
Action-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
 
Career and Life Management
Career and Life ManagementCareer and Life Management
Career and Life Management
 

Similar to The Solar Framework for PHP 5 (2010 Confoo)

Performance tuning with zend framework
Performance tuning with zend frameworkPerformance tuning with zend framework
Performance tuning with zend frameworkAlan Seiden
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207patter
 
Getting up & running with zend framework
Getting up & running with zend frameworkGetting up & running with zend framework
Getting up & running with zend frameworkSaidur Rahman
 
Zend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolZend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolGordon Forsythe
 
Head First Zend Framework - Part 1 Project & Application
Head First Zend Framework - Part 1 Project & ApplicationHead First Zend Framework - Part 1 Project & Application
Head First Zend Framework - Part 1 Project & ApplicationJace Ju
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5Darren Craig
 
The Solar Framework for PHP
The Solar Framework for PHPThe Solar Framework for PHP
The Solar Framework for PHPConFoo
 
Staying Sane with Drupal NEPHP
Staying Sane with Drupal NEPHPStaying Sane with Drupal NEPHP
Staying Sane with Drupal NEPHPOscar Merida
 
Symfony CMF - PHP Conference Brazil 2011
Symfony CMF - PHP Conference Brazil 2011Symfony CMF - PHP Conference Brazil 2011
Symfony CMF - PHP Conference Brazil 2011Jacopo Romei
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Racksickill
 
Submit PHP: Standards in PHP world. Михайло Морозов
Submit PHP: Standards in PHP world. Михайло МорозовSubmit PHP: Standards in PHP world. Михайло Морозов
Submit PHP: Standards in PHP world. Михайло МорозовBinary Studio
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐいHisateru Tanaka
 
Simplify your professional web development with symfony
Simplify your professional web development with symfonySimplify your professional web development with symfony
Simplify your professional web development with symfonyFrancois Zaninotto
 
PHP from soup to nuts Course Deck
PHP from soup to nuts Course DeckPHP from soup to nuts Course Deck
PHP from soup to nuts Course DeckrICh morrow
 
BP-6 Repository Customization Best Practices
BP-6 Repository Customization Best PracticesBP-6 Repository Customization Best Practices
BP-6 Repository Customization Best PracticesAlfresco Software
 
Supercharging WordPress Development in 2018
Supercharging WordPress Development in 2018Supercharging WordPress Development in 2018
Supercharging WordPress Development in 2018Adam Tomat
 

Similar to The Solar Framework for PHP 5 (2010 Confoo) (20)

Performance tuning with zend framework
Performance tuning with zend frameworkPerformance tuning with zend framework
Performance tuning with zend framework
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
 
Getting up & running with zend framework
Getting up & running with zend frameworkGetting up & running with zend framework
Getting up & running with zend framework
 
Getting up and running with Zend Framework
Getting up and running with Zend FrameworkGetting up and running with Zend Framework
Getting up and running with Zend Framework
 
Zend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolZend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_Tool
 
Head First Zend Framework - Part 1 Project & Application
Head First Zend Framework - Part 1 Project & ApplicationHead First Zend Framework - Part 1 Project & Application
Head First Zend Framework - Part 1 Project & Application
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5
 
The Solar Framework for PHP
The Solar Framework for PHPThe Solar Framework for PHP
The Solar Framework for PHP
 
Fatc
FatcFatc
Fatc
 
Staying Sane with Drupal NEPHP
Staying Sane with Drupal NEPHPStaying Sane with Drupal NEPHP
Staying Sane with Drupal NEPHP
 
Symfony CMF - PHP Conference Brazil 2011
Symfony CMF - PHP Conference Brazil 2011Symfony CMF - PHP Conference Brazil 2011
Symfony CMF - PHP Conference Brazil 2011
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Rack
 
Submit PHP: Standards in PHP world. Михайло Морозов
Submit PHP: Standards in PHP world. Михайло МорозовSubmit PHP: Standards in PHP world. Михайло Морозов
Submit PHP: Standards in PHP world. Михайло Морозов
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Simplify your professional web development with symfony
Simplify your professional web development with symfonySimplify your professional web development with symfony
Simplify your professional web development with symfony
 
PHP from soup to nuts Course Deck
PHP from soup to nuts Course DeckPHP from soup to nuts Course Deck
PHP from soup to nuts Course Deck
 
Hibernate java and_oracle
Hibernate java and_oracleHibernate java and_oracle
Hibernate java and_oracle
 
BP-6 Repository Customization Best Practices
BP-6 Repository Customization Best PracticesBP-6 Repository Customization Best Practices
BP-6 Repository Customization Best Practices
 
Supercharging WordPress Development in 2018
Supercharging WordPress Development in 2018Supercharging WordPress Development in 2018
Supercharging WordPress Development in 2018
 
CakePHP
CakePHPCakePHP
CakePHP
 

Recently uploaded

Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Exploring ChatGPT Prompt Hacks To Maximally Optimise Your Queries
Exploring ChatGPT Prompt Hacks To Maximally Optimise Your QueriesExploring ChatGPT Prompt Hacks To Maximally Optimise Your Queries
Exploring ChatGPT Prompt Hacks To Maximally Optimise Your QueriesSanjay Willie
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 

Recently uploaded (20)

Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Exploring ChatGPT Prompt Hacks To Maximally Optimise Your Queries
Exploring ChatGPT Prompt Hacks To Maximally Optimise Your QueriesExploring ChatGPT Prompt Hacks To Maximally Optimise Your Queries
Exploring ChatGPT Prompt Hacks To Maximally Optimise Your Queries
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 

The Solar Framework for PHP 5 (2010 Confoo)