SlideShare a Scribd company logo
How to learn to build  your own PHP framework Bridging the gap between PHP, OOP and Software Architecture Pham Cong Dinh (a.k.a pcdinh) Software Developer Hanoi PHP Day - December 2008 Hanoi - Vietnam
Introduction A foundation member of JavaVietnam since 2003 ( http://www.javavietnam.org ) A foundation member of PHPVietnam Discussion Group since 2004 ( http://groups.google.com/group/phpvietnam ) Lead web developer with World’Vest Base Inc. Java is my first love since 1999 PHP is my real lover since 2003. I love the way PHP community works Sometimes I works on Python, Ruby, Erlang I am a strong believer in dynamic programming languages, JavaScript, web standards, convergence of web as a platform and Outsourcing 2.0 I spent 2 years to play with my framework named Pone (PHP One)
Objectives Where is PHP now? It is changing. Enterprise oriented: which is driven by Yahoo, Facebook, Zend, Sun/MySQL, Oracle, OmniTI … PHP is too big. It can not just be ignored Object Oriented Programming adoption Increased complexity of web applications Web vs. Adobe Air, MS Silverlight, JavaFX, Google Native Client Trends Will Move Applications to the Web: Consumer Innovation Setting the Pace, Rise of the Power Collaborator, New Economics of Scale for IT, Barriers to Adoption Are Falling Scale-out wins Understanding what framework designers think Building up shared mindsets Providing food for thought
Agenda – 40 slides Making judgments Top notch frameworks and their shortcomings A broader view on your framework Lessons to learn
Making judgments Common wisdom: Reinventing the wheel Good You know it inside and out You control its pace It fits your needs. Sometimes, your need is unique It teaches you how the world around you works License: This is why GPL is sometime a bad thing Bad You may not as good as other ones No community No outside contributors Reinventing the square wheel
Making judgments To develop a framework is just like to set up a business Think of your limitation: time, resources, knowledge to build/test/document/maintain your own mental baby Know your team: how to train them Know the market : known frameworks in the market. Sometimes your needs are satisfied to some extent in several little-known frameworks Starts with pencil and paper: its components and how they interact Starts with API: learn how to design an API first You never do it right from day one
Know the market CakePHP shortcomings Zend Framework shortcomings Third party frameworks shortcomings
Know the market - CakePHP Misleading terms: plugin, model…  Plugin: CakePHP allows you to set up a combination of controllers, models, and views and release them as a packaged application   Too database centric:  CakePHP naming convention is driven by table names, not dependency injection mechanism. Admin routing sucks: why do we need one-and-only backend for the whole application/plugin/etc…? Flat application structure: plugin/controller/action and no more. Global space constants
Know the market - CakePHP No elegant way to change media file (css, javascript, meta content) on each layout page, controlled by a Controller. <head>     <?php echo $html->charset(); ?>     <title>           <?php echo $title_for_layout; ?>     </title>     <?php       echo $html->css('cake.generic');       echo $javascript->link('prototype-1.6.0.2');       echo $scripts_for_layout;       echo $html->meta('icon','/myapp/img/favicon.ico', array  ('type' =>'icon'));     ?>  </head>
Know the market - CakePHP loadModel(), loadController() are not about dependency injection E.x: You want to provide access to a model from a Component Say you have a model called FooBar in a file called foo_bar.php loadModel ('FooBar');   $this ->FooBar = & new  FooBar();   loadModel() maybe deprecated in favor of   App::import ('Model', 'ModelName');
Know the market - CakePHP beforeFilter(), afterFilter() are coupled with a certain controller (controller is a heavy object. It should avoid being hit too soon) <?php    class   AppController   extends   Controller  {       var   $beforeFilter  =  array ( 'checkAccess' );       var   $components  =  array ( 'Acl' );       function   checkAccess() {      }  }  ?>
Know the market - CakePHP Reuse of view via elements with  requestAction()  is bad and expensive The dispatcher is called for each call to a controller (routing, figures out what (Plugin)/Controller/Action is request, loops through all $paths->controllerPaths files, to figure out what Controller to load)  The controller is set up again Behavior: controllerActAsModel Controller is an interface to another tier Controller is not designed to provide data for internal components Cache unfriendly
Know the market - CakePHP Caching hits its hard time because there is no way to get generated view content <?php  $this->element('helpbox', array(&quot;cache&quot; => array('time'=> &quot;+7 days&quot;,'key'=>'unique value')));  ?>   What about URL-based caching, session/cookie-based caching, geo-based caching, date-based caching (there are a lot of things to tell about CakePHP but it is all for today)
Know the market – Zend Framework Zend Framework tries to be a better PEAR Powered by a solid foundation A solid and controllable licensing (CLA) More strictly controlled development environment Enterprise-oriented class library A well-defined roadmap and versioning Zend Framework is a glue framework or framework-oriented class library
Know the market – Zend Framework Zend Framework is extremely big and bloated Zend Framework 1.6.2: 1261 file, 267 folders Zend_Mail: 33 files Zend_Pdf: 89 files Zend_Controller: 50 files Zend_View: 57 files Drupal includes folders: 33 files Zend Framework is designed most like Java frameworks Small class file Lot of classes: object graph is hard (see next) Atomic responsibility Strongly embrace design patterns
 
Know the market – Zend Framework Everything is an object, even a HTML button or checkbox. The same to Java (see Apache Wicket, Tapestry, JBoss Seam) class  Zend_View_Helper_FormReset  extends  Zend_View_Helper_FormElement { public   function  formReset($name = '', $value = 'Reset', $attribs = null) { $info = $this->_getInfo($name, $value, $attribs); extract ($info); // name, value, attribs, options, listsep, disable // check if disabled $disabled = ''; if  ($disable) { $disabled = ' disabled=&quot;disabled&quot;'; } // get closing tag $endTag = '>'; if ($this->view->doctype()->isXhtml()) { $endTag = ' />'; } // Render button $xhtml = '<input type=&quot;reset&quot;' . ' name=&quot;' . $this->view->escape($name) . '&quot;' . ' id=&quot;' . $this->view->escape($id) . '&quot;' . $disabled; . . . . . . . . .  } }
Know the market – Zend Framework What Zend Framework brings Lot of files are loaded per request which is a bad thing for a dynamic, interpreted language and stateless platform like PHP Much more memory usage Bad thing for PHP memory management model in which memory is allocated in small chunks Zend Framework code: There are lot of require_once() call inside an if statement which is bad for opcode caching mechanism Zend Framework leaves shared hosting in the cold.  700 sites per server are quite normal No control over file system optimization No control over memory No control over opcode caching
Know the market – Zend Framework A glue framework requires you to know every concrete class and how to use them in a application life cycle A lot of things to consider means bootstrapping is a mess
Know the market – Zend Framework define ('ROOT_DIR', dirname(dirname(dirname(__FILE__)))); define ('APP_DIR',dirname(dirname(__FILE__))); set_include_path ('.' . PATH_SEPARATOR . APP_DIR . '/lib/' . PATH_SEPARATOR . APP_DIR . '/application/default/models/' . PATH_SEPARATOR . ROOT_DIR . '/shared/lib/' . PATH_SEPARATOR . get_include_path()); //This requires that your Zend library lies in ROOT_DIR/shared/lib/ //make classes autoload without doing require require_once ('Zend/Loader.php'); Zend_Loader::registerAutoload(); if ( defined ('ENV') !== TRUE) { define ('ENV','production'); //change staging to production to go to production settings } $config = new Zend_Config_Xml(APP_DIR . '/config/config.xml', ENV); Zend_Registry::set('config',$config); //init session $session =  new  Zend_Session_Namespace($config->session_name); Zend_Registry::set('session',$session); Zend_Db_Table::setDefaultAdapter(Zend_Db::factory(Zend_Registry::get('config')->database)); /** * Init the Smarty view wrapper and set smarty suffix to the view scripts. */ $view =  new  EZ_View_Smarty($config->smarty->toArray());
Know the market – Zend Framework // use the viewrenderer to keep the code DRY instantiate and add the helper in one go $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer'); $viewRenderer->setView($view); $viewRenderer->setViewSuffix($config->smarty->suffix); /** * Set inflector for Zend_Layout */ $inflector =  new  Zend_Filter_Inflector(':script.:suffix'); $inflector->addRules(array(':script' =>  array ('Word_CamelCaseToDash', 'StringToLower'), 'suffix'  => $config->layout->suffix)); // Initialise Zend_Layout's MVC helpers Zend_Layout::startMvc( array ('layoutPath' => ROOT_DIR.$config->layout->layoutPath, 'view' => $view, 'contentKey' => $config->layout->contentKey, 'inflector' => $inflector)); $front = Zend_Controller_Front::getInstance(); $front->setControllerDirectory(array( 'default' => '../application/default/controllers', 'blog'  => '../application/blog/controllers', )); $front->throwExceptions(true);  // enable logging to default.log $writer =  new  Zend_Log_Writer_Stream(APP_DIR.'/data/log/default.log'); $logger =  new  Zend_Log($writer); // give easy access to the logger Zend_Registry::set('logger', $logger); try  { $front->dispatch(); }  catch (Exception $e) { echo  nl2br($e->__toString()); }
Know the market – Zend Framework Zend Framework is different. It is not a solid application framework like CakePHP, it is designed to be a platform on which other frameworks are built Technical details should be mentioned in another talk (enough for today)
A broader view on your framework MVC Push or Pull MVC Push or Passive View <?php // Load the Savant3 class file and create an instance. require_once 'Savant3.php'; $tpl = new Savant3(); // Create a title. $name = &quot;Some Of My Favorite Books&quot;; // Generate an array of book authors and titles. $booklist = array(     array(         'author' => 'Hernando de Soto',         'title' => 'The Mystery of Capitalism'     ),     array(         'author' => 'Neal Stephenson',         'title' => 'Cryptonomicon'     ),     array(         'author' => 'Milton Friedman',         'title' => 'Free to Choose'     ) ); // Assign values to the Savant instance. $tpl->title = $name; $tpl->books = $booklist; // Display a template using the assigned values. $tpl->display('books.tpl.php'); ?>
A broader view on your framework MVC Push or Pull MVC Pull or so-called HMVC (see next): break a big controller into small ones
A broader view on your framework
 
A broader view on your framework MVC Push or Pull:  HMVC implementation Master Controller /** * Show the home page * * @link  http://www.wvbresearch.com/home/index/index * @name  index * @access public */ public function indexAction() { // Attach placeholder: the name of ElementGroup $this->_layout->registerBody('homeIndex'); // Set content for the response $this->_response->setContent($this->_layout->render('index3col')); }
A broader view on your framework MVC Push or Pull: HMVC implementation Group Controller class  Group_HomeIndex  extends  Pone_View_ElementGroup { /**   * Elements in in this group   *   * @var array   */ protected  $_elementsInGroup = array( 'homeTopNegativeEpsSurprises', 'homeTopPositiveEpsSurprises', 'homeIntroduction', 'brokerRatingsUpgrades', 'homeAnalystEstimatesSearchBox', 'homeResearchReportSearchBox', 'latestResearchReports' ); protected  $_templateFile = 'homeIndex'; public   function  setup() { } }
A broader view on your framework MVC Push or Pull: HMVC implementation Element Controller class  Element_LatestResearchReports  extends  Pone_View_Element { protected  $_templateFile = 'latestResearchReportsOnHome'; /** * List of recent research reports * * @var Pone_DataSet */ public  $researchReports; public   function  setup() { $module  = Pone::getContext()->getFront()->getRequest()->getModuleName(); $numberOfItems = 7; if  ('home'  !== $module) { $this->_templateFile = 'latestResearchReports'; $numberOfItems  = 10; } $dbConn  = Pone_Action_Helper_Database::getInstance()->getConnection('oracleweb', true); $researchReportDs  = ResearchReportDatabaseService::getInstance($dbConn); $this->researchReports = $researchReportDs->findRecentList($numberOfItems); } }
A broader view on your framework MVC Push or Pull: HMVC implementation Element Controller template < div   class =&quot; featureBlockHeader &quot;> < h2 >Latest reports</ h2 > </ div > < div  class=&quot; textBox &quot;> < div  class=&quot; textBoxContent &quot;> <?php   if  ( true  === $this->researchReports->isReadable()): $iter = $this->researchReports->getIterator();  ?> < ul  class=&quot; imgList &quot;> <?php  foreach  ($iter  as  $report): ?> < li ><a href=&quot;research/detail/view/rpid/<?php echo $report->get('report_id') ?>&quot;><?php echo $report->get('title'); ?></a></li> <?php  endforeach;  ?> </ul> <?php  else: echo $this->researchReports->getMessage(); endif; ?> </ div > </ div >
A broader view on your framework IDE support Code completion rocks MVC Push is bad for view data documentation Zend_Registry is bad for code completion Zend_Registry :: set('logger', $logger); Think of interface because implementing a way to load dynamic class from a variable or an array element. Learn how to write DocBlock
A broader view on your framework Core feature set MVC framework Model layer: DBO, File handling/transformation, business rules, workflows, search, messaging, memory, remote resource access … Validation framework instead of form handling Unified directory structure: model classes, controllers, views (page fragments, layouts), plugins, filters, custom exceptions, helpers Session Authentication and ACL: Abstract and extensible HTTP Digest Database backed SAML/SSO Serializable Unified Session User Object
A broader view on your framework Core feature set Validation framework class Form_Signup extends Pone_Form_Input { . . . . . . public function onPost() { // Email $emailRules  = array( Pone_Form_Rule::EMAIL => array('feedback'  => _t('common.error.email.notvalid')) ); $this->setValidationRule('email', $emailRules); // Email 2 $email2Rules  = array( Pone_Form_Rule::STRING_EQUAL => array('feedback' => _t('common.error.reemail.not_match'), 'reference' => 'email') ); $this->setValidationRule('email2', $email2Rules); // password $passwordRules  = array( Pone_Form_Rule::NOT_EMPTY  => array('feedback' => _t('common.error.password.empty')) ); $this->setValidationRule('password', $passwordRules); // password 2 $password2Rules  = array( Pone_Form_Rule::STRING_EQUAL => array('feedback' => _t('common.error.repassword.not_match'), 'reference' => 'password') ); $this->setValidationRule('password2', $password2Rules); } }
A broader view on your framework Much more things that need to take into account Behavior layer Caching Distributed caching Local caching Dependency Injection framework Internationalization (enough for today)
Lessons to learn Take your hand dirty please. Singleton is bad thing when dependency injection and unit testing are taken into consideration can't replace it with an interface  Factory allows for both discovery and instance management of the service providers  Final classes should keep singleton objects $dbConn =  Pone_Action_Helper_Database :: getInstance ()->getConnection('oracleweb', true);  $researchReportDs =  ResearchReportDatabaseService :: getInstance ($dbConn);  $this->researchReports = $researchReportDs->findRecentList($numberOfItems);
Lessons to learn Factory and interface make good things Factory and Adapter are good for service providers $conn  = Pone_Database_ConnectionFactory::getConnection($config); $stmt  = $conn->createStatement(); $stmt ->addBatch(&quot;INSERT INTO test2 VALUES (1007, 'pcdinh1007', 1)&quot;); $stmt ->addBatch(&quot;INSERT INTO test2 VALUES (1009, 'pcdinh1009', 1)&quot;); $stmt ->addBatch(&quot;INSERT INTO test2 VALUES (1010, 'pcdinh1010', 1)&quot;); $conn ->beginTransaction(); $updateCounts  = $stmt->executeBatch();
Lessons to learn Fluent interface/object chaining sometimes is a bad thing Law of Demeter $module = Pone::getContext()->getFront()->getRequest()->getModuleName();
Lessons to learn Don’t think DAO or ActiveRecord, think Domain Respository
Lessons to learn An interface between Model and Controller must be defined Model class returns an array: bad thing. How to catch errors and deal with them in the view template
Lessons to learn Dependency Injection Does all injection through the constructor $libBasePath = $basePath.'/libs'; $appBasePath = $basePath.'/apps'; Pone::executeContext( new BenchmarkContext() , $basePath, $appBasePath, $libBasePath); OR $front->setRequest(new Pone_Request( new Pone_Request_SimpleUrlParser() )); Use Template Method design pattern Seam if (session_id() === '' && PHP_SAPI != 'cli') { Pone::getContext()->loadSessionUserClass(); $started = session_start(); // PHP 5.3: returns false or true $this->_started = true; } Use XML/YAML like in Spring, Symfony which is somewhat heavy in an interpreted language like PHP
Design by Interface Rule: Don’t call me, I will call you Template Method Convention over configuration That’s end for today
Thanks you Any question?

More Related Content

What's hot (20)

Thymeleaf Introduction
Thymeleaf IntroductionThymeleaf Introduction
Thymeleaf Introduction
Anthony Chen
 
Broadleaf Presents Thymeleaf
Broadleaf Presents ThymeleafBroadleaf Presents Thymeleaf
Broadleaf Presents Thymeleaf
Broadleaf Commerce
 
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
Fabien Potencier
 
Ezobject wrapper workshop
Ezobject wrapper workshopEzobject wrapper workshop
Ezobject wrapper workshop
Kaliop-slide
 
WordPress and Ajax
WordPress and AjaxWordPress and Ajax
WordPress and Ajax
Ronald Huereca
 
JavaScript Basics with baby steps
JavaScript Basics with baby stepsJavaScript Basics with baby steps
JavaScript Basics with baby steps
Muhammad khurram khan
 
XUL - Mozilla Application Framework
XUL - Mozilla Application FrameworkXUL - Mozilla Application Framework
XUL - Mozilla Application Framework
Uldis Bojars
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
fishwarter
 
JavaScript on Rails 튜토리얼
JavaScript on Rails 튜토리얼JavaScript on Rails 튜토리얼
JavaScript on Rails 튜토리얼
Sukjoon Kim
 
Using Renderless Components in Vue.js during your software development.
Using Renderless Components in Vue.js during your software development.Using Renderless Components in Vue.js during your software development.
Using Renderless Components in Vue.js during your software development.
tothepointIT
 
Up & Running with Polymer
Up & Running with PolymerUp & Running with Polymer
Up & Running with Polymer
Fiyaz Hasan
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
Eyal Vardi
 
Lone StarPHP 2013 - Building Web Apps from a New Angle
Lone StarPHP 2013 - Building Web Apps from a New AngleLone StarPHP 2013 - Building Web Apps from a New Angle
Lone StarPHP 2013 - Building Web Apps from a New Angle
Pablo Godel
 
Extending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh PollockExtending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh Pollock
Caldera Labs
 
Webinar: AngularJS and the WordPress REST API
Webinar: AngularJS and the WordPress REST APIWebinar: AngularJS and the WordPress REST API
Webinar: AngularJS and the WordPress REST API
WP Engine UK
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHP
Bradley Holt
 
[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress Development[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress Development
Adam Tomat
 
Overlays, Accordions & Tabs, Oh My
Overlays, Accordions & Tabs, Oh MyOverlays, Accordions & Tabs, Oh My
Overlays, Accordions & Tabs, Oh My
Steve McMahon
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJS
Aaronius
 
Drupal 8 - Core and API Changes
Drupal 8 - Core and API ChangesDrupal 8 - Core and API Changes
Drupal 8 - Core and API Changes
Shabir Ahmad
 
Thymeleaf Introduction
Thymeleaf IntroductionThymeleaf Introduction
Thymeleaf Introduction
Anthony Chen
 
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
Fabien Potencier
 
Ezobject wrapper workshop
Ezobject wrapper workshopEzobject wrapper workshop
Ezobject wrapper workshop
Kaliop-slide
 
XUL - Mozilla Application Framework
XUL - Mozilla Application FrameworkXUL - Mozilla Application Framework
XUL - Mozilla Application Framework
Uldis Bojars
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
fishwarter
 
JavaScript on Rails 튜토리얼
JavaScript on Rails 튜토리얼JavaScript on Rails 튜토리얼
JavaScript on Rails 튜토리얼
Sukjoon Kim
 
Using Renderless Components in Vue.js during your software development.
Using Renderless Components in Vue.js during your software development.Using Renderless Components in Vue.js during your software development.
Using Renderless Components in Vue.js during your software development.
tothepointIT
 
Up & Running with Polymer
Up & Running with PolymerUp & Running with Polymer
Up & Running with Polymer
Fiyaz Hasan
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
Eyal Vardi
 
Lone StarPHP 2013 - Building Web Apps from a New Angle
Lone StarPHP 2013 - Building Web Apps from a New AngleLone StarPHP 2013 - Building Web Apps from a New Angle
Lone StarPHP 2013 - Building Web Apps from a New Angle
Pablo Godel
 
Extending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh PollockExtending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh Pollock
Caldera Labs
 
Webinar: AngularJS and the WordPress REST API
Webinar: AngularJS and the WordPress REST APIWebinar: AngularJS and the WordPress REST API
Webinar: AngularJS and the WordPress REST API
WP Engine UK
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHP
Bradley Holt
 
[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress Development[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress Development
Adam Tomat
 
Overlays, Accordions & Tabs, Oh My
Overlays, Accordions & Tabs, Oh MyOverlays, Accordions & Tabs, Oh My
Overlays, Accordions & Tabs, Oh My
Steve McMahon
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJS
Aaronius
 
Drupal 8 - Core and API Changes
Drupal 8 - Core and API ChangesDrupal 8 - Core and API Changes
Drupal 8 - Core and API Changes
Shabir Ahmad
 

Viewers also liked (20)

PHP MVC
PHP MVCPHP MVC
PHP MVC
Reggie Niccolo Santos
 
Un exemple élémentaire d'application MVC en PHP
Un exemple élémentaire d'application MVC en PHPUn exemple élémentaire d'application MVC en PHP
Un exemple élémentaire d'application MVC en PHP
Kristen Le Liboux
 
Seven Steps to Creating a Framework
Seven Steps to Creating a FrameworkSeven Steps to Creating a Framework
Seven Steps to Creating a Framework
Rob Philibert
 
Joomla @ Barcamp4(Feb 08 Pune)
Joomla @ Barcamp4(Feb 08 Pune)Joomla @ Barcamp4(Feb 08 Pune)
Joomla @ Barcamp4(Feb 08 Pune)
Amit Kumar Singh
 
Phpbasics And Php Framework
Phpbasics And Php FrameworkPhpbasics And Php Framework
Phpbasics And Php Framework
shivas
 
Implementing Comet using PHP
Implementing Comet using PHPImplementing Comet using PHP
Implementing Comet using PHP
King Foo
 
PHP framework difference
PHP framework differencePHP framework difference
PHP framework difference
iScripts
 
Alloy HMVC PHP Framework
Alloy HMVC PHP FrameworkAlloy HMVC PHP Framework
Alloy HMVC PHP Framework
Vance Lucas
 
Intro to DooPHP
Intro to DooPHPIntro to DooPHP
Intro to DooPHP
Leng Hong
 
Php tutorial
Php  tutorialPhp  tutorial
Php tutorial
Computer Hardware & Trouble shooting
 
Cake Php 1.2 (Ocphp)
Cake Php 1.2 (Ocphp)Cake Php 1.2 (Ocphp)
Cake Php 1.2 (Ocphp)
guest193fe1
 
PHP Framework
PHP FrameworkPHP Framework
PHP Framework
celeroo
 
Laravel - Website Development in Php Framework.
Laravel - Website Development in Php Framework.Laravel - Website Development in Php Framework.
Laravel - Website Development in Php Framework.
SWAAM Tech
 
Php Frameworks
Php FrameworksPhp Frameworks
Php Frameworks
Ryan Davis
 
Object Relational Mapping in PHP
Object Relational Mapping in PHPObject Relational Mapping in PHP
Object Relational Mapping in PHP
Rob Knight
 
Silex, the microframework
Silex, the microframeworkSilex, the microframework
Silex, the microframework
Inviqa
 
Benefits of the CodeIgniter Framework
Benefits of the CodeIgniter FrameworkBenefits of the CodeIgniter Framework
Benefits of the CodeIgniter Framework
Toby Beresford
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Jeremy Kendall
 
Plugin architecture (Extensible Application Architecture)
Plugin architecture (Extensible Application Architecture)Plugin architecture (Extensible Application Architecture)
Plugin architecture (Extensible Application Architecture)
Chinmoy Mohanty
 
Introduction to MVC Web Framework with CodeIgniter
Introduction to MVC Web Framework with CodeIgniterIntroduction to MVC Web Framework with CodeIgniter
Introduction to MVC Web Framework with CodeIgniter
Pongsakorn U-chupala
 
Un exemple élémentaire d'application MVC en PHP
Un exemple élémentaire d'application MVC en PHPUn exemple élémentaire d'application MVC en PHP
Un exemple élémentaire d'application MVC en PHP
Kristen Le Liboux
 
Seven Steps to Creating a Framework
Seven Steps to Creating a FrameworkSeven Steps to Creating a Framework
Seven Steps to Creating a Framework
Rob Philibert
 
Joomla @ Barcamp4(Feb 08 Pune)
Joomla @ Barcamp4(Feb 08 Pune)Joomla @ Barcamp4(Feb 08 Pune)
Joomla @ Barcamp4(Feb 08 Pune)
Amit Kumar Singh
 
Phpbasics And Php Framework
Phpbasics And Php FrameworkPhpbasics And Php Framework
Phpbasics And Php Framework
shivas
 
Implementing Comet using PHP
Implementing Comet using PHPImplementing Comet using PHP
Implementing Comet using PHP
King Foo
 
PHP framework difference
PHP framework differencePHP framework difference
PHP framework difference
iScripts
 
Alloy HMVC PHP Framework
Alloy HMVC PHP FrameworkAlloy HMVC PHP Framework
Alloy HMVC PHP Framework
Vance Lucas
 
Intro to DooPHP
Intro to DooPHPIntro to DooPHP
Intro to DooPHP
Leng Hong
 
Cake Php 1.2 (Ocphp)
Cake Php 1.2 (Ocphp)Cake Php 1.2 (Ocphp)
Cake Php 1.2 (Ocphp)
guest193fe1
 
PHP Framework
PHP FrameworkPHP Framework
PHP Framework
celeroo
 
Laravel - Website Development in Php Framework.
Laravel - Website Development in Php Framework.Laravel - Website Development in Php Framework.
Laravel - Website Development in Php Framework.
SWAAM Tech
 
Php Frameworks
Php FrameworksPhp Frameworks
Php Frameworks
Ryan Davis
 
Object Relational Mapping in PHP
Object Relational Mapping in PHPObject Relational Mapping in PHP
Object Relational Mapping in PHP
Rob Knight
 
Silex, the microframework
Silex, the microframeworkSilex, the microframework
Silex, the microframework
Inviqa
 
Benefits of the CodeIgniter Framework
Benefits of the CodeIgniter FrameworkBenefits of the CodeIgniter Framework
Benefits of the CodeIgniter Framework
Toby Beresford
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Jeremy Kendall
 
Plugin architecture (Extensible Application Architecture)
Plugin architecture (Extensible Application Architecture)Plugin architecture (Extensible Application Architecture)
Plugin architecture (Extensible Application Architecture)
Chinmoy Mohanty
 
Introduction to MVC Web Framework with CodeIgniter
Introduction to MVC Web Framework with CodeIgniterIntroduction to MVC Web Framework with CodeIgniter
Introduction to MVC Web Framework with CodeIgniter
Pongsakorn U-chupala
 
Ad

Similar to How to learn to build your own PHP framework (20)

WordPress development paradigms, idiosyncrasies and other big words
WordPress development paradigms, idiosyncrasies and other big wordsWordPress development paradigms, idiosyncrasies and other big words
WordPress development paradigms, idiosyncrasies and other big words
TomAuger
 
Система рендеринга в Magento
Система рендеринга в MagentoСистема рендеринга в Magento
Система рендеринга в Magento
Magecom Ukraine
 
Optimize Site Deployments with Drush (DrupalCamp WNY 2011)
Optimize Site Deployments with Drush (DrupalCamp WNY 2011)Optimize Site Deployments with Drush (DrupalCamp WNY 2011)
Optimize Site Deployments with Drush (DrupalCamp WNY 2011)
Jon Peck
 
Finding Your Way: Understanding Magento Code
Finding Your Way: Understanding Magento CodeFinding Your Way: Understanding Magento Code
Finding Your Way: Understanding Magento Code
Ben Marks
 
Howtobuildyourownframework
HowtobuildyourownframeworkHowtobuildyourownframework
Howtobuildyourownframework
hazzaz
 
Lca05
Lca05Lca05
Lca05
Sateesh Patil
 
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег ЗинченкоWebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
GeeksLab Odessa
 
Drupal Theme Development - DrupalCon Chicago 2011
Drupal Theme Development - DrupalCon Chicago 2011Drupal Theme Development - DrupalCon Chicago 2011
Drupal Theme Development - DrupalCon Chicago 2011
Ryan Price
 
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
Gordon Forsythe
 
Practical catalyst
Practical catalystPractical catalyst
Practical catalyst
dwm042
 
How to? Drupal developer toolkit. Dennis Povshedny.
How to? Drupal developer toolkit. Dennis Povshedny.How to? Drupal developer toolkit. Dennis Povshedny.
How to? Drupal developer toolkit. Dennis Povshedny.
DrupalCampDN
 
Drupal development
Drupal development Drupal development
Drupal development
Dennis Povshedny
 
Flash Templates- Joomla!Days NL 2009 #jd09nl
Flash Templates- Joomla!Days NL 2009 #jd09nlFlash Templates- Joomla!Days NL 2009 #jd09nl
Flash Templates- Joomla!Days NL 2009 #jd09nl
Joomla!Days Netherlands
 
Flash templates for Joomla!
Flash templates for Joomla!Flash templates for Joomla!
Flash templates for Joomla!
Herman Peeren
 
DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)
Oleg Zinchenko
 
Create a web-app with Cgi Appplication
Create a web-app with Cgi AppplicationCreate a web-app with Cgi Appplication
Create a web-app with Cgi Appplication
olegmmiller
 
Symfony CMF - PHP Conference Brazil 2011
Symfony CMF - PHP Conference Brazil 2011Symfony CMF - PHP Conference Brazil 2011
Symfony CMF - PHP Conference Brazil 2011
Jacopo Romei
 
Introduction to Zend Framework
Introduction to Zend FrameworkIntroduction to Zend Framework
Introduction to Zend Framework
Michelangelo van Dam
 
WordPress Standardized Loop API
WordPress Standardized Loop APIWordPress Standardized Loop API
WordPress Standardized Loop API
Chris Jean
 
Object Oriented Design Patterns for PHP
Object Oriented Design Patterns for PHPObject Oriented Design Patterns for PHP
Object Oriented Design Patterns for PHP
RobertGonzalez
 
WordPress development paradigms, idiosyncrasies and other big words
WordPress development paradigms, idiosyncrasies and other big wordsWordPress development paradigms, idiosyncrasies and other big words
WordPress development paradigms, idiosyncrasies and other big words
TomAuger
 
Система рендеринга в Magento
Система рендеринга в MagentoСистема рендеринга в Magento
Система рендеринга в Magento
Magecom Ukraine
 
Optimize Site Deployments with Drush (DrupalCamp WNY 2011)
Optimize Site Deployments with Drush (DrupalCamp WNY 2011)Optimize Site Deployments with Drush (DrupalCamp WNY 2011)
Optimize Site Deployments with Drush (DrupalCamp WNY 2011)
Jon Peck
 
Finding Your Way: Understanding Magento Code
Finding Your Way: Understanding Magento CodeFinding Your Way: Understanding Magento Code
Finding Your Way: Understanding Magento Code
Ben Marks
 
Howtobuildyourownframework
HowtobuildyourownframeworkHowtobuildyourownframework
Howtobuildyourownframework
hazzaz
 
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег ЗинченкоWebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
GeeksLab Odessa
 
Drupal Theme Development - DrupalCon Chicago 2011
Drupal Theme Development - DrupalCon Chicago 2011Drupal Theme Development - DrupalCon Chicago 2011
Drupal Theme Development - DrupalCon Chicago 2011
Ryan Price
 
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
Gordon Forsythe
 
Practical catalyst
Practical catalystPractical catalyst
Practical catalyst
dwm042
 
How to? Drupal developer toolkit. Dennis Povshedny.
How to? Drupal developer toolkit. Dennis Povshedny.How to? Drupal developer toolkit. Dennis Povshedny.
How to? Drupal developer toolkit. Dennis Povshedny.
DrupalCampDN
 
Flash Templates- Joomla!Days NL 2009 #jd09nl
Flash Templates- Joomla!Days NL 2009 #jd09nlFlash Templates- Joomla!Days NL 2009 #jd09nl
Flash Templates- Joomla!Days NL 2009 #jd09nl
Joomla!Days Netherlands
 
Flash templates for Joomla!
Flash templates for Joomla!Flash templates for Joomla!
Flash templates for Joomla!
Herman Peeren
 
DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)
Oleg Zinchenko
 
Create a web-app with Cgi Appplication
Create a web-app with Cgi AppplicationCreate a web-app with Cgi Appplication
Create a web-app with Cgi Appplication
olegmmiller
 
Symfony CMF - PHP Conference Brazil 2011
Symfony CMF - PHP Conference Brazil 2011Symfony CMF - PHP Conference Brazil 2011
Symfony CMF - PHP Conference Brazil 2011
Jacopo Romei
 
WordPress Standardized Loop API
WordPress Standardized Loop APIWordPress Standardized Loop API
WordPress Standardized Loop API
Chris Jean
 
Object Oriented Design Patterns for PHP
Object Oriented Design Patterns for PHPObject Oriented Design Patterns for PHP
Object Oriented Design Patterns for PHP
RobertGonzalez
 
Ad

Recently uploaded (20)

End-to-end Assurance for SD-WAN & SASE with ThousandEyes
End-to-end Assurance for SD-WAN & SASE with ThousandEyesEnd-to-end Assurance for SD-WAN & SASE with ThousandEyes
End-to-end Assurance for SD-WAN & SASE with ThousandEyes
ThousandEyes
 
Mastering AI Workflows with FME - Peak of Data & AI 2025
Mastering AI Workflows with FME - Peak of Data & AI 2025Mastering AI Workflows with FME - Peak of Data & AI 2025
Mastering AI Workflows with FME - Peak of Data & AI 2025
Safe Software
 
Agentic AI: Beyond the Buzz- LangGraph Studio V2
Agentic AI: Beyond the Buzz- LangGraph Studio V2Agentic AI: Beyond the Buzz- LangGraph Studio V2
Agentic AI: Beyond the Buzz- LangGraph Studio V2
Shashikant Jagtap
 
How to Detect Outliers in IBM SPSS Statistics.pptx
How to Detect Outliers in IBM SPSS Statistics.pptxHow to Detect Outliers in IBM SPSS Statistics.pptx
How to Detect Outliers in IBM SPSS Statistics.pptx
Version 1 Analytics
 
How Advanced Environmental Detection Is Revolutionizing Oil & Gas Safety.pdf
How Advanced Environmental Detection Is Revolutionizing Oil & Gas Safety.pdfHow Advanced Environmental Detection Is Revolutionizing Oil & Gas Safety.pdf
How Advanced Environmental Detection Is Revolutionizing Oil & Gas Safety.pdf
Rejig Digital
 
Boosting MySQL with Vector Search -THE VECTOR SEARCH CONFERENCE 2025 .pdf
Boosting MySQL with Vector Search -THE VECTOR SEARCH CONFERENCE 2025 .pdfBoosting MySQL with Vector Search -THE VECTOR SEARCH CONFERENCE 2025 .pdf
Boosting MySQL with Vector Search -THE VECTOR SEARCH CONFERENCE 2025 .pdf
Alkin Tezuysal
 
LSNIF: Locally-Subdivided Neural Intersection Function
LSNIF: Locally-Subdivided Neural Intersection FunctionLSNIF: Locally-Subdivided Neural Intersection Function
LSNIF: Locally-Subdivided Neural Intersection Function
Takahiro Harada
 
Dancing with AI - A Developer's Journey.pptx
Dancing with AI - A Developer's Journey.pptxDancing with AI - A Developer's Journey.pptx
Dancing with AI - A Developer's Journey.pptx
Elliott Richmond
 
Developing Schemas with FME and Excel - Peak of Data & AI 2025
Developing Schemas with FME and Excel - Peak of Data & AI 2025Developing Schemas with FME and Excel - Peak of Data & AI 2025
Developing Schemas with FME and Excel - Peak of Data & AI 2025
Safe Software
 
Domino IQ – What to Expect, First Steps and Use Cases
Domino IQ – What to Expect, First Steps and Use CasesDomino IQ – What to Expect, First Steps and Use Cases
Domino IQ – What to Expect, First Steps and Use Cases
panagenda
 
Azure vs AWS Which Cloud Platform Is Best for Your Business in 2025
Azure vs AWS  Which Cloud Platform Is Best for Your Business in 2025Azure vs AWS  Which Cloud Platform Is Best for Your Business in 2025
Azure vs AWS Which Cloud Platform Is Best for Your Business in 2025
Infrassist Technologies Pvt. Ltd.
 
DevOps in the Modern Era - Thoughtfully Critical Podcast
DevOps in the Modern Era - Thoughtfully Critical PodcastDevOps in the Modern Era - Thoughtfully Critical Podcast
DevOps in the Modern Era - Thoughtfully Critical Podcast
Chris Wahl
 
vertical-cnc-processing-centers-drillteq-v-200-en.pdf
vertical-cnc-processing-centers-drillteq-v-200-en.pdfvertical-cnc-processing-centers-drillteq-v-200-en.pdf
vertical-cnc-processing-centers-drillteq-v-200-en.pdf
AmirStern2
 
Murdledescargadarkweb.pdfvolumen1 100 elementary
Murdledescargadarkweb.pdfvolumen1 100 elementaryMurdledescargadarkweb.pdfvolumen1 100 elementary
Murdledescargadarkweb.pdfvolumen1 100 elementary
JorgeSemperteguiMont
 
Oracle Cloud Infrastructure Generative AI Professional
Oracle Cloud Infrastructure Generative AI ProfessionalOracle Cloud Infrastructure Generative AI Professional
Oracle Cloud Infrastructure Generative AI Professional
VICTOR MAESTRE RAMIREZ
 
ELNL2025 - Unlocking the Power of Sensitivity Labels - A Comprehensive Guide....
ELNL2025 - Unlocking the Power of Sensitivity Labels - A Comprehensive Guide....ELNL2025 - Unlocking the Power of Sensitivity Labels - A Comprehensive Guide....
ELNL2025 - Unlocking the Power of Sensitivity Labels - A Comprehensive Guide....
Jasper Oosterveld
 
7 Salesforce Data Cloud Best Practices.pdf
7 Salesforce Data Cloud Best Practices.pdf7 Salesforce Data Cloud Best Practices.pdf
7 Salesforce Data Cloud Best Practices.pdf
Minuscule Technologies
 
If You Use Databricks, You Definitely Need FME
If You Use Databricks, You Definitely Need FMEIf You Use Databricks, You Definitely Need FME
If You Use Databricks, You Definitely Need FME
Safe Software
 
Down the Rabbit Hole – Solving 5 Training Roadblocks
Down the Rabbit Hole – Solving 5 Training RoadblocksDown the Rabbit Hole – Solving 5 Training Roadblocks
Down the Rabbit Hole – Solving 5 Training Roadblocks
Rustici Software
 
What is Oracle EPM A Guide to Oracle EPM Cloud Everything You Need to Know
What is Oracle EPM A Guide to Oracle EPM Cloud Everything You Need to KnowWhat is Oracle EPM A Guide to Oracle EPM Cloud Everything You Need to Know
What is Oracle EPM A Guide to Oracle EPM Cloud Everything You Need to Know
SMACT Works
 
End-to-end Assurance for SD-WAN & SASE with ThousandEyes
End-to-end Assurance for SD-WAN & SASE with ThousandEyesEnd-to-end Assurance for SD-WAN & SASE with ThousandEyes
End-to-end Assurance for SD-WAN & SASE with ThousandEyes
ThousandEyes
 
Mastering AI Workflows with FME - Peak of Data & AI 2025
Mastering AI Workflows with FME - Peak of Data & AI 2025Mastering AI Workflows with FME - Peak of Data & AI 2025
Mastering AI Workflows with FME - Peak of Data & AI 2025
Safe Software
 
Agentic AI: Beyond the Buzz- LangGraph Studio V2
Agentic AI: Beyond the Buzz- LangGraph Studio V2Agentic AI: Beyond the Buzz- LangGraph Studio V2
Agentic AI: Beyond the Buzz- LangGraph Studio V2
Shashikant Jagtap
 
How to Detect Outliers in IBM SPSS Statistics.pptx
How to Detect Outliers in IBM SPSS Statistics.pptxHow to Detect Outliers in IBM SPSS Statistics.pptx
How to Detect Outliers in IBM SPSS Statistics.pptx
Version 1 Analytics
 
How Advanced Environmental Detection Is Revolutionizing Oil & Gas Safety.pdf
How Advanced Environmental Detection Is Revolutionizing Oil & Gas Safety.pdfHow Advanced Environmental Detection Is Revolutionizing Oil & Gas Safety.pdf
How Advanced Environmental Detection Is Revolutionizing Oil & Gas Safety.pdf
Rejig Digital
 
Boosting MySQL with Vector Search -THE VECTOR SEARCH CONFERENCE 2025 .pdf
Boosting MySQL with Vector Search -THE VECTOR SEARCH CONFERENCE 2025 .pdfBoosting MySQL with Vector Search -THE VECTOR SEARCH CONFERENCE 2025 .pdf
Boosting MySQL with Vector Search -THE VECTOR SEARCH CONFERENCE 2025 .pdf
Alkin Tezuysal
 
LSNIF: Locally-Subdivided Neural Intersection Function
LSNIF: Locally-Subdivided Neural Intersection FunctionLSNIF: Locally-Subdivided Neural Intersection Function
LSNIF: Locally-Subdivided Neural Intersection Function
Takahiro Harada
 
Dancing with AI - A Developer's Journey.pptx
Dancing with AI - A Developer's Journey.pptxDancing with AI - A Developer's Journey.pptx
Dancing with AI - A Developer's Journey.pptx
Elliott Richmond
 
Developing Schemas with FME and Excel - Peak of Data & AI 2025
Developing Schemas with FME and Excel - Peak of Data & AI 2025Developing Schemas with FME and Excel - Peak of Data & AI 2025
Developing Schemas with FME and Excel - Peak of Data & AI 2025
Safe Software
 
Domino IQ – What to Expect, First Steps and Use Cases
Domino IQ – What to Expect, First Steps and Use CasesDomino IQ – What to Expect, First Steps and Use Cases
Domino IQ – What to Expect, First Steps and Use Cases
panagenda
 
Azure vs AWS Which Cloud Platform Is Best for Your Business in 2025
Azure vs AWS  Which Cloud Platform Is Best for Your Business in 2025Azure vs AWS  Which Cloud Platform Is Best for Your Business in 2025
Azure vs AWS Which Cloud Platform Is Best for Your Business in 2025
Infrassist Technologies Pvt. Ltd.
 
DevOps in the Modern Era - Thoughtfully Critical Podcast
DevOps in the Modern Era - Thoughtfully Critical PodcastDevOps in the Modern Era - Thoughtfully Critical Podcast
DevOps in the Modern Era - Thoughtfully Critical Podcast
Chris Wahl
 
vertical-cnc-processing-centers-drillteq-v-200-en.pdf
vertical-cnc-processing-centers-drillteq-v-200-en.pdfvertical-cnc-processing-centers-drillteq-v-200-en.pdf
vertical-cnc-processing-centers-drillteq-v-200-en.pdf
AmirStern2
 
Murdledescargadarkweb.pdfvolumen1 100 elementary
Murdledescargadarkweb.pdfvolumen1 100 elementaryMurdledescargadarkweb.pdfvolumen1 100 elementary
Murdledescargadarkweb.pdfvolumen1 100 elementary
JorgeSemperteguiMont
 
Oracle Cloud Infrastructure Generative AI Professional
Oracle Cloud Infrastructure Generative AI ProfessionalOracle Cloud Infrastructure Generative AI Professional
Oracle Cloud Infrastructure Generative AI Professional
VICTOR MAESTRE RAMIREZ
 
ELNL2025 - Unlocking the Power of Sensitivity Labels - A Comprehensive Guide....
ELNL2025 - Unlocking the Power of Sensitivity Labels - A Comprehensive Guide....ELNL2025 - Unlocking the Power of Sensitivity Labels - A Comprehensive Guide....
ELNL2025 - Unlocking the Power of Sensitivity Labels - A Comprehensive Guide....
Jasper Oosterveld
 
7 Salesforce Data Cloud Best Practices.pdf
7 Salesforce Data Cloud Best Practices.pdf7 Salesforce Data Cloud Best Practices.pdf
7 Salesforce Data Cloud Best Practices.pdf
Minuscule Technologies
 
If You Use Databricks, You Definitely Need FME
If You Use Databricks, You Definitely Need FMEIf You Use Databricks, You Definitely Need FME
If You Use Databricks, You Definitely Need FME
Safe Software
 
Down the Rabbit Hole – Solving 5 Training Roadblocks
Down the Rabbit Hole – Solving 5 Training RoadblocksDown the Rabbit Hole – Solving 5 Training Roadblocks
Down the Rabbit Hole – Solving 5 Training Roadblocks
Rustici Software
 
What is Oracle EPM A Guide to Oracle EPM Cloud Everything You Need to Know
What is Oracle EPM A Guide to Oracle EPM Cloud Everything You Need to KnowWhat is Oracle EPM A Guide to Oracle EPM Cloud Everything You Need to Know
What is Oracle EPM A Guide to Oracle EPM Cloud Everything You Need to Know
SMACT Works
 

How to learn to build your own PHP framework

  • 1. How to learn to build your own PHP framework Bridging the gap between PHP, OOP and Software Architecture Pham Cong Dinh (a.k.a pcdinh) Software Developer Hanoi PHP Day - December 2008 Hanoi - Vietnam
  • 2. Introduction A foundation member of JavaVietnam since 2003 ( http://www.javavietnam.org ) A foundation member of PHPVietnam Discussion Group since 2004 ( http://groups.google.com/group/phpvietnam ) Lead web developer with World’Vest Base Inc. Java is my first love since 1999 PHP is my real lover since 2003. I love the way PHP community works Sometimes I works on Python, Ruby, Erlang I am a strong believer in dynamic programming languages, JavaScript, web standards, convergence of web as a platform and Outsourcing 2.0 I spent 2 years to play with my framework named Pone (PHP One)
  • 3. Objectives Where is PHP now? It is changing. Enterprise oriented: which is driven by Yahoo, Facebook, Zend, Sun/MySQL, Oracle, OmniTI … PHP is too big. It can not just be ignored Object Oriented Programming adoption Increased complexity of web applications Web vs. Adobe Air, MS Silverlight, JavaFX, Google Native Client Trends Will Move Applications to the Web: Consumer Innovation Setting the Pace, Rise of the Power Collaborator, New Economics of Scale for IT, Barriers to Adoption Are Falling Scale-out wins Understanding what framework designers think Building up shared mindsets Providing food for thought
  • 4. Agenda – 40 slides Making judgments Top notch frameworks and their shortcomings A broader view on your framework Lessons to learn
  • 5. Making judgments Common wisdom: Reinventing the wheel Good You know it inside and out You control its pace It fits your needs. Sometimes, your need is unique It teaches you how the world around you works License: This is why GPL is sometime a bad thing Bad You may not as good as other ones No community No outside contributors Reinventing the square wheel
  • 6. Making judgments To develop a framework is just like to set up a business Think of your limitation: time, resources, knowledge to build/test/document/maintain your own mental baby Know your team: how to train them Know the market : known frameworks in the market. Sometimes your needs are satisfied to some extent in several little-known frameworks Starts with pencil and paper: its components and how they interact Starts with API: learn how to design an API first You never do it right from day one
  • 7. Know the market CakePHP shortcomings Zend Framework shortcomings Third party frameworks shortcomings
  • 8. Know the market - CakePHP Misleading terms: plugin, model… Plugin: CakePHP allows you to set up a combination of controllers, models, and views and release them as a packaged application Too database centric: CakePHP naming convention is driven by table names, not dependency injection mechanism. Admin routing sucks: why do we need one-and-only backend for the whole application/plugin/etc…? Flat application structure: plugin/controller/action and no more. Global space constants
  • 9. Know the market - CakePHP No elegant way to change media file (css, javascript, meta content) on each layout page, controlled by a Controller. <head>    <?php echo $html->charset(); ?>    <title>         <?php echo $title_for_layout; ?>    </title>    <?php      echo $html->css('cake.generic');      echo $javascript->link('prototype-1.6.0.2');     echo $scripts_for_layout;      echo $html->meta('icon','/myapp/img/favicon.ico', array ('type' =>'icon'));    ?> </head>
  • 10. Know the market - CakePHP loadModel(), loadController() are not about dependency injection E.x: You want to provide access to a model from a Component Say you have a model called FooBar in a file called foo_bar.php loadModel ('FooBar');   $this ->FooBar = & new  FooBar(); loadModel() maybe deprecated in favor of App::import ('Model', 'ModelName');
  • 11. Know the market - CakePHP beforeFilter(), afterFilter() are coupled with a certain controller (controller is a heavy object. It should avoid being hit too soon) <?php   class   AppController   extends   Controller  {      var   $beforeFilter  =  array ( 'checkAccess' );      var   $components  =  array ( 'Acl' );      function   checkAccess() {     } } ?>
  • 12. Know the market - CakePHP Reuse of view via elements with requestAction() is bad and expensive The dispatcher is called for each call to a controller (routing, figures out what (Plugin)/Controller/Action is request, loops through all $paths->controllerPaths files, to figure out what Controller to load) The controller is set up again Behavior: controllerActAsModel Controller is an interface to another tier Controller is not designed to provide data for internal components Cache unfriendly
  • 13. Know the market - CakePHP Caching hits its hard time because there is no way to get generated view content <?php $this->element('helpbox', array(&quot;cache&quot; => array('time'=> &quot;+7 days&quot;,'key'=>'unique value'))); ?> What about URL-based caching, session/cookie-based caching, geo-based caching, date-based caching (there are a lot of things to tell about CakePHP but it is all for today)
  • 14. Know the market – Zend Framework Zend Framework tries to be a better PEAR Powered by a solid foundation A solid and controllable licensing (CLA) More strictly controlled development environment Enterprise-oriented class library A well-defined roadmap and versioning Zend Framework is a glue framework or framework-oriented class library
  • 15. Know the market – Zend Framework Zend Framework is extremely big and bloated Zend Framework 1.6.2: 1261 file, 267 folders Zend_Mail: 33 files Zend_Pdf: 89 files Zend_Controller: 50 files Zend_View: 57 files Drupal includes folders: 33 files Zend Framework is designed most like Java frameworks Small class file Lot of classes: object graph is hard (see next) Atomic responsibility Strongly embrace design patterns
  • 16.  
  • 17. Know the market – Zend Framework Everything is an object, even a HTML button or checkbox. The same to Java (see Apache Wicket, Tapestry, JBoss Seam) class Zend_View_Helper_FormReset extends Zend_View_Helper_FormElement { public function formReset($name = '', $value = 'Reset', $attribs = null) { $info = $this->_getInfo($name, $value, $attribs); extract ($info); // name, value, attribs, options, listsep, disable // check if disabled $disabled = ''; if ($disable) { $disabled = ' disabled=&quot;disabled&quot;'; } // get closing tag $endTag = '>'; if ($this->view->doctype()->isXhtml()) { $endTag = ' />'; } // Render button $xhtml = '<input type=&quot;reset&quot;' . ' name=&quot;' . $this->view->escape($name) . '&quot;' . ' id=&quot;' . $this->view->escape($id) . '&quot;' . $disabled; . . . . . . . . . } }
  • 18. Know the market – Zend Framework What Zend Framework brings Lot of files are loaded per request which is a bad thing for a dynamic, interpreted language and stateless platform like PHP Much more memory usage Bad thing for PHP memory management model in which memory is allocated in small chunks Zend Framework code: There are lot of require_once() call inside an if statement which is bad for opcode caching mechanism Zend Framework leaves shared hosting in the cold. 700 sites per server are quite normal No control over file system optimization No control over memory No control over opcode caching
  • 19. Know the market – Zend Framework A glue framework requires you to know every concrete class and how to use them in a application life cycle A lot of things to consider means bootstrapping is a mess
  • 20. Know the market – Zend Framework define ('ROOT_DIR', dirname(dirname(dirname(__FILE__)))); define ('APP_DIR',dirname(dirname(__FILE__))); set_include_path ('.' . PATH_SEPARATOR . APP_DIR . '/lib/' . PATH_SEPARATOR . APP_DIR . '/application/default/models/' . PATH_SEPARATOR . ROOT_DIR . '/shared/lib/' . PATH_SEPARATOR . get_include_path()); //This requires that your Zend library lies in ROOT_DIR/shared/lib/ //make classes autoload without doing require require_once ('Zend/Loader.php'); Zend_Loader::registerAutoload(); if ( defined ('ENV') !== TRUE) { define ('ENV','production'); //change staging to production to go to production settings } $config = new Zend_Config_Xml(APP_DIR . '/config/config.xml', ENV); Zend_Registry::set('config',$config); //init session $session = new Zend_Session_Namespace($config->session_name); Zend_Registry::set('session',$session); Zend_Db_Table::setDefaultAdapter(Zend_Db::factory(Zend_Registry::get('config')->database)); /** * Init the Smarty view wrapper and set smarty suffix to the view scripts. */ $view = new EZ_View_Smarty($config->smarty->toArray());
  • 21. Know the market – Zend Framework // use the viewrenderer to keep the code DRY instantiate and add the helper in one go $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer'); $viewRenderer->setView($view); $viewRenderer->setViewSuffix($config->smarty->suffix); /** * Set inflector for Zend_Layout */ $inflector = new Zend_Filter_Inflector(':script.:suffix'); $inflector->addRules(array(':script' => array ('Word_CamelCaseToDash', 'StringToLower'), 'suffix' => $config->layout->suffix)); // Initialise Zend_Layout's MVC helpers Zend_Layout::startMvc( array ('layoutPath' => ROOT_DIR.$config->layout->layoutPath, 'view' => $view, 'contentKey' => $config->layout->contentKey, 'inflector' => $inflector)); $front = Zend_Controller_Front::getInstance(); $front->setControllerDirectory(array( 'default' => '../application/default/controllers', 'blog' => '../application/blog/controllers', )); $front->throwExceptions(true); // enable logging to default.log $writer = new Zend_Log_Writer_Stream(APP_DIR.'/data/log/default.log'); $logger = new Zend_Log($writer); // give easy access to the logger Zend_Registry::set('logger', $logger); try { $front->dispatch(); } catch (Exception $e) { echo nl2br($e->__toString()); }
  • 22. Know the market – Zend Framework Zend Framework is different. It is not a solid application framework like CakePHP, it is designed to be a platform on which other frameworks are built Technical details should be mentioned in another talk (enough for today)
  • 23. A broader view on your framework MVC Push or Pull MVC Push or Passive View <?php // Load the Savant3 class file and create an instance. require_once 'Savant3.php'; $tpl = new Savant3(); // Create a title. $name = &quot;Some Of My Favorite Books&quot;; // Generate an array of book authors and titles. $booklist = array(     array(         'author' => 'Hernando de Soto',         'title' => 'The Mystery of Capitalism'     ),     array(         'author' => 'Neal Stephenson',         'title' => 'Cryptonomicon'     ),     array(         'author' => 'Milton Friedman',         'title' => 'Free to Choose'     ) ); // Assign values to the Savant instance. $tpl->title = $name; $tpl->books = $booklist; // Display a template using the assigned values. $tpl->display('books.tpl.php'); ?>
  • 24. A broader view on your framework MVC Push or Pull MVC Pull or so-called HMVC (see next): break a big controller into small ones
  • 25. A broader view on your framework
  • 26.  
  • 27. A broader view on your framework MVC Push or Pull: HMVC implementation Master Controller /** * Show the home page * * @link http://www.wvbresearch.com/home/index/index * @name index * @access public */ public function indexAction() { // Attach placeholder: the name of ElementGroup $this->_layout->registerBody('homeIndex'); // Set content for the response $this->_response->setContent($this->_layout->render('index3col')); }
  • 28. A broader view on your framework MVC Push or Pull: HMVC implementation Group Controller class Group_HomeIndex extends Pone_View_ElementGroup { /** * Elements in in this group * * @var array */ protected $_elementsInGroup = array( 'homeTopNegativeEpsSurprises', 'homeTopPositiveEpsSurprises', 'homeIntroduction', 'brokerRatingsUpgrades', 'homeAnalystEstimatesSearchBox', 'homeResearchReportSearchBox', 'latestResearchReports' ); protected $_templateFile = 'homeIndex'; public function setup() { } }
  • 29. A broader view on your framework MVC Push or Pull: HMVC implementation Element Controller class Element_LatestResearchReports extends Pone_View_Element { protected $_templateFile = 'latestResearchReportsOnHome'; /** * List of recent research reports * * @var Pone_DataSet */ public $researchReports; public function setup() { $module = Pone::getContext()->getFront()->getRequest()->getModuleName(); $numberOfItems = 7; if ('home' !== $module) { $this->_templateFile = 'latestResearchReports'; $numberOfItems = 10; } $dbConn = Pone_Action_Helper_Database::getInstance()->getConnection('oracleweb', true); $researchReportDs = ResearchReportDatabaseService::getInstance($dbConn); $this->researchReports = $researchReportDs->findRecentList($numberOfItems); } }
  • 30. A broader view on your framework MVC Push or Pull: HMVC implementation Element Controller template < div class =&quot; featureBlockHeader &quot;> < h2 >Latest reports</ h2 > </ div > < div class=&quot; textBox &quot;> < div class=&quot; textBoxContent &quot;> <?php if ( true === $this->researchReports->isReadable()): $iter = $this->researchReports->getIterator(); ?> < ul class=&quot; imgList &quot;> <?php foreach ($iter as $report): ?> < li ><a href=&quot;research/detail/view/rpid/<?php echo $report->get('report_id') ?>&quot;><?php echo $report->get('title'); ?></a></li> <?php endforeach; ?> </ul> <?php else: echo $this->researchReports->getMessage(); endif; ?> </ div > </ div >
  • 31. A broader view on your framework IDE support Code completion rocks MVC Push is bad for view data documentation Zend_Registry is bad for code completion Zend_Registry :: set('logger', $logger); Think of interface because implementing a way to load dynamic class from a variable or an array element. Learn how to write DocBlock
  • 32. A broader view on your framework Core feature set MVC framework Model layer: DBO, File handling/transformation, business rules, workflows, search, messaging, memory, remote resource access … Validation framework instead of form handling Unified directory structure: model classes, controllers, views (page fragments, layouts), plugins, filters, custom exceptions, helpers Session Authentication and ACL: Abstract and extensible HTTP Digest Database backed SAML/SSO Serializable Unified Session User Object
  • 33. A broader view on your framework Core feature set Validation framework class Form_Signup extends Pone_Form_Input { . . . . . . public function onPost() { // Email $emailRules = array( Pone_Form_Rule::EMAIL => array('feedback' => _t('common.error.email.notvalid')) ); $this->setValidationRule('email', $emailRules); // Email 2 $email2Rules = array( Pone_Form_Rule::STRING_EQUAL => array('feedback' => _t('common.error.reemail.not_match'), 'reference' => 'email') ); $this->setValidationRule('email2', $email2Rules); // password $passwordRules = array( Pone_Form_Rule::NOT_EMPTY => array('feedback' => _t('common.error.password.empty')) ); $this->setValidationRule('password', $passwordRules); // password 2 $password2Rules = array( Pone_Form_Rule::STRING_EQUAL => array('feedback' => _t('common.error.repassword.not_match'), 'reference' => 'password') ); $this->setValidationRule('password2', $password2Rules); } }
  • 34. A broader view on your framework Much more things that need to take into account Behavior layer Caching Distributed caching Local caching Dependency Injection framework Internationalization (enough for today)
  • 35. Lessons to learn Take your hand dirty please. Singleton is bad thing when dependency injection and unit testing are taken into consideration can't replace it with an interface Factory allows for both discovery and instance management of the service providers Final classes should keep singleton objects $dbConn = Pone_Action_Helper_Database :: getInstance ()->getConnection('oracleweb', true); $researchReportDs = ResearchReportDatabaseService :: getInstance ($dbConn); $this->researchReports = $researchReportDs->findRecentList($numberOfItems);
  • 36. Lessons to learn Factory and interface make good things Factory and Adapter are good for service providers $conn = Pone_Database_ConnectionFactory::getConnection($config); $stmt = $conn->createStatement(); $stmt ->addBatch(&quot;INSERT INTO test2 VALUES (1007, 'pcdinh1007', 1)&quot;); $stmt ->addBatch(&quot;INSERT INTO test2 VALUES (1009, 'pcdinh1009', 1)&quot;); $stmt ->addBatch(&quot;INSERT INTO test2 VALUES (1010, 'pcdinh1010', 1)&quot;); $conn ->beginTransaction(); $updateCounts = $stmt->executeBatch();
  • 37. Lessons to learn Fluent interface/object chaining sometimes is a bad thing Law of Demeter $module = Pone::getContext()->getFront()->getRequest()->getModuleName();
  • 38. Lessons to learn Don’t think DAO or ActiveRecord, think Domain Respository
  • 39. Lessons to learn An interface between Model and Controller must be defined Model class returns an array: bad thing. How to catch errors and deal with them in the view template
  • 40. Lessons to learn Dependency Injection Does all injection through the constructor $libBasePath = $basePath.'/libs'; $appBasePath = $basePath.'/apps'; Pone::executeContext( new BenchmarkContext() , $basePath, $appBasePath, $libBasePath); OR $front->setRequest(new Pone_Request( new Pone_Request_SimpleUrlParser() )); Use Template Method design pattern Seam if (session_id() === '' && PHP_SAPI != 'cli') { Pone::getContext()->loadSessionUserClass(); $started = session_start(); // PHP 5.3: returns false or true $this->_started = true; } Use XML/YAML like in Spring, Symfony which is somewhat heavy in an interpreted language like PHP
  • 41. Design by Interface Rule: Don’t call me, I will call you Template Method Convention over configuration That’s end for today
  • 42. Thanks you Any question?