Your SlideShare is downloading. ×
0
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Hanoi php day 2008 - 01.pham cong dinh - how.to.build.your.own.framework

2,937

Published on

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,937
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
42
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • You need to think different. You can not see it in a 1999 manner. Java purist mindsets are obsolete
  • Transcript

    • 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?

    ×