Secret sauce of building                    PHP applications                         林佑安 (Yo-An Lin)                      ...
About                         •   GitHub, Twitter, Plurk: @c9s                         •   220+ GitHub repository in Perl,...
為什麼是                          PHP?Monday, January 14, 13
Hey! PHP SucksMonday, January 14, 13
PHP Sucks!Monday, January 14, 13
2000 年開始使⽤用 PHP websites ⼤大幅成⻑⾧長Monday, January 14, 13
Monday, January 14, 13
⾼高流量 PHP 網站                          High traffic PHP                             websitesMonday, January 14, 13
Monday, January 14, 13
Monday, January 14, 13
Monday, January 14, 13
Monday, January 14, 13
Monday, January 14, 13
Monday, January 14, 13
Monday, January 14, 13
http://highscalability.com/flickr-architectureMonday, January 14, 13
Monday, January 14, 13
Monday, January 14, 13
Monday, January 14, 13
Monday, January 14, 13
Monday, January 14, 13
Monday, January 14, 13
Monday, January 14, 13
Monday, January 14, 13
Monday, January 14, 13
Applications developed                      with Symfony.                         http://trac.symfony-project.org/wiki/   ...
Yii powered                              applications                         http://www.yiiframework.com/forum/          ...
⼤大家都跑                           PHPMonday, January 14, 13
為什麼?Monday, January 14, 13
劣即是夯                            唐鳳 - OSDC 2012Monday, January 14, 13
有多夯?Monday, January 14, 13
去街上問Monday, January 14, 13
⼗十個有九個                         都會寫 PHPMonday, January 14, 13
你Grandma都會寫 PHP                         我也寫 PHPMonday, January 14, 13
但是Monday, January 14, 13
你還在使⽤用⽯石器時代                       的 PHP 嗎?Monday, January 14, 13
⽯石器時代 PHP ?Monday, January 14, 13
⽯石器時代義⼤大利麵Monday, January 14, 13
⽯石器時代 PHPMonday, January 14, 13
⽯石器時代 PHP                    • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂)Monday, January 14, 13
⽯石器時代 PHP                    • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂)                    • Copy & Paste (品質低落)Monday, January 14, 13
⽯石器時代 PHP                    • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂)                    • Copy & Paste (品質低落)                    ...
⽯石器時代 PHP                    • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂)                    • Copy & Paste (品質低落)                    ...
⽯石器時代 PHP                    • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂)                    • Copy & Paste (品質低落)                    ...
⽯石器時代 PHP                    • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂)                    • Copy & Paste (品質低落)                    ...
為什麼?Monday, January 14, 13
24⼩小時學會 PHPMonday, January 14, 13
24⼩小時學會 PHP                    • 語⾔言學習⼊入⾨門⾨門檻低Monday, January 14, 13
24⼩小時學會 PHP                    • 語⾔言學習⼊入⾨門⾨門檻低                    • 隨便寫,丟給 Apache 就可以執⾏行了Monday, January 14, 13
24⼩小時學會 PHP                    • 語⾔言學習⼊入⾨門⾨門檻低                    • 隨便寫,丟給 Apache 就可以執⾏行了                    • $_POST, $_G...
24⼩小時學會 PHP                    • 語⾔言學習⼊入⾨門⾨門檻低                    • 隨便寫,丟給 Apache 就可以執⾏行了                    • $_POST, $_G...
寫這樣的 PHP            您⼼心安嗎?Monday, January 14, 13
現代 PHP 解決⽅方案                    The Modern PHP SolutionMonday, January 14, 13
Modern Tools                    • PSR                    • Composer / Onion / PEAR / Pyrus                    • phpbrew / ...
PHP spl_autoload_*Monday, January 14, 13
Zend Engine                         CompilationMonday, January 14, 13
Request                             File a.php                             Scanning              Zend Engine     Lexing   ...
Request                                                         File a.php                         Require b.php   Require...
Request                                                         File a.php                         Require b.php   Require...
Request            x 100,000                                                          File a.php                         R...
那 APC 呢?Monday, January 14, 13
Request            x 100,000                                                            File a.php                        ...
Monday, January 14, 13
這就是                                       WordPress                                       慢的原因                         htt...
PHP spl_autoload_*                    • PHP 5.3+ 的新功能。Monday, January 14, 13
PHP spl_autoload_*                    • PHP 5.3+ 的新功能。                    • 可註冊⾃自訂的類別載⼊入策略 (autoloading                   ...
PHP spl_autoload_*                    • PHP 5.3+ 的新功能。                    • 可註冊⾃自訂的類別載⼊入策略 (autoloading                   ...
PHP spl_autoload_*                    • PHP 5.3+ 的新功能。                    • 可註冊⾃自訂的類別載⼊入策略 (autoloading                   ...
PSR                         ⾞車同軌,書同⽂文Monday, January 14, 13
PSR-0 for PHP class                           定義了 ClassLoader 的規範Monday, January 14, 13
$bar = new FooBar;                                     spl_autoload_call(“FooBar”)Monday, January 14, 13
Package dependency                             套件相依性Monday, January 14, 13
套件相依性可以很混亂Monday, January 14, 13
Package dependenciesMonday, January 14, 13
Package dependenciesMonday, January 14, 13
Package dependenciesMonday, January 14, 13
Composer                                  https://github.com/composer/composer                         http://www.slidesha...
Composer                                  https://github.com/composer/composer                    • composer.json 取材於 Node...
Composer                                     https://github.com/composer/composer                    • composer.json 取材於 N...
Composer                                     https://github.com/composer/composer                    • composer.json 取材於 N...
Composer                                     https://github.com/composer/composer                    • composer.json 取材於 N...
Composer                                     https://github.com/composer/composer                    • composer.json 取材於 N...
Onion                         http://github.com/c9s/OnionMonday, January 14, 13
Onion                            http://github.com/c9s/Onion                    • PEAR 向後相容⼯工具Monday, January 14, 13
Onion                             http://github.com/c9s/Onion                    • PEAR 向後相容⼯工具                    • 提供簡易的...
Onion                             http://github.com/c9s/Onion                    • PEAR 向後相容⼯工具                    • 提供簡易的...
Onion                                    http://github.com/c9s/Onion                    • PEAR 向後相容⼯工具                    ...
PHP 版本環境⼯工具Monday, January 14, 13
phpbrew                         http://github.com/c9s/phpbrewMonday, January 14, 13
phpbrew                              http://github.com/c9s/phpbrew                    • 取材⾃自 @gugod perlbrewMonday, Januar...
phpbrew                              http://github.com/c9s/phpbrew                    • 取材⾃自 @gugod perlbrew              ...
phpbrew                                http://github.com/c9s/phpbrew                    • 取材⾃自 @gugod perlbrew            ...
phpbrew                                http://github.com/c9s/phpbrew                    • 取材⾃自 @gugod perlbrew            ...
phpbrew                                    http://github.com/c9s/phpbrew                    • 取材⾃自 @gugod perlbrew        ...
PHP library/app from                              corneltekMonday, January 14, 13
PHP Projects                    •    phpbrew          •   PEARX                    •    CLIFramework     •   Universal    ...
為什麼要重造輪⼦子?Monday, January 14, 13
設計軟體 != 設計輪⼦子Monday, January 14, 13
It’s not that simple                         並⾮非像輪⼦子那樣的簡單Monday, January 14, 13
軟體有相依性                          但輪⼦子沒有Monday, January 14, 13
⼀一旦應⽤用程式相依了他⼈人的框架           你的開發模式也將受到侷限Monday, January 14, 13
開發⼯工具與⼈人息息相關       但輪⼦子只需透過輪軸傳動Monday, January 14, 13
使⽤用他⼈人的 FullStack 框架Monday, January 14, 13
嘗到的是短期的甜頭Monday, January 14, 13
犧牲的是未來的無限可能Monday, January 14, 13
什麼是 FullStack                          Framework ?Monday, January 14, 13
就是⼀一整包送給你Monday, January 14, 13
FullStack Framework                    • Rails                    • Zend Framework                    • Symfony           ...
使⽤用⼀一個架構快速⼤大幅修改的框架                         FW 1.0Monday, January 14, 13
使⽤用⼀一個架構快速⼤大幅修改的框架                         FW 1.0                         App A                           這個 FW 好像不錯      ...
使⽤用⼀一個架構快速⼤大幅修改的框架                         FW 1.0   FW 2.0                         App AMonday, January 14, 13
使⽤用⼀一個架構快速⼤大幅修改的框架                         FW 1.0   FW 2.0                         App A    App B                 改太多     ...
使⽤用⼀一個架構快速⼤大幅修改的框架                         FW 1.0   FW 2.0   FW 3.0                         App A    App BMonday, January ...
使⽤用⼀一個架構快速⼤大幅修改的框架                         FW 1.0   FW 2.0     FW 3.0                         App A    App B              ...
使⽤用⼀一個架構快速⼤大幅修改的框架                         FW 1.0   FW 2.0      FW 3.0                         App A    App B       App C ...
使⽤用⼀一個架構快速⼤大幅修改的框架                                                             security                         FW 1.0   F...
使⽤用 FullStack 框架之侷限Monday, January 14, 13
使⽤用 FullStack 框架之侷限                    • 隨著框架不斷修改內建⾏行為, 升級                         的過程,就會有越多不確定因素                         ...
使⽤用 FullStack 框架之侷限                    • 隨著框架不斷修改內建⾏行為, 升級                         的過程,就會有越多不確定因素                         ...
使⽤用 FullStack 框架之侷限                    • 隨著框架不斷修改內建⾏行為, 升級                         的過程,就會有越多不確定因素                         ...
Allen Own 不安定因素Monday, January 14, 13
Allen Own 不安定因素Monday, January 14, 13
So how do we do that?Monday, January 14, 13
Divide and ConquerMonday, January 14, 13
Framework should just                      be “framework”Monday, January 14, 13
Components should be                  easy to adapt/swapMonday, January 14, 13
Each component should                  have a package state                     - API stability                   -Package...
Component A          The core is pretty small,          we don’t need to change     Framework         Component B         ...
Component A 2.0                                                            API Lock                                       ...
We can build another new                                                                  framework very easily.          ...
How do we build CLI                            applications?Monday, January 14, 13
CLIFramework                          https://github.com/c9s/CLIFrameworkMonday, January 14, 13
CLIFramework                    • 提供最快最簡易的⽅方式建置⼀一個命令列                         的⼯工具                    • phpbrew, onion, cl...
CLIFramework                               ⽀支持⼦子命令及⼦子命令選項Monday, January 14, 13
CLIFramework                         <?php                         namespace TestAppCommand;                         use C...
CLIFramework          <?php          namespace YourApp;          use CLIFrameworkApplication;          class CLIApplicatio...
CLIFramework                         <?php                         $app = new TestAppApplication;                         ...
CLIFramework                         ⾃自動產⽣生的 Command-line helpMonday, January 14, 13
How do we generate                              forms?Monday, January 14, 13
FormKit                         https://github.com/c9s/FormKitMonday, January 14, 13
FormKit                    • A powerful form widget generator.                    • Simple API for defining widgets and lay...
FormKit: TextInput         <?php         $text = new FormKitWidgetTextInput(username, array(             label => Username...
FormKit         <?php         $countries = new FormKitWidgetSelectInput( country , array(             label => Country,   ...
FormKit: GenericLayout                         <?php                         $layout = new FormKitLayoutGenericLayout;    ...
FormKit: Helpers                         <?php                         use FormKitFormKit;                         $userna...
Available Widgets                    •    TextareaInput                                         •   Label                 ...
For more details                          http://github.com/c9s/FormKitMonday, January 14, 13
How do we define                          logics for forms?Monday, January 14, 13
ActionKit                         https://github.com/c9s/ActionKitMonday, January 14, 13
ActionKit                    • Let you define logics and form field                         definitions.                    •...
If I have a login form                             and login logicsMonday, January 14, 13
<?php                         namespace UserAction;                         use ActionKit;                         class L...
<?php                         namespace UserAction;                         use ActionKit;                         class L...
ActionKit: The API                         <?php                         $action = new UserActionLogin;                   ...
ActionKit: The API              <?php              $runner = ActionKitActionRunner::getInstance();              $runner->r...
How do we dispatch                               URL?Monday, January 14, 13
Roller Router                           https://github.com/c9s/RollerMonday, January 14, 13
Roller Router                    • A fast router for PHP.Monday, January 14, 13
Roller Router                    • A fast router for PHP.                    • Designed for performance.Monday, January 14...
Roller Router                    • A fast router for PHP.                    • Designed for performance.                  ...
Roller Router                    • A fast router for PHP.                    • Designed for performance.                  ...
Roller Router                    • A fast router for PHP.                    • Designed for performance.                  ...
Roller Router                    • A fast router for PHP.                    • Designed for performance.                  ...
Roller Router                    • A fast router for PHP.                    • Designed for performance.                  ...
Roller Router              <?php              $router = new RollerRouter( null, array(                  cache_id => router...
Roller Router              <?php              $router = new RollerRouter( null, array(                  cache_id => router...
Roller Router              <?php              $router = new RollerRouter( null, array(                  cache_id => router...
Roller: Add routes                  <?php                  $router->add( /posts/:id,                        array(PostCont...
Roller with DSL                 <?php                 require bootstrap.php;                 require Roller/DSL.php;      ...
One more thing!Monday, January 14, 13
If you’re using PHP5.4+Monday, January 14, 13
You can even use the                         built-in HTTP server.Monday, January 14, 13
Roller Router                  <?php                  if (php_sapi_name() == cli-server) {                      $uri = $_S...
$ php -S localhost:8888 router.phpMonday, January 14, 13
How about RESTful?Monday, January 14, 13
<?php                             Roller + RESTful                     class MyGenericHandler extends RollerPluginRESTfulG...
Mount your RESTful                              handler     $restful = new RollerPluginRESTful(array( prefix => /= ));    ...
For more details                           http://github.com/c9s/RollerMonday, January 14, 13
LazyRecord                          https://github.com/c9s/RollerMonday, January 14, 13
A Fast PHP ORMMonday, January 14, 13
Why another PHP                             ORM ?Monday, January 14, 13
PHP ORMs                    • DoctrineMonday, January 14, 13
PHP ORMs                    • Doctrine                    • PropelMonday, January 14, 13
PHP ORMs                    • Doctrine                    • Propel                    • Idiorm / ParisMonday, January 14, 13
Propel / Doctrine                    • Propel uses XML Schema file.Monday, January 14, 13
Propel / Doctrine                    • Propel uses XML Schema file.                    • Doctrine uses XML/YAML/Annotations...
Propel / Doctrine                    • Propel uses XML Schema file.                    • Doctrine uses XML/YAML/Annotations...
Propel / Doctrine                    • Propel uses XML Schema file.                    • Doctrine uses XML/YAML/Annotations...
Common characteristicMonday, January 14, 13
• XML for configuration file.                    • XML for schema file.                    • XML for everything.             ...
Propel XML                         runtime.confMonday, January 14, 13
<?xml version="1.0"?>                <config>                   <log>                      <ident>propel-bookstore</ident>...
<datasource id="bookstore">                        <adapter>sqlite</adapter>                        <connection>          ...
Monday, January 14, 13
So we designed an                            easier ORMMonday, January 14, 13
LazyRecord                    • Lazy attributes.Monday, January 14, 13
LazyRecord                    • Lazy attributes.                    • Lazy schema loader.Monday, January 14, 13
LazyRecord                    • Lazy attributes.                    • Lazy schema loader.                    • Dynamic sch...
LazyRecord                    • Lazy attributes.                    • Lazy schema loader.                    • Dynamic sch...
LazyRecord                    • Lazy attributes.                    • Lazy schema loader.                    • Dynamic sch...
LazyRecord                    • Filter / Canonicalizer support.Monday, January 14, 13
LazyRecord                    • Filter / Canonicalizer support.                    • CRUD support via ActionKit.Monday, Ja...
LazyRecord                    • Filter / Canonicalizer support.                    • CRUD support via ActionKit.          ...
LazyRecord                    • Filter / Canonicalizer support.                    • CRUD support via ActionKit.          ...
LazyRecord: Schema                          <?php                          namespace TodosModel;                          ...
LazyRecord: Model              <?php              $author = new Author;              $ret = $author->create([             ...
LazyRecord: Collection                         <?php                         $authors = new AuthorCollection;             ...
LazyRecord: Collection                         $authors = new AuthorCollection;                         $authors->where() ...
LazyRecord: Collection               $newAuthors = $authors->filter(function($item) {                   // do something el...
Powerful featuresMonday, January 14, 13
Model Schema ->                         CRUD Actions ->                           Form LayoutMonday, January 14, 13
LazyRecord                         Model SchemaMonday, January 14, 13
LazyRecord          Model Schema ⇛ ActionMonday, January 14, 13
LazyRecord       Model Schema ⇛ Action ⇛                                 CRUDMonday, January 14, 13
LazyRecord                         App::Model::Phone ☚ write onceMonday, January 14, 13
LazyRecord                              App::Model::Phone                         App::Model::PhoneCollectionMonday, Janua...
LazyRecord                              App::Model::Phone                         App::Model::PhoneCollection             ...
LazyRecord                              App::Model::Phone                         App::Model::PhoneCollection             ...
LazyRecord                              App::Model::Phone                         App::Model::PhoneCollection             ...
LazyRecord                              App::Model::Phone                         App::Model::PhoneCollection             ...
LazyRecord                                  App::Model::Phone                             App::Model::PhoneCollection     ...
MigrationMonday, January 14, 13
2013 年                    還在⾃自⼰己⼿手動下 SQL                     做 migration 嗎?Monday, January 14, 13
Monday, January 14, 13
Schema UpgradeMonday, January 14, 13
Monday, January 14, 13
For more details                          http://github.com/c9s/LazyRecord                         http://www.slideshare.n...
Thank you                         Find me: Twitter: @c9sMonday, January 14, 13
Upcoming SlideShare
Loading in...5
×

Secret sauce of building php applications

8,461

Published on

Published in: Technology
0 Comments
42 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
8,461
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
181
Comments
0
Likes
42
Embeds 0
No embeds

No notes for slide

Secret sauce of building php applications

  1. 1. Secret sauce of building PHP applications 林佑安 (Yo-An Lin) aka c9sMonday, January 14, 13
  2. 2. About • GitHub, Twitter, Plurk: @c9s • 220+ GitHub repository in Perl, VimL, PHP, JavaScript and Go.Monday, January 14, 13
  3. 3. 為什麼是 PHP?Monday, January 14, 13
  4. 4. Hey! PHP SucksMonday, January 14, 13
  5. 5. PHP Sucks!Monday, January 14, 13
  6. 6. 2000 年開始使⽤用 PHP websites ⼤大幅成⻑⾧長Monday, January 14, 13
  7. 7. Monday, January 14, 13
  8. 8. ⾼高流量 PHP 網站 High traffic PHP websitesMonday, January 14, 13
  9. 9. Monday, January 14, 13
  10. 10. Monday, January 14, 13
  11. 11. Monday, January 14, 13
  12. 12. Monday, January 14, 13
  13. 13. Monday, January 14, 13
  14. 14. Monday, January 14, 13
  15. 15. Monday, January 14, 13
  16. 16. http://highscalability.com/flickr-architectureMonday, January 14, 13
  17. 17. Monday, January 14, 13
  18. 18. Monday, January 14, 13
  19. 19. Monday, January 14, 13
  20. 20. Monday, January 14, 13
  21. 21. Monday, January 14, 13
  22. 22. Monday, January 14, 13
  23. 23. Monday, January 14, 13
  24. 24. Monday, January 14, 13
  25. 25. Monday, January 14, 13
  26. 26. Applications developed with Symfony. http://trac.symfony-project.org/wiki/ ApplicationsDevelopedWithSymfony 1000+ websites listed.Monday, January 14, 13
  27. 27. Yii powered applications http://www.yiiframework.com/forum/ index.php/forum/14-yii-powered- applications/Monday, January 14, 13
  28. 28. ⼤大家都跑 PHPMonday, January 14, 13
  29. 29. 為什麼?Monday, January 14, 13
  30. 30. 劣即是夯 唐鳳 - OSDC 2012Monday, January 14, 13
  31. 31. 有多夯?Monday, January 14, 13
  32. 32. 去街上問Monday, January 14, 13
  33. 33. ⼗十個有九個 都會寫 PHPMonday, January 14, 13
  34. 34. 你Grandma都會寫 PHP 我也寫 PHPMonday, January 14, 13
  35. 35. 但是Monday, January 14, 13
  36. 36. 你還在使⽤用⽯石器時代 的 PHP 嗎?Monday, January 14, 13
  37. 37. ⽯石器時代 PHP ?Monday, January 14, 13
  38. 38. ⽯石器時代義⼤大利麵Monday, January 14, 13
  39. 39. ⽯石器時代 PHPMonday, January 14, 13
  40. 40. ⽯石器時代 PHP • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂)Monday, January 14, 13
  41. 41. ⽯石器時代 PHP • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂) • Copy & Paste (品質低落)Monday, January 14, 13
  42. 42. ⽯石器時代 PHP • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂) • Copy & Paste (品質低落) • .inc 附檔名 (安全漏洞)Monday, January 14, 13
  43. 43. ⽯石器時代 PHP • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂) • Copy & Paste (品質低落) • .inc 附檔名 (安全漏洞) • ⼤大量的 require 呼叫循環 (效能問題)Monday, January 14, 13
  44. 44. ⽯石器時代 PHP • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂) • Copy & Paste (品質低落) • .inc 附檔名 (安全漏洞) • ⼤大量的 require 呼叫循環 (效能問題) • HTML Render 不做 Escape (XSS 漏洞)Monday, January 14, 13
  45. 45. ⽯石器時代 PHP • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂) • Copy & Paste (品質低落) • .inc 附檔名 (安全漏洞) • ⼤大量的 require 呼叫循環 (效能問題) • HTML Render 不做 Escape (XSS 漏洞) • POST/GET 從不過濾 (SQL Injection)Monday, January 14, 13
  46. 46. 為什麼?Monday, January 14, 13
  47. 47. 24⼩小時學會 PHPMonday, January 14, 13
  48. 48. 24⼩小時學會 PHP • 語⾔言學習⼊入⾨門⾨門檻低Monday, January 14, 13
  49. 49. 24⼩小時學會 PHP • 語⾔言學習⼊入⾨門⾨門檻低 • 隨便寫,丟給 Apache 就可以執⾏行了Monday, January 14, 13
  50. 50. 24⼩小時學會 PHP • 語⾔言學習⼊入⾨門⾨門檻低 • 隨便寫,丟給 Apache 就可以執⾏行了 • $_POST, $_GET 是什麼⻤⿁鬼 (管他,可以跑 就好了)Monday, January 14, 13
  51. 51. 24⼩小時學會 PHP • 語⾔言學習⼊入⾨門⾨門檻低 • 隨便寫,丟給 Apache 就可以執⾏行了 • $_POST, $_GET 是什麼⻤⿁鬼 (管他,可以跑 就好了) • 義⼤大利麵好煮⼜又好吃,維護是什麼?沒 聽過!Monday, January 14, 13
  52. 52. 寫這樣的 PHP 您⼼心安嗎?Monday, January 14, 13
  53. 53. 現代 PHP 解決⽅方案 The Modern PHP SolutionMonday, January 14, 13
  54. 54. Modern Tools • PSR • Composer / Onion / PEAR / Pyrus • phpbrew / phpenv / phpbuild • ClassLoader via spl_autoload_* functions • New language features (traits, spl, generator...)Monday, January 14, 13
  55. 55. PHP spl_autoload_*Monday, January 14, 13
  56. 56. Zend Engine CompilationMonday, January 14, 13
  57. 57. Request File a.php Scanning Zend Engine Lexing Compilation AST Parsing Compilation Execution OutputMonday, January 14, 13
  58. 58. Request File a.php Require b.php Require c.php Require d.php Require e.php Scanning Scanning Scanning Scanning Lexing Lexing Lexing Lexing Parsing Parsing Parsing Parsing Compilation Compilation Compilation Compilation Execution OutputMonday, January 14, 13
  59. 59. Request File a.php Require b.php Require c.php Require d.php Require e.php Scanning Scanning Scanning Scanning Lexing Lexing Lexing Lexing Parsing Parsing Parsing Parsing Compilation Compilation Compilation Compilation Execution 只⽤用到 b.php 的 function OutputMonday, January 14, 13
  60. 60. Request x 100,000 File a.php Require b.php Require c.php Require d.php Require e.php Scanning Scanning Scanning Scanning Lexing Lexing Lexing Lexing Parsing Parsing Parsing Parsing Compilation Compilation Compilation Compilation 資源浪費 (CPU + Memory) x 100,000 Execution OutputMonday, January 14, 13
  61. 61. 那 APC 呢?Monday, January 14, 13
  62. 62. Request x 100,000 File a.php Require b.php Require c.php Require d.php Require e.php Scanning Lexing fstat check fstat check fstat check Parsing unserialize op cache unserialize op cache unserialize op cache Compilation 仍須作 filestat check (default) Memory 照樣浪費 Execution OutputMonday, January 14, 13
  63. 63. Monday, January 14, 13
  64. 64. 這就是 WordPress 慢的原因 http://talks.php.net/presentations/slides/intro/wp_inclued1.pngMonday, January 14, 13
  65. 65. PHP spl_autoload_* • PHP 5.3+ 的新功能。Monday, January 14, 13
  66. 66. PHP spl_autoload_* • PHP 5.3+ 的新功能。 • 可註冊⾃自訂的類別載⼊入策略 (autoloading strategy)Monday, January 14, 13
  67. 67. PHP spl_autoload_* • PHP 5.3+ 的新功能。 • 可註冊⾃自訂的類別載⼊入策略 (autoloading strategy) • 對於找不到定義的類別,⾃自動呼叫 class loader 進⾏行類別的⾃自動載⼊入。Monday, January 14, 13
  68. 68. PHP spl_autoload_* • PHP 5.3+ 的新功能。 • 可註冊⾃自訂的類別載⼊入策略 (autoloading strategy) • 對於找不到定義的類別,⾃自動呼叫 class loader 進⾏行類別的⾃自動載⼊入。 • 每個 request 只會載⼊入⾃自⼰己需要的 class, ⽤用越少,載越少。Monday, January 14, 13
  69. 69. PSR ⾞車同軌,書同⽂文Monday, January 14, 13
  70. 70. PSR-0 for PHP class 定義了 ClassLoader 的規範Monday, January 14, 13
  71. 71. $bar = new FooBar; spl_autoload_call(“FooBar”)Monday, January 14, 13
  72. 72. Package dependency 套件相依性Monday, January 14, 13
  73. 73. 套件相依性可以很混亂Monday, January 14, 13
  74. 74. Package dependenciesMonday, January 14, 13
  75. 75. Package dependenciesMonday, January 14, 13
  76. 76. Package dependenciesMonday, January 14, 13
  77. 77. Composer https://github.com/composer/composer http://www.slideshare.net/naderman/composer-9206307Monday, January 14, 13
  78. 78. Composer https://github.com/composer/composer • composer.json 取材於 Node.js NPM http://www.slideshare.net/naderman/composer-9206307Monday, January 14, 13
  79. 79. Composer https://github.com/composer/composer • composer.json 取材於 Node.js NPM • 更好的相依性解決⽅方案 SAT,取材於 OpenSuse 的 minisat / libzypper http://www.slideshare.net/naderman/composer-9206307Monday, January 14, 13
  80. 80. Composer https://github.com/composer/composer • composer.json 取材於 Node.js NPM • 更好的相依性解決⽅方案 SAT,取材於 OpenSuse 的 minisat / libzypper • Satis package repository 可架設套件庫 http://www.slideshare.net/naderman/composer-9206307Monday, January 14, 13
  81. 81. Composer https://github.com/composer/composer • composer.json 取材於 Node.js NPM • 更好的相依性解決⽅方案 SAT,取材於 OpenSuse 的 minisat / libzypper • Satis package repository 可架設套件庫 • composer.lock 可鎖定套件相依資料 http://www.slideshare.net/naderman/composer-9206307Monday, January 14, 13
  82. 82. Composer https://github.com/composer/composer • composer.json 取材於 Node.js NPM • 更好的相依性解決⽅方案 SAT,取材於 OpenSuse 的 minisat / libzypper • Satis package repository 可架設套件庫 • composer.lock 可鎖定套件相依資料 • ⼯工具逐漸成熟,越來越多⼈人使⽤用 http://www.slideshare.net/naderman/composer-9206307Monday, January 14, 13
  83. 83. Onion http://github.com/c9s/OnionMonday, January 14, 13
  84. 84. Onion http://github.com/c9s/Onion • PEAR 向後相容⼯工具Monday, January 14, 13
  85. 85. Onion http://github.com/c9s/Onion • PEAR 向後相容⼯工具 • 提供簡易的套件定義 package.iniMonday, January 14, 13
  86. 86. Onion http://github.com/c9s/Onion • PEAR 向後相容⼯工具 • 提供簡易的套件定義 package.ini • 可快速打包成 PEAR 套件Monday, January 14, 13
  87. 87. Onion http://github.com/c9s/Onion • PEAR 向後相容⼯工具 • 提供簡易的套件定義 package.ini • 可快速打包成 PEAR 套件 • 可 Bundle 安裝 PEAR 套件 (like Ruby Bundler)Monday, January 14, 13
  88. 88. PHP 版本環境⼯工具Monday, January 14, 13
  89. 89. phpbrew http://github.com/c9s/phpbrewMonday, January 14, 13
  90. 90. phpbrew http://github.com/c9s/phpbrew • 取材⾃自 @gugod perlbrewMonday, January 14, 13
  91. 91. phpbrew http://github.com/c9s/phpbrew • 取材⾃自 @gugod perlbrew • 易於切換 PHP 相關版本Monday, January 14, 13
  92. 92. phpbrew http://github.com/c9s/phpbrew • 取材⾃自 @gugod perlbrew • 易於切換 PHP 相關版本 • 提供 variant 建置選項 +mysql, +pgsql...etcMonday, January 14, 13
  93. 93. phpbrew http://github.com/c9s/phpbrew • 取材⾃自 @gugod perlbrew • 易於切換 PHP 相關版本 • 提供 variant 建置選項 +mysql, +pgsql...etc • 不需 root 權限Monday, January 14, 13
  94. 94. phpbrew http://github.com/c9s/phpbrew • 取材⾃自 @gugod perlbrew • 易於切換 PHP 相關版本 • 提供 variant 建置選項 +mysql, +pgsql...etc • 不需 root 權限 • 平台⽀支援: Mac OS X 10.5+, Ubuntu, Debian..Monday, January 14, 13
  95. 95. PHP library/app from corneltekMonday, January 14, 13
  96. 96. PHP Projects • phpbrew • PEARX • CLIFramework • Universal • Onion • FormKit • Roller Router • ValidationKit • LazyRecord • ClassMap • ActionKit • GetOptionKit 族繁不及備載...Monday, January 14, 13
  97. 97. 為什麼要重造輪⼦子?Monday, January 14, 13
  98. 98. 設計軟體 != 設計輪⼦子Monday, January 14, 13
  99. 99. It’s not that simple 並⾮非像輪⼦子那樣的簡單Monday, January 14, 13
  100. 100. 軟體有相依性 但輪⼦子沒有Monday, January 14, 13
  101. 101. ⼀一旦應⽤用程式相依了他⼈人的框架 你的開發模式也將受到侷限Monday, January 14, 13
  102. 102. 開發⼯工具與⼈人息息相關 但輪⼦子只需透過輪軸傳動Monday, January 14, 13
  103. 103. 使⽤用他⼈人的 FullStack 框架Monday, January 14, 13
  104. 104. 嘗到的是短期的甜頭Monday, January 14, 13
  105. 105. 犧牲的是未來的無限可能Monday, January 14, 13
  106. 106. 什麼是 FullStack Framework ?Monday, January 14, 13
  107. 107. 就是⼀一整包送給你Monday, January 14, 13
  108. 108. FullStack Framework • Rails • Zend Framework • Symfony • WordPress • Joomla • etc...Monday, January 14, 13
  109. 109. 使⽤用⼀一個架構快速⼤大幅修改的框架 FW 1.0Monday, January 14, 13
  110. 110. 使⽤用⼀一個架構快速⼤大幅修改的框架 FW 1.0 App A 這個 FW 好像不錯 來⽤用⽤用看Monday, January 14, 13
  111. 111. 使⽤用⼀一個架構快速⼤大幅修改的框架 FW 1.0 FW 2.0 App AMonday, January 14, 13
  112. 112. 使⽤用⼀一個架構快速⼤大幅修改的框架 FW 1.0 FW 2.0 App A App B 改太多 2.0 有個功能 X 實在 沒時間升級啦 太棒了,趕快來⽤用 不管了Monday, January 14, 13
  113. 113. 使⽤用⼀一個架構快速⼤大幅修改的框架 FW 1.0 FW 2.0 FW 3.0 App A App BMonday, January 14, 13
  114. 114. 使⽤用⼀一個架構快速⼤大幅修改的框架 FW 1.0 FW 2.0 FW 3.0 App A App B Migration is hard! 相依於 FW2.0 的 X 功能 但 FW3.0 卻拿掉了 XMonday, January 14, 13
  115. 115. 使⽤用⼀一個架構快速⼤大幅修改的框架 FW 1.0 FW 2.0 FW 3.0 App A App B App C 無形之中增加的維護成本 怕跟不上潮流,於是 新網站⼜又使⽤用 FW 3.0Monday, January 14, 13
  116. 116. 使⽤用⼀一個架構快速⼤大幅修改的框架 security FW 1.0 FW 2.0 FW 3.0 bug fix fix security App A App B App C bug fix fix 新的修正只適⽤用新的版本 但由於架構⼤大幅修改,同樣的 patch 無法直 接套⽤用於 FW 2.0 的 App B,只能⼿手動修改Monday, January 14, 13
  117. 117. 使⽤用 FullStack 框架之侷限Monday, January 14, 13
  118. 118. 使⽤用 FullStack 框架之侷限 • 隨著框架不斷修改內建⾏行為, 升級 的過程,就會有越多不確定因素 (bug, security)Monday, January 14, 13
  119. 119. 使⽤用 FullStack 框架之侷限 • 隨著框架不斷修改內建⾏行為, 升級 的過程,就會有越多不確定因素 (bug, security) • 網站規模越⼤大,升級越苦。Monday, January 14, 13
  120. 120. 使⽤用 FullStack 框架之侷限 • 隨著框架不斷修改內建⾏行為, 升級 的過程,就會有越多不確定因素 (bug, security) • 網站規模越⼤大,升級越苦。 • 功能開發及系統效能會因為框架⽽而 有所限制。Monday, January 14, 13
  121. 121. Allen Own 不安定因素Monday, January 14, 13
  122. 122. Allen Own 不安定因素Monday, January 14, 13
  123. 123. So how do we do that?Monday, January 14, 13
  124. 124. Divide and ConquerMonday, January 14, 13
  125. 125. Framework should just be “framework”Monday, January 14, 13
  126. 126. Components should be easy to adapt/swapMonday, January 14, 13
  127. 127. Each component should have a package state - API stability -Package stabilityMonday, January 14, 13
  128. 128. Component A The core is pretty small, we don’t need to change Framework Component B core API frequently Component CMonday, January 14, 13
  129. 129. Component A 2.0 API Lock Stable Framework Component B API Lock Stable API Lock Beta Stability Component C API Beta Beta StabilityMonday, January 14, 13
  130. 130. We can build another new framework very easily. Component A 2.0 API Lock Stable Framework B New Concept Framework Component B API Lock Stable API Lock Beta Stability Component C API Beta Beta StabilityMonday, January 14, 13
  131. 131. How do we build CLI applications?Monday, January 14, 13
  132. 132. CLIFramework https://github.com/c9s/CLIFrameworkMonday, January 14, 13
  133. 133. CLIFramework • 提供最快最簡易的⽅方式建置⼀一個命令列 的⼯工具 • phpbrew, onion, classmap ... etcMonday, January 14, 13
  134. 134. CLIFramework ⽀支持⼦子命令及⼦子命令選項Monday, January 14, 13
  135. 135. CLIFramework <?php namespace TestAppCommand; use CLIFrameworkCommand; class ListCommand extends Command { function execute($arg1,$arg2) { // .. do something here... } }Monday, January 14, 13
  136. 136. CLIFramework <?php namespace YourApp; use CLIFrameworkApplication; class CLIApplication extends Application { /* init your application options here */ function options($opts) { $opts->add(v|verbose, verbose message); $opts->add(path:, required option with a value.); $opts->add(path?, optional option with a value); $opts->add(path+, multiple value option.); } /* register your command here */ function init() { $this->registerCommand( list, YourAppCommandListCommand ); $this->registerCommand( foo, YourAppCommandFooCommand ); } }Monday, January 14, 13
  137. 137. CLIFramework <?php $app = new TestAppApplication; $app->run($argv);Monday, January 14, 13
  138. 138. CLIFramework ⾃自動產⽣生的 Command-line helpMonday, January 14, 13
  139. 139. How do we generate forms?Monday, January 14, 13
  140. 140. FormKit https://github.com/c9s/FormKitMonday, January 14, 13
  141. 141. FormKit • A powerful form widget generator. • Simple API for defining widgets and layout. • Customizable layout engine.Monday, January 14, 13
  142. 142. FormKit: TextInput <?php $text = new FormKitWidgetTextInput(username, array( label => Username, placeholder => Your name please, hint => Please enter 6 characters for your username, )); $text->value( default ) ->size(20); echo $text; // renderMonday, January 14, 13
  143. 143. FormKit <?php $countries = new FormKitWidgetSelectInput( country , array( label => Country, options => array( Test => Test, Asia => array( Taiwan, Taipei, Tainan, Tokyo, Korea, ) ) ));Monday, January 14, 13
  144. 144. FormKit: GenericLayout <?php $layout = new FormKitLayoutGenericLayout; $layout->width(400); $layout->addWidget( $text ) ->addWidget( $password ) ->addWidget( $remember ) ->addWidget( $birthday ) ->addWidget( $best_time ) ->addWidget( $role ) ->addWidget( $size ) ->addWidget( $countries ) ->cellpadding(6) ->cellspacing(6) ->border(0); echo $layout;Monday, January 14, 13
  145. 145. FormKit: Helpers <?php use FormKitFormKit; $username = FormKit::text(username); $password = FormKit::password(password,array( class => your-element-class-name, id => your-element-id, value => default password, )); echo $username->render(); echo $password->render();Monday, January 14, 13
  146. 146. Available Widgets • TextareaInput • Label • TextInput • PasswordInput • ButtonInput • RadioInput • CheckboxInput • ResetInput • ColorInput • SelectInput • DateInput • SubmitInput • DatetimeInput • AjaxCompleteInput • FileInput • CanvasInput • HiddenInputMonday, January 14, 13
  147. 147. For more details http://github.com/c9s/FormKitMonday, January 14, 13
  148. 148. How do we define logics for forms?Monday, January 14, 13
  149. 149. ActionKit https://github.com/c9s/ActionKitMonday, January 14, 13
  150. 150. ActionKit • Let you define logics and form field definitions. • Use FormKit to render form fields automatically.Monday, January 14, 13
  151. 151. If I have a login form and login logicsMonday, January 14, 13
  152. 152. <?php namespace UserAction; use ActionKit; class Login extends ActionKitAction { public function scheme() { $this->param("account") ->renderAs("TextInput"); $this->param("password") Define your form fields. ->renderAs("PasswordInput"); $this->param("remember_me"); } }Monday, January 14, 13
  153. 153. <?php namespace UserAction; use ActionKit; class Login extends ActionKitAction { public function scheme() { $this->param("account") ->renderAs("TextInput"); $this->param("password") ->renderAs("PasswordInput"); $this->param("remember_me"); } public function run() { $account = $this->arg(account); $password = $this->arg(password); Define your logics here. /* your login logics here */ return $this->success(Login successfully); } }Monday, January 14, 13
  154. 154. ActionKit: The API <?php $action = new UserActionLogin; echo $action->createView()->render(); // customized action layout. echo $action->createView("CustomziedLayoutClass")->render(); Render the form.Monday, January 14, 13
  155. 155. ActionKit: The API <?php $runner = ActionKitActionRunner::getInstance(); $runner->registerAutoloader(); $result = $runner->run("UserActionLogin"); if( $result && $runner->isAjax() ) { // JSON header(Content-Type: application/json; Charset=utf-8); echo $result->__toString(); exit(0); } Handle the logics and return the result.Monday, January 14, 13
  156. 156. How do we dispatch URL?Monday, January 14, 13
  157. 157. Roller Router https://github.com/c9s/RollerMonday, January 14, 13
  158. 158. Roller Router • A fast router for PHP.Monday, January 14, 13
  159. 159. Roller Router • A fast router for PHP. • Designed for performance.Monday, January 14, 13
  160. 160. Roller Router • A fast router for PHP. • Designed for performance. • Let you define plugins, routes easily.Monday, January 14, 13
  161. 161. Roller Router • A fast router for PHP. • Designed for performance. • Let you define plugins, routes easily. • APC / File Cache.Monday, January 14, 13
  162. 162. Roller Router • A fast router for PHP. • Designed for performance. • Let you define plugins, routes easily. • APC / File Cache. • Annotation Reader support.Monday, January 14, 13
  163. 163. Roller Router • A fast router for PHP. • Designed for performance. • Let you define plugins, routes easily. • APC / File Cache. • Annotation Reader support. • RESTful pluginMonday, January 14, 13
  164. 164. Roller Router • A fast router for PHP. • Designed for performance. • Let you define plugins, routes easily. • APC / File Cache. • Annotation Reader support. • RESTful plugin • With C Extension support.Monday, January 14, 13
  165. 165. Roller Router <?php $router = new RollerRouter( null, array( cache_id => router_demo ));Monday, January 14, 13
  166. 166. Roller Router <?php $router = new RollerRouter( null, array( cache_id => router_demo )); $router->add( /:id/:name , function($id,$name) { return sprintf(Hello %s, %d, $name, $id); });Monday, January 14, 13
  167. 167. Roller Router <?php $router = new RollerRouter( null, array( cache_id => router_demo )); $router->add( /:id/:name , function($id,$name) { return sprintf(Hello %s, %d, $name, $id); }); $r = $router->dispatch( $_SERVER[PATH_INFO] ); if( $r !== false ) echo $r(); else die(page not found.);Monday, January 14, 13
  168. 168. Roller: Add routes <?php $router->add( /posts/:id, array(PostController,readPostAction) );Monday, January 14, 13
  169. 169. Roller with DSL <?php require bootstrap.php; require Roller/DSL.php; on(/path,function() { return your content; }); on(/path/to/:year, [ :year => d+ ] ,function() { return your content; }); dispatch( $_SERVER[PATH_INFO] );Monday, January 14, 13
  170. 170. One more thing!Monday, January 14, 13
  171. 171. If you’re using PHP5.4+Monday, January 14, 13
  172. 172. You can even use the built-in HTTP server.Monday, January 14, 13
  173. 173. Roller Router <?php if (php_sapi_name() == cli-server) { $uri = $_SERVER[REQUEST_URI]; $info = parse_url($uri); if (preg_match(/.(?:png|jpg|jpeg|gif|js|css)$/, $info[path] )) return false; // serve the requested resource as-is. $path = ltrim($info[path],/); if( file_exists($path) ) return false; $pathinfo = $info[path]; } else { $pathinfo = isset($_SERVER[PATH_INFO]) ? $_SERVER[PATH_INFO] : /; } ... $router hereMonday, January 14, 13
  174. 174. $ php -S localhost:8888 router.phpMonday, January 14, 13
  175. 175. How about RESTful?Monday, January 14, 13
  176. 176. <?php Roller + RESTful class MyGenericHandler extends RollerPluginRESTfulGenericHandler { public function create($resource) { return array( id => 99 ); } public function load($resource,$id) { return array( id => $id ); } public function update($resource,$id) { $put = $this->parseInput(); return $put; } public function delete($resource,$id) { $args = $this->parseInput(); // print_r($args); return array( id => $id ); } public function find($resource) { return range(1,10); } }Monday, January 14, 13
  177. 177. Mount your RESTful handler $restful = new RollerPluginRESTful(array( prefix => /= )); $restful->setGenericHandler( MyGenericHandler ); $router->addPlugin($restful); GET http://localhost:8888/=/book/1 POST http://localhost:8888/=/bookMonday, January 14, 13
  178. 178. For more details http://github.com/c9s/RollerMonday, January 14, 13
  179. 179. LazyRecord https://github.com/c9s/RollerMonday, January 14, 13
  180. 180. A Fast PHP ORMMonday, January 14, 13
  181. 181. Why another PHP ORM ?Monday, January 14, 13
  182. 182. PHP ORMs • DoctrineMonday, January 14, 13
  183. 183. PHP ORMs • Doctrine • PropelMonday, January 14, 13
  184. 184. PHP ORMs • Doctrine • Propel • Idiorm / ParisMonday, January 14, 13
  185. 185. Propel / Doctrine • Propel uses XML Schema file.Monday, January 14, 13
  186. 186. Propel / Doctrine • Propel uses XML Schema file. • Doctrine uses XML/YAML/Annotations.Monday, January 14, 13
  187. 187. Propel / Doctrine • Propel uses XML Schema file. • Doctrine uses XML/YAML/Annotations. • Slow & Fat.Monday, January 14, 13
  188. 188. Propel / Doctrine • Propel uses XML Schema file. • Doctrine uses XML/YAML/Annotations. • Slow & Fat. • Doctrine is too complicated.Monday, January 14, 13
  189. 189. Common characteristicMonday, January 14, 13
  190. 190. • XML for configuration file. • XML for schema file. • XML for everything. • Concepts are from Java, too complicated.Monday, January 14, 13
  191. 191. Propel XML runtime.confMonday, January 14, 13
  192. 192. <?xml version="1.0"?> <config> <log> <ident>propel-bookstore</ident> <type>console</type> <level>7</level> </log> <propel> <datasources default="bookstore"> <datasource id="bookstore"> <adapter>sqlite</adapter> <connection> <classname>DebugPDO</classname> <dsn>mysql:host=localhost;dbname=bookstore</dsn> <user>testuser</user> <password>password</password> <options> <option id="ATTR_PERSISTENT">false</option> </options> <attributes> <option id="ATTR_EMULATE_PREPARES">true</option> </attributes> <settings> <setting id="charset">utf8</setting> <setting id="queries"> <query>set search_path myschema, public</query><!-- automatically set postgresqls search_path --> <query>INSERT INTO BAR (hey, there)</query><!-- execute some other query --> </setting> </settings> </connection> <slaves> <connection> <dsn>mysql:host=slave-server1; dbname=bookstore</dsn> </connection> <connection> <dsn>mysql:host=slave-server2; dbname=bookstore</dsn> </connection> </slaves> </datasource> </datasources> <debugpdo> <logging> <details> <method> <enabled>true</enabled> </method> <time> <enabled>true</enabled> <precision>3</precision> </time> <mem> <enabled>true</enabled> <precision>1</precision>Monday, January 14, 13 </mem>
  193. 193. <datasource id="bookstore"> <adapter>sqlite</adapter> <connection> <classname>DebugPDO</classname> <dsn>mysql:host=localhost;dbname=bookstore</dsn> <user>testuser</user> <password>password</password> <options> <option id="ATTR_PERSISTENT">false</option> </options> <attributes> <option id="ATTR_EMULATE_PREPARES">true</option> </attributes> <settings> <setting id="charset">utf8</setting> <setting id="queries"> <query>set search_path myschema, public</query><!-- automatically set postgresqls search_path --> <query>INSERT INTO BAR (hey, there)</query><!-- execute some other query --> </setting> </settings> </connection> <slaves> <connection> <dsn>mysql:host=slave-server1; dbname=bookstore</dsn> </connection> <connection> <dsn>mysql:host=slave-server2; dbname=bookstore</dsn> </connection> </slaves> </datasource> </datasources> <debugpdo> <logging> <details> <method> <enabled>true</enabled> </method> <time> <enabled>true</enabled> <precision>3</precision> </time> <mem> <enabled>true</enabled> <precision>1</precision> </mem> </details> </logging> </debugpdo> </propel> </config>Monday, January 14, 13
  194. 194. Monday, January 14, 13
  195. 195. So we designed an easier ORMMonday, January 14, 13
  196. 196. LazyRecord • Lazy attributes.Monday, January 14, 13
  197. 197. LazyRecord • Lazy attributes. • Lazy schema loader.Monday, January 14, 13
  198. 198. LazyRecord • Lazy attributes. • Lazy schema loader. • Dynamic schema via PHP codeMonday, January 14, 13
  199. 199. LazyRecord • Lazy attributes. • Lazy schema loader. • Dynamic schema via PHP code • Static schema class generatorMonday, January 14, 13
  200. 200. LazyRecord • Lazy attributes. • Lazy schema loader. • Dynamic schema via PHP code • Static schema class generator • SQL Generator for SQLite, MySQL & PgSQL.Monday, January 14, 13
  201. 201. LazyRecord • Filter / Canonicalizer support.Monday, January 14, 13
  202. 202. LazyRecord • Filter / Canonicalizer support. • CRUD support via ActionKit.Monday, January 14, 13
  203. 203. LazyRecord • Filter / Canonicalizer support. • CRUD support via ActionKit. • Form generation via ActionKit.Monday, January 14, 13
  204. 204. LazyRecord • Filter / Canonicalizer support. • CRUD support via ActionKit. • Form generation via ActionKit. • Migration support.Monday, January 14, 13
  205. 205. LazyRecord: Schema <?php namespace TodosModel; use LazyRecordBaseModel; class Todo extends BaseModel { function schema($schema) { $schema->column(title) ->varchar(128) ->required() ; $schema->column(description) ->text(); $schema->column(created_on) ->timestamp() ->default(function() { return date(c); }); $schema->seeds(TodosSeed); } }Monday, January 14, 13
  206. 206. LazyRecord: Model <?php $author = new Author; $ret = $author->create([ name => "Deflator Test $i", country => Tokyo, confirmed => true, date => new DateTime(2011-01-01 00:00:00), ]); if( $ret->success ) { echo "Created!"; } ActiveRecord PatternMonday, January 14, 13
  207. 207. LazyRecord: Collection <?php $authors = new AuthorCollection; foreach( $authors as $author ) { echo $author->name , "n" } Collection IteratingMonday, January 14, 13
  208. 208. LazyRecord: Collection $authors = new AuthorCollection; $authors->where() ->equal(name,Foo) ->groupBy(name,address); SQL Conditions via SQLBuilderMonday, January 14, 13
  209. 209. LazyRecord: Collection $newAuthors = $authors->filter(function($item) { // do something else })->filter(function($item) { return $item->confirmed; });Monday, January 14, 13
  210. 210. Powerful featuresMonday, January 14, 13
  211. 211. Model Schema -> CRUD Actions -> Form LayoutMonday, January 14, 13
  212. 212. LazyRecord Model SchemaMonday, January 14, 13
  213. 213. LazyRecord Model Schema ⇛ ActionMonday, January 14, 13
  214. 214. LazyRecord Model Schema ⇛ Action ⇛ CRUDMonday, January 14, 13
  215. 215. LazyRecord App::Model::Phone ☚ write onceMonday, January 14, 13
  216. 216. LazyRecord App::Model::Phone App::Model::PhoneCollectionMonday, January 14, 13
  217. 217. LazyRecord App::Model::Phone App::Model::PhoneCollection App::Action::CreatePhoneMonday, January 14, 13
  218. 218. LazyRecord App::Model::Phone App::Model::PhoneCollection App::Action::CreatePhone App::Action::UpdatePhoneMonday, January 14, 13
  219. 219. LazyRecord App::Model::Phone App::Model::PhoneCollection App::Action::CreatePhone App::Action::UpdatePhone App::Action::DeletePhoneMonday, January 14, 13
  220. 220. LazyRecord App::Model::Phone App::Model::PhoneCollection App::Action::CreatePhone App::Action::UpdatePhone App::Action::DeletePhone ... or any other actions predefined.Monday, January 14, 13
  221. 221. LazyRecord App::Model::Phone App::Model::PhoneCollection App::Action::CreatePhone App::Action::UpdatePhone App::Action::DeletePhone ... or any other actions predefined. $phone->asCreateAction()->render();Monday, January 14, 13
  222. 222. MigrationMonday, January 14, 13
  223. 223. 2013 年 還在⾃自⼰己⼿手動下 SQL 做 migration 嗎?Monday, January 14, 13
  224. 224. Monday, January 14, 13
  225. 225. Schema UpgradeMonday, January 14, 13
  226. 226. Monday, January 14, 13
  227. 227. For more details http://github.com/c9s/LazyRecord http://www.slideshare.net/c9s/lazyrecord-the-fast-orm-for-phpMonday, January 14, 13
  228. 228. Thank you Find me: Twitter: @c9sMonday, January 14, 13
  1. A particular slide catching your eye?

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

×