Zend Framework Tutorial Matthew Weier O'Phinney Project Lead Zend Framework ZendCon 2009 19 October 2009
About me: <ul><li>ZF Contributor since January 2006
Assigned to the ZF team in July 2007
Promoted to Software Architect in April 2008
Project Lead since April 2009 </li></ul>Photo  ©  2009, Chris Shiflett
What we'll cover
<ul><li>What is Zend Framework?
Getting and Installing Zend Framework
Utilities and Patterns  used throughout ZF
Using ZF's MVC layer:  Hands-on demonstration: Pastebin </li></ul>
What is  Zend Framework?
Full Stack Framework?
Component Library?
Both.
 
Getting and Installing  Zend Framework
Always found at: http://framework.zend.com /download/latest
Zend Server
CDN Links
Direct Links
<ul><li>Use CLI: % tar xzf ZendFramework-1.9.2-minimal.tar.gz % unzip ZendFramework-1.9.2-minimal.zip
Or use a GUI file manager </li></ul>Unzip/Untar
Add to your include_path ; UNIX: &quot;/path1:/path2&quot; include_path  =   &quot;.:/home/matthew/zf/library&quot;
Add to your include_path # Goes in either a <VirtualHost>,  # <Directory> or .htaccess: php_value include_path   &quot;.:/...
Add to your include_path <?php set_include_path( implode (PATH_SEPARATOR,   array ( '.' , '/home/matthew/zf/library' , get...
Utilities and Patterns Used throughout  Zend Framework
The Autoloader
<ul><li>Class names have a 1:1 relationship with the FileSystem: Zend_Db => Zend/Db.php
The initial class prefix is called the “vendor” or “namespace” prefix: “Zend_”, “ZendX_”
Register either namespace prefixes or actual autoloader callbacks with the ZF autoloader </li></ul>Rules
Initialize the autoloader require_once   'Zend/Loader/Autoloader.php' ; Zend_Loader_Autoloader::getInstance();
Register namespaces $al   =   Zend_Loader_Autoloader::getInstance(); $al ->registerNamespace( 'Foo_' ); $al ->registerName...
Register other autoloaders $al   =   Zend_Loader_Autoloader::getInstance(); $al ->registerNamespace( 'Doctrine' ); $al ->p...
<ul><li>Groups of resources with a common vendor prefix/namespace
No 1:1 mapping between class name and filename
Define arbitrary mappings, or use Zend_Application_Module_Autoloader for use with MVC modules </li></ul>Resource Autoloaders
Create a resource autoloader // Initialize resource autoloader: $loader   =   new   Zend_Loader_Autoloader_Resource( array...
Create a module autoloader /* * Maps: * - forms/  -> Foo_Form_* * - models/  -> Foo_Model_* * - models/DbTable -> Foo_Mode...
Plugins
<ul><li>For those times when 1:1 doesn't work (e.g., application code)
Standard pattern: “all code in this location shares the same class prefix” (aka PrefixPath)
Plugin loader is passed a “short name,” and attempts to resolve it to a known PrefixPath </li></ul>Rules
Example $element ->addPrefixPath( 'Foo_Validate' ,   // PREFIX 'foo/plugins/validators/' ,   // PATH 'validate' ); foo/ |-...
Invoking plugins $element ->addValidator( 'NotEmpty' ) ->addValidator( 'Int' ) ->addValidator( 'Even' ) ->addValidator( 'D...
Zend_Config
<ul><li>Zend Framework is configurationless, but often your applications are not
Many common configuration formats: XML, INI, PHP
Access to configuration values should not vary between backends
Configuration inheritance is useful </li></ul>Why Zend_Config?
Sample INI config [production] app.name  =   &quot;Foo!&quot; db.adapter  =   &quot;Pdo_Mysql&quot; db.params.username  = ...
Sample XML config <?xml   version = &quot;1.0&quot; ?> <config> <production> <app><name> Foo! </name></app> <db> <adapter>...
Sample PHP config $production   =   include   'production.conf.php' ; $config   =   array ( 'db'   =>   array ( 'adapter' ...
Instantiating a Config object // Load 'testing' section of INI configuration: $config   =   new   Zend_Config_Ini( $fileNa...
Using Config objects // Multiple levels: $appName   =   $config ->app->name; // Using config object as argument $db   =   ...
Using  Zend Framework's MVC Layer
<ul><li>Learn how to create a new ZF MVC project
Learn how to use various MVC components: </li><ul><li>Zend_Application, Zend_Controller_Front, Zend_Controller_Action, Zen...
<ul><li>Create “pastes” with optional expiry; allow listing pastes by username
Single table is ideal for demonstrating simple component interactions
Ask questions as you have them! </li></ul>The Application: Pastebin
<ul><li>A Paste consists of: </li></ul>Pastebin Specification code content (required) summary (optional) code_type content...
<ul><li>Each paste will have a unique URL
Pastes may optionally expire, in which case they won't be displayed
Pastes may be listed by username </li></ul>Pastebin Specification
Step 1: Create the project
<ul><li>In  bin/zf.sh  or  bin/zf.bat  of your ZF install (choose based on your OS)
Place  bin/  in your path, or create an alias on your path: alias zf=/path/to/bin/zf.sh
Or use pear.zfcampus.org PEAR channel </li></ul>Locate the zf utility
Create the project # Unix: %   zf.sh create project quickstart # DOS/Windows: C:>   zf.bat create project quickstart
Add ZF to the project # Symlink: %   cd   library;   ln   -s  path/to/ZendFramework/library/Zend . # Copy: %   cd   librar...
Create a vhost <VirtualHost   *: 80 > ServerAdmin you@atyour.tld DocumentRoot /abs/path/to/quickstart/public ServerName qu...
Add a hosts entry 127.0.0.1   quickstart
Fire up your browser!
Looking under the hood
The  directory  tree quickstart |--   application |  |--   Bootstrap.php |  |--   configs |  |   `-- application.ini |  |-...
The bootstrap <?php class   Bootstrap     extends   Zend_Application_Bootstrap_Bootstrap { }
Upcoming SlideShare
Loading in...5
×

Zend Framework Tutorial, ZendCon 2009

7,462

Published on

Published in: Technology
3 Comments
21 Likes
Statistics
Notes
No Downloads
Views
Total Views
7,462
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
468
Comments
3
Likes
21
Embeds 0
No embeds

No notes for slide

Zend Framework Tutorial, ZendCon 2009

  1. 1. Zend Framework Tutorial Matthew Weier O'Phinney Project Lead Zend Framework ZendCon 2009 19 October 2009
  2. 2. About me: <ul><li>ZF Contributor since January 2006
  3. 3. Assigned to the ZF team in July 2007
  4. 4. Promoted to Software Architect in April 2008
  5. 5. Project Lead since April 2009 </li></ul>Photo © 2009, Chris Shiflett
  6. 6. What we'll cover
  7. 7. <ul><li>What is Zend Framework?
  8. 8. Getting and Installing Zend Framework
  9. 9. Utilities and Patterns used throughout ZF
  10. 10. Using ZF's MVC layer: Hands-on demonstration: Pastebin </li></ul>
  11. 11. What is Zend Framework?
  12. 12. Full Stack Framework?
  13. 13. Component Library?
  14. 14. Both.
  15. 16. Getting and Installing Zend Framework
  16. 17. Always found at: http://framework.zend.com /download/latest
  17. 18. Zend Server
  18. 19. CDN Links
  19. 20. Direct Links
  20. 21. <ul><li>Use CLI: % tar xzf ZendFramework-1.9.2-minimal.tar.gz % unzip ZendFramework-1.9.2-minimal.zip
  21. 22. Or use a GUI file manager </li></ul>Unzip/Untar
  22. 23. Add to your include_path ; UNIX: &quot;/path1:/path2&quot; include_path = &quot;.:/home/matthew/zf/library&quot;
  23. 24. Add to your include_path # Goes in either a <VirtualHost>, # <Directory> or .htaccess: php_value include_path &quot;.:/home/matthew/zf/library&quot;
  24. 25. Add to your include_path <?php set_include_path( implode (PATH_SEPARATOR, array ( '.' , '/home/matthew/zf/library' , get_include_path(), )));
  25. 26. Utilities and Patterns Used throughout Zend Framework
  26. 27. The Autoloader
  27. 28. <ul><li>Class names have a 1:1 relationship with the FileSystem: Zend_Db => Zend/Db.php
  28. 29. The initial class prefix is called the “vendor” or “namespace” prefix: “Zend_”, “ZendX_”
  29. 30. Register either namespace prefixes or actual autoloader callbacks with the ZF autoloader </li></ul>Rules
  30. 31. Initialize the autoloader require_once 'Zend/Loader/Autoloader.php' ; Zend_Loader_Autoloader::getInstance();
  31. 32. Register namespaces $al = Zend_Loader_Autoloader::getInstance(); $al ->registerNamespace( 'Foo_' ); $al ->registerNamespace( array ( 'Foo_' , 'Bar_' ));
  32. 33. Register other autoloaders $al = Zend_Loader_Autoloader::getInstance(); $al ->registerNamespace( 'Doctrine' ); $al ->pushAutoloader( array ( 'Doctrine' , 'autoload' ), 'Doctrine_' );
  33. 34. <ul><li>Groups of resources with a common vendor prefix/namespace
  34. 35. No 1:1 mapping between class name and filename
  35. 36. Define arbitrary mappings, or use Zend_Application_Module_Autoloader for use with MVC modules </li></ul>Resource Autoloaders
  36. 37. Create a resource autoloader // Initialize resource autoloader: $loader = new Zend_Loader_Autoloader_Resource( array ( 'namespace' => 'Foo' , 'basePath' => $path , )); // Map $path/forms/*.php to Foo_Form_*: $loader ->addResourceType( 'form' , 'forms' , 'Form' );
  37. 38. Create a module autoloader /* * Maps: * - forms/ -> Foo_Form_* * - models/ -> Foo_Model_* * - models/DbTable -> Foo_Model_DbTable_* * - plugins -> Foo_Plugin_* * - services -> Foo_Service_* * - views/helpers -> Foo_View_Helper_* * - views/filters -> Foo_View_Filter_* */ $loader = new Zend_Application_Module_Autoloader( array ( 'namespace' => 'Foo' , 'basePath' => dirname (__FILE__), ));
  38. 39. Plugins
  39. 40. <ul><li>For those times when 1:1 doesn't work (e.g., application code)
  40. 41. Standard pattern: “all code in this location shares the same class prefix” (aka PrefixPath)
  41. 42. Plugin loader is passed a “short name,” and attempts to resolve it to a known PrefixPath </li></ul>Rules
  42. 43. Example $element ->addPrefixPath( 'Foo_Validate' , // PREFIX 'foo/plugins/validators/' , // PATH 'validate' ); foo/ |-- plugins/ | |-- validators/ | | |-- Even.php | | |-- Dozens.php | | |-- Int.php
  43. 44. Invoking plugins $element ->addValidator( 'NotEmpty' ) ->addValidator( 'Int' ) ->addValidator( 'Even' ) ->addValidator( 'Dozens' ); New, custom validators Custom validator overriding existing validator
  44. 45. Zend_Config
  45. 46. <ul><li>Zend Framework is configurationless, but often your applications are not
  46. 47. Many common configuration formats: XML, INI, PHP
  47. 48. Access to configuration values should not vary between backends
  48. 49. Configuration inheritance is useful </li></ul>Why Zend_Config?
  49. 50. Sample INI config [production] app.name = &quot;Foo!&quot; db.adapter = &quot;Pdo_Mysql&quot; db.params.username = &quot;foo&quot; db.params.password = &quot;bar&quot; db.params.dbname = &quot;foodb&quot; db.params.host = &quot;127.0.0.1&quot; [testing : production] db.adapter = &quot;Pdo_Sqlite&quot; db.params.dbname = APPLICATION_PATH &quot;/data/test.db&quot;
  50. 51. Sample XML config <?xml version = &quot;1.0&quot; ?> <config> <production> <app><name> Foo! </name></app> <db> <adapter> Pdo_Mysql </adapter> <params username = &quot;foo&quot; password = &quot;bar&quot; dbname = &quot;foodb&quot; host = &quot;127.0.0.1&quot; /> </db> </production> <testing extends = &quot;production&quot; > <db> <adapter> Pdo_Sqlite </adapter> <params dbname = &quot;/data/test.db&quot; /> </db> </testing> </config>
  51. 52. Sample PHP config $production = include 'production.conf.php' ; $config = array ( 'db' => array ( 'adapter' => 'Pdo_Sqlite' , 'params' => array ( 'dbname' => APP_PATH . '/../data/test.db' , ), ) ); $config = $production + $config ; return $config ;
  52. 53. Instantiating a Config object // Load 'testing' section of INI configuration: $config = new Zend_Config_Ini( $fileName , 'testing' ); // Load 'testing' section of XML configuration: $config = new Zend_Config_Xml( $fileName , 'testing' ); // Load 'testing' configuration via PHP array: $config = include 'testing.conf.php' ; $config = new Zend_Config( $config );
  53. 54. Using Config objects // Multiple levels: $appName = $config ->app->name; // Using config object as argument $db = Zend_Db::factory( $config ->db);
  54. 55. Using Zend Framework's MVC Layer
  55. 56. <ul><li>Learn how to create a new ZF MVC project
  56. 57. Learn how to use various MVC components: </li><ul><li>Zend_Application, Zend_Controller_Front, Zend_Controller_Action, Zend_Controller_Router, Zend_Db_Table, Zend_View, Action Helpers, View Helpers, Zend_Form, Zend_Layout, etc. </li></ul><li>Learn concepts related to separation of concerns </li></ul>Goals
  57. 58. <ul><li>Create “pastes” with optional expiry; allow listing pastes by username
  58. 59. Single table is ideal for demonstrating simple component interactions
  59. 60. Ask questions as you have them! </li></ul>The Application: Pastebin
  60. 61. <ul><li>A Paste consists of: </li></ul>Pastebin Specification code content (required) summary (optional) code_type content type (required, default to plain text) username (optional) timestamp (required; created on commit) expiry (optional) identifier (required; a unique hash)
  61. 62. <ul><li>Each paste will have a unique URL
  62. 63. Pastes may optionally expire, in which case they won't be displayed
  63. 64. Pastes may be listed by username </li></ul>Pastebin Specification
  64. 65. Step 1: Create the project
  65. 66. <ul><li>In bin/zf.sh or bin/zf.bat of your ZF install (choose based on your OS)
  66. 67. Place bin/ in your path, or create an alias on your path: alias zf=/path/to/bin/zf.sh
  67. 68. Or use pear.zfcampus.org PEAR channel </li></ul>Locate the zf utility
  68. 69. Create the project # Unix: % zf.sh create project quickstart # DOS/Windows: C:> zf.bat create project quickstart
  69. 70. Add ZF to the project # Symlink: % cd library; ln -s path/to/ZendFramework/library/Zend . # Copy: % cd library; cp -r path/to/ZendFramework/library/Zend .
  70. 71. Create a vhost <VirtualHost *: 80 > ServerAdmin you@atyour.tld DocumentRoot /abs/path/to/quickstart/public ServerName quickstart <Directory /abs/path/to/quickstart/public > DirectoryIndex index.php AllowOverride All Order allow,deny Allow from all </Directory> </VirtualHost>
  71. 72. Add a hosts entry 127.0.0.1 quickstart
  72. 73. Fire up your browser!
  73. 74. Looking under the hood
  74. 75. The directory tree quickstart |-- application | |-- Bootstrap.php | |-- configs | | `-- application.ini | |-- controllers | | |-- ErrorController.php | | ` -- IndexController.php | |-- models | `-- views | |-- helpers | ` -- scripts | |-- error | | `-- error.phtml | ` -- index | `-- index.phtml |-- library |-- public | ` -- index.php `-- tests |-- application | ` -- bootstrap.php |-- library | `-- bootstrap.php ` -- phpunit.xml 14 directories, 10 files
  75. 76. The bootstrap <?php class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { }
  76. 77. Configuration [production] phpSettings.display_startup_errors = 0 phpSettings.display_errors = 0 includePaths.library = APPLICATION_PATH &quot;/../library&quot; bootstrap.path = APPLICATION_PATH &quot;/Bootstrap.php&quot; bootstrap.class = &quot;Bootstrap&quot; resources.frontController.controllerDirectory = APPLICATION_PATH &quot;/controllers&quot; [staging : production] [testing : production] phpSettings.display_startup_errors = 1 phpSettings.display_errors = 1 [development : production] phpSettings.display_startup_errors = 1 phpSettings.display_errors = 1
  77. 78. Index (default) controller <?php class IndexController extends Zend_Controller_Action { public function init() { /* Initialize action controller here */ } public function indexAction() { // action body } }
  78. 79. Error controller class ErrorController extends Zend_Controller_Action { public function errorAction() { $errors = $this ->_getParam( 'error_handler' ); switch ( $errors ->type) { case 'EXCEPTION_NO_CONTROLLER': case 'EXCEPTION_NO_ACTION': // 404 error -- controller or action not found $this ->getResponse()->setHttpResponseCode( 404 ); $this ->view->message = 'Page not found' ; break ; default: // application error $this ->getResponse()->setHttpResponseCode( 500 ); $this ->view->message = 'Application error' ; break ; } $this ->view->exception = $errors ->exception; $this ->view->request = $errors ->request; } }
  79. 80. Index view (home page) <div id = &quot;welcome&quot; > <h1> Welcome to the <span id = &quot;zf-name&quot; > Zend Framework! </span> </h1> <h3> This is your project's main page </h3> <!-- and a little bit more markup --> </div>
  80. 81. Error view <h1>An error occurred</h1> <h2><?php echo $this ->message ?></h2> <?php if ( 'development' == APPLICATION_ENV): ?> <h3>Exception information:</h3> <p> <b>Message:</b> <?php echo $this ->exception->getMessage() ?> </p> <h3>Stack trace:</h3> <pre> <?php echo $this ->exception->getTraceAsString() ?> </pre> <h3>Request Parameters:</h3> <pre> <?php var_dump ( $this ->request->getParams()) ?> </pre> <?php endif ?>
  81. 82. .htaccess file SetEnv APPLICATION_ENV development RewriteEngine On RewriteCond %{REQUEST_FILENAME} -s [OR] RewriteCond %{REQUEST_FILENAME} -l [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^.*$ - [NC,L] RewriteRule ^.*$ index.php [NC,L]
  82. 83. index.php (environment) <?php // Define path to application directory defined ( 'APPLICATION_PATH' ) || define ( 'APPLICATION_PATH' , realpath ( dirname (__FILE__) . '/../application' )); // Define application environment defined ( 'APPLICATION_ENV' ) || define ( 'APPLICATION_ENV' , ( getenv ( 'APPLICATION_ENV' ) ? getenv ( 'APPLICATION_ENV' ) : 'production' )); // Ensure library/ is on include_path set_include_path( implode (PATH_SEPARATOR, array ( realpath (APPLICATION_PATH . '/../library' ), get_include_path(), )));
  83. 84. index.php (application) /** Zend_Application */ require_once 'Zend/Application.php' ; // Create application, bootstrap, and run $application = new Zend_Application( APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini' ); $application ->bootstrap() ->run();
  84. 85. Step 2: Create the model
  85. 86. Step 3: Create a form
  86. 87. Step 4: Create a controller
  87. 88. Step 5: Create new routes
  88. 89. Step 6: Create controller actions
  89. 90. Step 7: Create views
  90. 91. Step 8: Create a layout
  91. 92. Step 9: Update the default view
  92. 93. Step 10: Check it out!
  93. 94. Further Steps
  94. 95. <ul><li>Add Dojo handling for code highlighting
  95. 96. Add CSS for forms
  96. 97. Add CSS for errors
  97. 98. Add some layout specific styling and/or use dojo containers to improve layout
  98. 99. Add Navigation elements to provide a menu/breadcrumbs
  99. 100. Add caching (pastes may not be updated; cache forever) </li></ul>Make it prettier
  100. 101. Summary or, “The fat guy sings”
  101. 102. <ul><li>What Zend Framework is
  102. 103. Some common utilities/patterns used (autoloading, plugins, configuration)
  103. 104. How to build a ZF MVC application </li></ul>We looked at:
  104. 105. Questions? or, “Your turn!”
  105. 106. Thank you. http://framework.zend.com/ http://twitter.com/weierophinney http://slideshare.net/weierophinney Feedback? http://joind.in/talk/view/878
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×