Zend Framework's Little Known Gems Matthew Weier O'Phinney Software Architect Zend Framework
What is Zend Framework?
Full Stack Framework?
Component Library?
Both.
 
Why loosely coupled matters
PHP has been around for > 10 years
PHP has a low barrier to entry
Many successful PHP applications have been written in that time frame
<ul><li>Many of these applications suck </li></ul><ul><li>from an architectural standpoint: </li></ul><ul><li>Many PHP dev...
Refactoring sucks
Loosely coupled libraries allow you to refactor incrementally
Little Known Gems
Zend_Acl
Basic ACLs $acl   =   new   Zend_Acl (); $acl -> addRole ( new   Zend_Acl_Role ( 'guest' )) -> addRole ( new   Zend_Acl_Ro...
Custom ACL role class   Wiki_Role_Guest    implements Zend_Acl_Role_Interface { public   function   getRoleId () { return ...
Mixing ACL interfaces into models class   Wiki_Guest    implements Zend_Acl_Role_Interface { public   function   getRoleId...
Zend_Cache
Creating a cache object $cache   =   Zend_Cache :: factory ( 'Core' ,   // cache object frontend 'File' ,   // caching bac...
Using a cache if   (! $data   =   $cache -> load ( 'foo' )) { $data   =   $someLongRunning -> process (); $cache -> save (...
Using tags with caching if   (! $data   =   $cache -> load ( 'foo' )) { $data   =   $someLongRunning -> process (); // Use...
Zend_Config
Several configuration backends // Load 'testing' section of INI configuration: $config   =   new   Zend_Config_Ini ( $file...
Sample INI configuration [production] app.name  =   &quot;Foo!&quot; db.adapter  =   &quot;Pdo_Mysql&quot; db.params.usern...
Sample XML configuration <?xml   version = &quot;1.0&quot;   ?> <config> <production> <app><name> Foo! </name></app> <db> ...
Sample PHP configuration $production   =   file_get_contents ( 'production.conf.php' ); $config   =   array ( 'db'   =>   ...
Zend_Dom_Query
Simple link screen scraper $dom   =   new   Zend_Dom_Query ( $html ); $nodes   =   $dom -> query ( '#content a' ); if   ( ...
Zend_Dom_Query powers Zend_Test_PHPUnit assertions class   FooControllerTest     extends   Zend_Test_PHPUnit_ControllerTes...
Zend_Json_Server and Zend_XmlRpc_Server
JSON-RPC server with  Service Mapping Description $server   =   new   Zend_Json_Server (); $server -> setClass ( 'My_FormH...
XML-RPC server $server   =   new   Zend_XmlRpc_Server (); $server -> setClass ( 'My_FormHandler' ); echo   $server -> hand...
Zend_Loader_PluginLoader
Basic plugin loading $loader   =   new   Zend_Loader_PluginLoader ( array ( 'Foo_Bar'   =>   'path/to/foo/' , 'Bar_Baz'   ...
Use inflection for  better plugin loading class   My_Loader   extends   Zend_Loader_PluginLoader { public   function   inf...
Zend_Log_Writer_Firebug
Log to FireBug $writer   =   new   Zend_Log_Writer_Firebug (); $log   =   new   Zend_Log ( $writer ); $channel   =   Zend_...
Akismet, ReCaptcha, and Captcha, oh my!
Akismet $akismet   =   new   Zend_Service_Akismet ( $apiKey ,   $url ); if   (! $akismet -> verifyKey ()) { throw new   Ex...
ReCaptcha $captcha   =   new   Zend_Service_ReCaptcha ( $pubKey ,   $privKey ); // Render it: $captcha -> getHTML (); // V...
Captcha $captcha   =   new   Zend_Captcha_Figlet ( array ( 'name'   =>   'foo' , 'wordLen'   =>   6 ,   // Length of captc...
Questions?
Thank you.
Upcoming SlideShare
Loading in...5
×

Zend Framework's Little Known Gems

21,067

Published on

Short introduction to Zend Framework, followed by examples of several core components.

Published in: Technology
1 Comment
7 Likes
Statistics
Notes
  • they should figure out how to narrate these so slides with just a heading have some context behind them.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
21,067
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
174
Comments
1
Likes
7
Embeds 0
No embeds

No notes for slide

Zend Framework's Little Known Gems

  1. 1. Zend Framework's Little Known Gems Matthew Weier O'Phinney Software Architect Zend Framework
  2. 2. What is Zend Framework?
  3. 3. Full Stack Framework?
  4. 4. Component Library?
  5. 5. Both.
  6. 7. Why loosely coupled matters
  7. 8. PHP has been around for > 10 years
  8. 9. PHP has a low barrier to entry
  9. 10. Many successful PHP applications have been written in that time frame
  10. 11. <ul><li>Many of these applications suck </li></ul><ul><li>from an architectural standpoint: </li></ul><ul><li>Many PHP developers never learn good programming skills </li></ul><ul><li>Many PHP developers never learn design patterns </li></ul><ul><li>Many of these applications do not follow MVC paradigms </li></ul>
  11. 12. Refactoring sucks
  12. 13. Loosely coupled libraries allow you to refactor incrementally
  13. 14. Little Known Gems
  14. 15. Zend_Acl
  15. 16. Basic ACLs $acl = new Zend_Acl (); $acl -> addRole ( new Zend_Acl_Role ( 'guest' )) -> addRole ( new Zend_Acl_Role ( 'admin' ), 'guest' ) -> add ( new Zend_Acl_Resource ( 'wiki' )) -> allow ( 'guest' , 'wiki' , array ( 'view' , 'list' , 'feed' )) -> allow ( 'admin' , 'wiki' ); if ( $acl -> isAllowed ( $role , 'wiki' , 'list' )) { // woohoo! }
  16. 17. Custom ACL role class Wiki_Role_Guest implements Zend_Acl_Role_Interface { public function getRoleId () { return 'guest' ; } }
  17. 18. Mixing ACL interfaces into models class Wiki_Guest implements Zend_Acl_Role_Interface { public function getRoleId () { return 'guest' ; } public function save () { $this -> dataSource -> save ( $this -> toArray () ); } // ... }
  18. 19. Zend_Cache
  19. 20. Creating a cache object $cache = Zend_Cache :: factory ( 'Core' , // cache object frontend 'File' , // caching backend array ( // frontend options 'lifetime' => 3600 , // seconds 'automatic_serialization' => true , ), array ( // backend options 'cache_dir' => APPLICATION_PATH . '/cache' , ) );
  20. 21. Using a cache if (! $data = $cache -> load ( 'foo' )) { $data = $someLongRunning -> process (); $cache -> save ( $data , 'foo' ); } $view -> data = $data ;
  21. 22. Using tags with caching if (! $data = $cache -> load ( 'foo' )) { $data = $someLongRunning -> process (); // Use tags to group records for later cleaning $cache -> save ( $data , 'foo' , array ( 'bar' , 'baz' )); } // Clean all records tagged 'bar': $cache -> clean ( Zend_Cache :: CLEANING_MODE_MATCHING_TAG , array ( 'bar' ) );
  22. 23. Zend_Config
  23. 24. Several configuration backends // 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 = new Zend_Config ( file_get_contents ( 'testing.conf.php' ));
  24. 25. Sample INI configuration [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;
  25. 26. Sample XML configuration <?xml version = &quot;1.0&quot; ?> <config> <production> <app><name> Foo! </name></app> <db> <adapter> Pdo_Mysql </adapter> <params> <username> foo </username> <password> bar </password> <dbname> foodb </dbname> <host> 127.0.0.1 </host> </params> </db> </production> <testing extends = &quot;production&quot; > <db> <adapter> Pdo_Sqlite </adapter> <params> <dbname> /data/test.db </dbname> </params> </db> </testing> </config>
  26. 27. Sample PHP configuration $production = file_get_contents ( 'production.conf.php' ); $config = array ( 'db' => array ( 'adapter' => 'Pdo_Sqlite' , 'params' => array ( 'dbname' => APP_PATH . '/data/test.db' , ), ) ); $config = $production + $config ; return $config ;
  27. 28. Zend_Dom_Query
  28. 29. Simple link screen scraper $dom = new Zend_Dom_Query ( $html ); $nodes = $dom -> query ( '#content a' ); if ( 0 > count ( $nodes )) { foreach ( $nodes as $node ) { // do something with link DOM node } }
  29. 30. Zend_Dom_Query powers Zend_Test_PHPUnit assertions class FooControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { public function testHomePagHasAtLeast3Links () { $this -> dispatch ( '/' ); $this -> assertQueryCountMin ( '#content a' , 3 ); } }
  30. 31. Zend_Json_Server and Zend_XmlRpc_Server
  31. 32. JSON-RPC server with Service Mapping Description $server = new Zend_Json_Server (); $server -> setClass ( 'My_FormHandler' ); // Return the Service Mapping Description, if requested if ( 'GET' == strtoupper ( $_SERVER [ 'REQUEST_METHOD' ])) { $server -> setTarget ( '/jsonrpc' ) -> setEnvelope ( Zend_Json_Server_Smd :: ENV_JSONRPC_2 ); // Grab the SMD $smd = $server -> getServiceMap (); // Return the SMD to the client header ( 'Content-Type: application/json' ); echo $smd ; return ; } // Handle the request $server -> handle ();
  32. 33. XML-RPC server $server = new Zend_XmlRpc_Server (); $server -> setClass ( 'My_FormHandler' ); echo $server -> handle ();
  33. 34. Zend_Loader_PluginLoader
  34. 35. Basic plugin loading $loader = new Zend_Loader_PluginLoader ( array ( 'Foo_Bar' => 'path/to/foo/' , 'Bar_Baz' => 'path/to/bar/' , )); // Load 'Bat' plugin: $class = $loader -> load ( 'bat' ); $bat = new $class (); // Foo_Bar_Bat or // Bar_Baz_Bat
  35. 36. Use inflection for better plugin loading class My_Loader extends Zend_Loader_PluginLoader { public function inflectName ( $name ) { $inflector = new Zend_Filter_Inflector ( ':name' ); $inflector -> setRules ( array ( 'name' => array ( 'StringToLower' , 'Word_DashToCamelCase' ), )); return $inflector -> filter ( array ( 'name' => $name )); } public function load ( $name ) { $name = $this -> inflectName ( $name ); return parent :: load ( $name ); } }
  36. 37. Zend_Log_Writer_Firebug
  37. 38. Log to FireBug $writer = new Zend_Log_Writer_Firebug (); $log = new Zend_Log ( $writer ); $channel = Zend_Wildfire_Channel_HttpHeaders :: getInstance (); $channel -> setRequest ( new Zend_Controller_Request_Http ()) -> setResponse ( new Zend_Controller_Response_Http ()); ob_start (); // ... $log -> info ( 'Firebug integration!' ); // flush log and send headers... $channel -> flush (); $channel -> getResponse ()-> sendHeaders ();
  38. 39. Akismet, ReCaptcha, and Captcha, oh my!
  39. 40. Akismet $akismet = new Zend_Service_Akismet ( $apiKey , $url ); if (! $akismet -> verifyKey ()) { throw new Exception ( 'Invalid Akismet key' ); } $data = array ( 'user_ip' => $_SERVER [ 'REMOTE_ADDR' ], 'user_agent' => $_SERVER [ 'HTTP_USER_AGENT' ], 'comment_content' => $submittedContent , 'comment_type' => 'email' , 'comment_author_email' => $submittedEmail , ); if ( $akismet -> isSpam ( $data )) { $log -> info ( 'Spam trapped: ' . var_export ( $data , 1 )); }
  40. 41. ReCaptcha $captcha = new Zend_Service_ReCaptcha ( $pubKey , $privKey ); // Render it: $captcha -> getHTML (); // Verify it: $result = $captcha -> verify ( $challenge , $response ); if (! $result -> isValid ()) { // slap their wrist }
  41. 42. Captcha $captcha = new Zend_Captcha_Figlet ( array ( 'name' => 'foo' , 'wordLen' => 6 , // Length of captcha 'timeout' => 300 , // Validation dur. )); $id = $captcha -> generate (); // Render it: echo $captcha -> render ( $view ); // Verify it: if (! $captcha -> isValid ( $data [ 'foo' ], $data )) { // slap their wrist }
  42. 43. Questions?
  43. 44. Thank you.
  1. A particular slide catching your eye?

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

×