SlideShare una empresa de Scribd logo
1 de 65
Descargar para leer sin conexión
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

Más contenido relacionado

La actualidad más candente

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
 

La actualidad más candente (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
 

Destacado

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
 

Destacado (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 a 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 a 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
 

Último

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 

Último (20)

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 

The Solar Framework for PHP 5 (2010 Confoo)