Zend Framework is widely known as having a "use-at-will" architecture, but what does that really mean? We'll explore two scenarios: one where developers use Zend Framework as a base and extend various components to suite their needs and another where developers can extend nonZF code with ZF components. On conclusion, developers will have a necessary enough understanding to extend with and for ZF.
2. Who is this guy?
•Ralph Schindler
PHP’er since 1998-ish, 3.0 days
Software Engineer
Zend Framework team since Jan 2008
New Orleans born, currently reside in Austin, TX
•Me on the interwebs:
IRC:
•Freenode - ralphschindler
•EFNet - ralphschi / ralphs
ralph.schindler@zend.com
http://twitter.com/ralphschindler
http://ralphschindler.com
http://slideshare.com/ralphschindler
2
3. Who is this talk for?
•Anyone who has an interest in extending ZF beyond it’s current
capabilities
•Anyone who has an existing infrastructure / library / framework
that wants to enhance it with ZF functionality
•People love Getting Things Done!
3
4. Extending ZF
Lets explore ZF as an extensible library
4 Insert->Header & Footer
5. What is Zend Framework?
•Released in March 2006
•1.0 in July 1, 2007
•Goals
Don’t change PHP
Use-at-will architecture
Best practices
•Object oriented / Design patterns
High quality
•Continuous integration
•Proper versioning scheme
•Backwards compatible minor releases
•Predictable release cycle
5
7. What is an extension?
•“Extending software” is the act of taking software and
enhancing it with more specific or value added features
•Extension is typically based around a pre-existing API
•Extension software is typically not useful on its own
7
8. Extending before OO
•Patched existing functions
Managing .diff or .patch files
Worked b/c when consuming a specific version of a library, then
patching, typically not concerned with new versions of base library
•Extended into an extension or plugin style framework
Naming conventions
•scripts
•functions
Registered callbacks
•Dynamic code paths
example: url name loaded a script with a specific name
8
9. Life in the OO fast lane
•PHP5 has a very robust object model, exploit it
•Object oriented code is well suited for “extensibility”
Principal of polymorphic code
•PHP is a single inheritance, multiple interface language
•OO Libraries built with best practices in mind should be easy to extend
•Patching is NO LONGER OK!
Consumed libraries should have adopted a lifecycle
Your software (should) have adopted a lifecycle
You don’t want to manage a “patching” process
•patch -> test -> update, patch -> test -> update
•complexity grows exponentially for each patch
9
10. ZF’s Dual Nature API
•Public “Consumable” API
Public members (properties, methods, constants)
Well defined use cases
Very strict backwards compatibility rules
•Protected “Extension” API
Protected members (properties, methods)
No private members
Use cases include:
•Overriding methods
•Extending abstract classes or implementing interfaces
•As defined as the original author has fore-thought
10
11. Extensibility as an Application Infrastructure
•Use “extends” as a feature
By extending base classes, they “plug into” a working system
•Conventions also help serve the easy by which an extensions
infrastructure
Examples of extendable elements:
•Zend_Controller_Action
•Zend_Controller_Plugin, Zend_Controller_Action_Helper
•Zend_Controller_View (.phtml files)
•Zend_Controller_View_Helper
Conventions that aid in ease of use:
•ZF’s loader: PEAR naming convention assumed
•ZF’s MVC system: placement of controller file, action method
11
12. ZF is coded for extensibility
•No private members (unless private is required)
•Methods kept as fairly small, discreet responsibilities
•Public API fully tested, with very high levels of code coverage
•All predictable use cases included in tests
•The ultimate balancing act:
Interfaces - the signature of the contract, no implementation
Abstracts - the contract in a pseudo-implementation form
•Low levels of coupling
Coupling should be optional
Should work in default use case, poke-yoke style
12
14. Examples of Extension as an Infrastructure
•Zend_Controller
class FooController extends Zend_Controller_Action
FooController’s public function barAction()
Placement of this file in a specific location
•Zend_View_Helper
My_View_Helper_Foo must implement Zend_View_Helper_Interface
Must be placed inside the application/views/helpers/ directory,
named as Foo.php
•Zend_Controller_Action_Helper
(same as above)
•Zend_Application’s Resource_Module & Module_Autoloader
Assume a particular directory structure, file name, & class name
14
17. Extending Stand-Alone Components
•Zend_Auth_Adapter_DbTable is well suited for this
Extend any method, and place this adapter in your models folder (or
library)
•Any Service component that does not implement a feature you
need
•Components with adapter pattern:
Zend_Cache_Frontend & Zend_Cache_Backend
Zend_Auth_Adapter
Extend Zend_Config for new formats
Implement new Zend_View_Interface to support template engines
17
18. When it’s Hard To Extend ...
•Complain
File an issue describing the use case
•Example: Zend_Auth_Adapter_DbTable
authenticate() went from a rather long method to 6 shorter methods
each method is responsible for a very discreet task as such each can
be overridden to suite a new use case
see revision r7598 of Zend Framework
•~$ svn diff -c 7598 http://framework.zend.com/svn/framework/standard/
trunk/library/Zend/Auth/Adapter/DbTable.php
18
19. Components well suited to extension
•Adapter based components
Zend_Auth_Adapter (interface driven)
Zend_Cache_Frontend (interface driven)
Zend_Cache_Backend (base class driven)
Zend_Captcha_Adapter (base class driven)
Zend_Db_Adapter (base class driven)
Zend_Filter & Zend_Validate (interface driven)
Zend_Form: Decorators, Elements (base class driven)
Zend_Paginator_Adapter (interface driven)
Zend_Queue_Adapter (interface driven)
Zend_Service_Abstract (base class driven)
Zend_Translate_Adapter (base class driven)
Zend_View_Helper (interface & abstract driven)
19
21. Some Are Easier Than Others
•All stand-alone, low-couple components can be used in any
PHP5 setting provided ZF is at least in the include_path
•To make things easy, use Zend_Autoloader, find a place:
Project configuration area
OR Project initialization or “bootstrap” area
Worst case: create a static method you can call prior to using ZF
components
21
22. Symfony
•http://symfony-project.com
inspired by RoR, features a convention based, tightly coupled set of
infrastructure features (MVC layer)
•2 common methods:
ProjectConfiguration static method
•Pro: available to all modules at all time
•Con: must be called before consuming ZF component in actions
App initialize() method
•Pro: available on demand when the app is invoked, ZF everywhere, less
action coding required
•Con: must be done in each app configuration
22
25. Symfony: Using the ProjectConfiguration
apps/{appName}/modules/{moduleName}/actions/actions.class.php
apps/{appName}/modules/{moduleName}/templates/indexSuccess.php
25
28. Symfony: Using the App initialize method
apps/{appName}/modules/{moduleName}/actions/actions.class.php
apps/{appName}/modules/{moduleName}/templates/indexSuccess.php
28
29. CodeIgniter and others
•CodeIgniter & homegrown frameworks
http://codeigniter.com/
conventions based, light-weight MVC style framework
•Best method: register autoloader in correct place
29