Webinar: Zend framework Getting to grips (ZF1)
-
Upload
ryan-mauger -
Category
Technology
-
view
3.396 -
download
0
Transcript of Webinar: Zend framework Getting to grips (ZF1)
ZEND FRAMEWORK: GETTING TO GRIPS
Ryan Mauger
WHO IS RYAN MAUGER?• Zend Framework Contributor
• Zend Framework CR Team Member
• Co-Author of Zend Framework 2 in Action (With Rob Allen)
• Technical Editor for Zend Framework: A Beginners Guide
• Community Supporter
• Zend Certified PHP5 Engineer
• Lead Developer at Lupimedia
WHAT ARE YOU GOING TO TAKE AWAY
Fundamental concepts to help you figure things out for yourself
WHERE TO START?
• Tutorials
• Akrabat’s (Rob Allen): http://akrabat.com/zft
• Official Quickstart: http://bit.ly/zf-quickstart
• Build your own sandbox
• KEEP IT!
• Add to it, keep additions for later reference
WHATS NEXT?
• Dispatch cycle
• Autoloaders, Plugin Loaders & Resource Loaders
• Plugins
• Helpers
• Models
• Forms, Decorators, Validators & Filters
BUT WHAT SHOULD I TACKLE FIRST?
BUT WHAT SHOULD I TACKLE FIRST?
• Understand the Lifecycle of a ZF request
BUT WHAT SHOULD I TACKLE FIRST?
• Understand the Lifecycle of a ZF request
• Understand the Lifecycle of a ZF request
BUT WHAT SHOULD I TACKLE FIRST?
• Understand the Lifecycle of a ZF request
• Understand the Lifecycle of a ZF request
• Understand the Lifecycle of a ZF request
BUT WHAT SHOULD I TACKLE FIRST?
• Understand the Lifecycle of a ZF request
• Understand the Lifecycle of a ZF request
• Understand the Lifecycle of a ZF request
• Understand the Lifecycle of a ZF request
EXECUTION LIFECYCLE
Bootstrap
Route
Dispatch
Simple?
HOW ABOUT A FLOWCHART?
Source: Polly Wong http://www.slideshare.net/polleywong/zend-framework-dispatch-workflow
YIKES!
SOMETHING SIMPLERBootstrap
routeStartup
route
routeShutdown
dispatchLoopStartup
preDispatch
dispatch (action)
postDispatch
dispatchLoopShutdown
FC PluginSOMETHING SIMPLER
routeStartup
route
routeShutdown
dispatchLoopStartup
preDispatch
dispatch (action)
postDispatch
dispatchLoopShutdown
preDispatch
postDispatch
Router
Controller
Dispatch Loop
BOOTSTRAPPING
BOOTSTRAPPING
•Initialise everything you may need
•Make things ready for your request to be dispatched
•Do nothing module specific
•Remember your module bootstraps, even if they are empty!
MODULE BOOTSTRAPSresources.frontController.moduleDirectory = APPLICATION_PATH "/modules"resources.frontController.controllerDirectory.default = APPLICATION_PATH "/controllers"resources.modules[] = ""
<?php
class Abcd_Bootstrap extends Zend_Application_Module_Bootstrap{ protected function _initRest() { $fc = Zend_Controller_Front::getInstance(); $restRoute = new Zend_Rest_Route($fc, array(), array( 'abcd' => array('contacts'), )); $fc->getRouter()->addRoute('contacts', $restRoute); }}
FRONT CONTROLLER PLUGINS AND ACTION
HELPERS
FRONT CONTROLLER PLUGINS
• Provide hooks into various points in the request lifecycle
• Run Automatically
• Should be able to run independently of the action controller itself
• Exceptions thrown in preDispatch will not prevent further plugins preDispatch calls being run
• Are easier to use if you have no constructor parameters.
ADDING A FRONT CONTROLLER PLUGIN
• In the configautoloaderNamespaces[] = " My_ "resources.frontController.plugins[] = "My_Controller_Plugin";
• In the bootstrap (useful for modules)<?php
class ModuleName_Bootstrap extends Zend_Application_Module_Bootstrap{ protected function _initPlugins() { $this->getApplication() ->getResourcePlugin('frontController') ->registerPlugin(new ModuleName_Plugin_Acl()); }}
ACTION HELPERS
• Provide hooks into the request lifecycle
• Run automatically, or on demand
• Are intended to either replace repeated code in your actions (think DRY) or to extend functionality of action controllers
• Thrown Exceptions in pre/postDispatch will stop further execution of other action helpers
ADDING AN ACTION HELPER• In the config
• In the bootstrap (useful for modules)
resources.frontController.actionHelperPaths.My_Action_Helper = "My/Action/Helper"
<?php
class Abcd_Bootstrap extends Zend_Application_Module_Bootstrap{ protected function _initActionHelpers() { Zend_Controller_Action_HelperBroker::addPath( 'My/Action/Helper', 'My_Action_Helper' ); Zend_Controller_Action_HelperBroker::addHelper( new My_Action_Helper_Thingy() ); }}
ACTION HELPER OR FC PLUGIN?
Do you need to interact with it from
the controller?
Do you need to hook earlier than
preDispatch?
Front Controller Plugin Action Helper
Error Handler
Layout
Action stack
Redirector
Flash Messenger
START
No
NoYes
Yes
Context Switch
View Renderer
AUTOLOADING
AUTOLOADING
Autoloading
AUTOLOADING
Autoloading
Plugin loading
AUTOLOADING
Autoloading
Plugin loading
Resource loading
AUTOLOADING
•Library components
•Follows PEAR naming
•Used where ever you see:
• new Zend_Form()
• new Zend_Db()
• new Zend_Service_...
PLUGIN LOADING•Prefixes names to resolve a classname, and path to load
•Can work away from the include_path
•Is used wherever a class is created with only a suffix
•Form Elements, View Helpers, Action Helpers, Resource plugins
RESOURCE LOADING• Resolves classnames which do not map 1:1 with the
filesystemApplication_Model_Page : application/models/Page.php
• Is used for module components (forms, models, services)
• Provide a namespace for the module
• Is created automatically for modules with a module bootstrap
• Makes your modules directories ‘tidier’ (controllers, views, models, forms, etc)
LOADERS IN ACTIONPlugin Loading
“Text” is resolved to Zend_Form_Element_Text by looping through the given prefix paths until a match is found
<?php
class My_Form extends Zend_Form { public function init() { $this->addElement('Text', 'aTextBox', array('label' => 'A text Box')); }}
LOADERS IN ACTIONAdding your own prefix path
Zend_Form::addElementPrefixPath() is an example of accessing a resource loader to add an extra prefix path.
There is also an optional third parameter, to specifically supply a path for only elements, decorators, filters, or validators
<?php
class My_Form extends Zend_Form { public function init() { $this->addElementPrefixPath('My_Form_Element_', 'My/Form/Elements/'); $this->addElement('Text', 'aTextBox', array('label' => 'A text Box')); }}
LOADERS IN ACTIONAutoloading
[production]phpSettings.display_startup_errors = 0phpSettings.display_errors = 0autoloaderNamespaces[] = "My_"includePaths.library = APPLICATION_PATH "/../library"bootstrap.path = APPLICATION_PATH "/Bootstrap.php"bootstrap.class = "Bootstrap"
<?php
class IndexController extends Zend_Controller_Action{ public function indexAction() { $myComponent = new My_Cool_Component(); }}
LOADERS IN ACTIONResource Loading
<?php
class Admin_IndexController extends Zend_Controller_Action{ public function indexAction() { $form = new Admin_Form_EditPage(); $this->view->form = $form; }}
CONSTRUCTOR OPTIONSWhat can I put in $options?
WHAT CAN I PUT IN $OPTIONS?
• $options is always an associative array
• Each key is normalised and turned into a method name for a setter. ‘foo’ becomes ‘setFoo’, ‘bar’ becomes ‘setBar’
• If that setter exists, it is called, and the value at that index is passed as a single argument
• Generally, exceptions are not thrown for invalid options.
• Some components will store any options without a setter for other purposes, e.g. Zend_Form, options without a setter become attributes
WHERE CAN I SEE THE AVAILABLE SETTERS?
• The API documentation (http://framework.zend.com/apidoc/core)
• Your IDE (autocomplete)
• The manual
ADVANTAGES OF USING OPTIONS ARRAYS
• Flexibility of configuration
• Easily extended
• Largely self documenting
TAKING ADVANTAGE OF THE OPTIONS ARRAY IN ZEND_FORM
setPage() is called before init(), allowing
you to pass through the constructor an object, array, or scalar value to
be used for any purpose when
initialising your form.
<?php
class Admin_Form_EditPage extends Zend_Form{ protected $_page; public function init() { $this->addElements(array( //... $multi = new Zend_Form_Element_Select('multi'), //... )); $multi->setMultiOptions($this->_page->getOptions()); } public function setPage(Application_Model_Page $page) { $this->_page = $page; return $this; }}
DECORATORS
HOW THE HECK DO DECORATORS WORK THEN?
HtmlTag <dd>...</dd>
Errors <ul>...</ul>
Label <dt><label></label></dt> Rendered inside-out,
each wrapping,
appending or prepending
content to the content from the previous decorator
Element <input.../>
Description <p>...</p>
DEFINING A DECORATOR STACK
ViewHelper - Renders the elementDescription - renders a paragraph beneath
the element (if a description is set)Errors - Adds a ul beneath the element
HtmlTag - Renders the dd elementLabel - Renders the label and dt tags
$multi->setMultiOptions($this->_page->getOptions()) ->setDecorators(array( 'ViewHelper', 'Description', 'Errors', array('HtmlTag', array('tag' => 'dd')), array('Label', array('tag' => 'dt')), ));
DEFINING A DECORATOR STACK
BeachPHP Demo
THE M IN YOUR MVC
MODELLING DATA
• Business logic
• Domain logic
• Services
• Mappers
• Entities
• Models
ApplicationRDBMSDomain logicFront Controller
View
Action Controller
RDBMS
Domain?
Zend_Db_Table
Zend_Db_Table based modelsDIRECT TDG
RDBMS
Domain
Zend_Db_Table
Zend_Db_Table based models
Entity
TDG WRAPPER BASED MODEL
RDBMS
Domain
Zend_Db_Table
DataMapper based models
Entity
Mapper
QUICKSTART MAPPER
RDBMS
Domain
DBAL
DataMapper based models
Entity Mapper
DOCTRINE2
WHICH PATTERN TO USE?
•Maintenance cycle
•Complexity of the application
•Project timeframe
•Available solutions (Doctrine, Propel, phpDataMapper), do they suit you?
WHAT DOES ZF SUPPORT?
DB Abstraction
WHAT DOES ZF SUPPORT?
DB Abstraction
Expect some sort of integration with Doctrine2 when ZF2 arrives
Doctrine2 is gaining popularity as the ORM of choice for ZF on the whole
Doctrine 1.x is already a very common choice of ORM, though based on Active Record
THANKS FOR LISTENING
Questions?