SlideShare a Scribd company logo
1 of 228
Download to read offline
Secret sauce of building
                    PHP applications
                         林佑安 (Yo-An Lin)
                           aka c9s




Monday, January 14, 13
About


                         •   GitHub, Twitter, Plurk: @c9s

                         •   220+ GitHub repository in Perl,
                             VimL, PHP, JavaScript and Go.




Monday, January 14, 13
為什麼是
                          PHP?
Monday, January 14, 13
Hey! PHP Sucks



Monday, January 14, 13
PHP Sucks!



Monday, January 14, 13
2000 年開始使⽤用 PHP websites ⼤大幅成⻑⾧長


Monday, January 14, 13
Monday, January 14, 13
⾼高流量 PHP 網站
                          High traffic PHP
                             websites

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
http://highscalability.com/flickr-architecture

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
Monday, January 14, 13
Applications developed
                      with Symfony.
                         http://trac.symfony-project.org/wiki/
                         ApplicationsDevelopedWithSymfony

                                1000+ websites listed.


Monday, January 14, 13
Yii powered
                              applications
                         http://www.yiiframework.com/forum/
                           index.php/forum/14-yii-powered-
                                     applications/



Monday, January 14, 13
⼤大家都跑
                           PHP
Monday, January 14, 13
為什麼?

Monday, January 14, 13
劣即是夯
                            唐鳳 - OSDC 2012


Monday, January 14, 13
有多夯?

Monday, January 14, 13
去街上問

Monday, January 14, 13
⼗十個有九個
                         都會寫 PHP


Monday, January 14, 13
你Grandma都會寫 PHP

                         我也寫 PHP




Monday, January 14, 13
但是
Monday, January 14, 13
你還在使⽤用⽯石器時代
                       的 PHP 嗎?


Monday, January 14, 13
⽯石器時代 PHP ?




Monday, January 14, 13
⽯石器時代義⼤大利麵




Monday, January 14, 13
⽯石器時代 PHP




Monday, January 14, 13
⽯石器時代 PHP
                    • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂)




Monday, January 14, 13
⽯石器時代 PHP
                    • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂)
                    • Copy & Paste (品質低落)




Monday, January 14, 13
⽯石器時代 PHP
                    • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂)
                    • Copy & Paste (品質低落)
                    • .inc 附檔名 (安全漏洞)




Monday, January 14, 13
⽯石器時代 PHP
                    • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂)
                    • Copy & Paste (品質低落)
                    • .inc 附檔名 (安全漏洞)
                    • ⼤大量的 require 呼叫循環 (效能問題)



Monday, January 14, 13
⽯石器時代 PHP
                    • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂)
                    • Copy & Paste (品質低落)
                    • .inc 附檔名 (安全漏洞)
                    • ⼤大量的 require 呼叫循環 (效能問題)
                    • HTML Render 不做 Escape (XSS 漏洞)

Monday, January 14, 13
⽯石器時代 PHP
                    • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂)
                    • Copy & Paste (品質低落)
                    • .inc 附檔名 (安全漏洞)
                    • ⼤大量的 require 呼叫循環 (效能問題)
                    • HTML Render 不做 Escape (XSS 漏洞)
                    • POST/GET 從不過濾 (SQL Injection)
Monday, January 14, 13
為什麼?

Monday, January 14, 13
24⼩小時學會 PHP




Monday, January 14, 13
24⼩小時學會 PHP
                    • 語⾔言學習⼊入⾨門⾨門檻低




Monday, January 14, 13
24⼩小時學會 PHP
                    • 語⾔言學習⼊入⾨門⾨門檻低
                    • 隨便寫,丟給 Apache 就可以執⾏行了




Monday, January 14, 13
24⼩小時學會 PHP
                    • 語⾔言學習⼊入⾨門⾨門檻低
                    • 隨便寫,丟給 Apache 就可以執⾏行了
                    • $_POST, $_GET 是什麼⻤⿁鬼 (管他,可以跑
                         就好了)




Monday, January 14, 13
24⼩小時學會 PHP
                    • 語⾔言學習⼊入⾨門⾨門檻低
                    • 隨便寫,丟給 Apache 就可以執⾏行了
                    • $_POST, $_GET 是什麼⻤⿁鬼 (管他,可以跑
                         就好了)

                    • 義⼤大利麵好煮⼜又好吃,維護是什麼?沒
                         聽過!



Monday, January 14, 13
寫這樣的 PHP
            您⼼心安嗎?
Monday, January 14, 13
現代 PHP 解決⽅方案
                    The Modern PHP Solution



Monday, January 14, 13
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
PHP spl_autoload_*



Monday, January 14, 13
Zend Engine
                         Compilation


Monday, January 14, 13
Request


                             File a.php



                             Scanning
              Zend Engine     Lexing
              Compilation   AST Parsing
                            Compilation



                             Execution


                              Output




Monday, January 14, 13
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


                                                          Output




Monday, January 14, 13
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


                                                          Output




Monday, January 14, 13
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


                                                           Output




Monday, January 14, 13
那 APC 呢?



Monday, January 14, 13
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


                                                             Output




Monday, January 14, 13
Monday, January 14, 13
這就是
                                       WordPress
                                       慢的原因


                         http://talks.php.net/presentations/slides/intro/wp_inclued1.png


Monday, January 14, 13
PHP spl_autoload_*
                    • PHP 5.3+ 的新功能。




Monday, January 14, 13
PHP spl_autoload_*
                    • PHP 5.3+ 的新功能。
                    • 可註冊⾃自訂的類別載⼊入策略 (autoloading
                         strategy)




Monday, January 14, 13
PHP spl_autoload_*
                    • PHP 5.3+ 的新功能。
                    • 可註冊⾃自訂的類別載⼊入策略 (autoloading
                         strategy)
                    • 對於找不到定義的類別,⾃自動呼叫 class
                         loader 進⾏行類別的⾃自動載⼊入。




Monday, January 14, 13
PHP spl_autoload_*
                    • PHP 5.3+ 的新功能。
                    • 可註冊⾃自訂的類別載⼊入策略 (autoloading
                         strategy)
                    • 對於找不到定義的類別,⾃自動呼叫 class
                         loader 進⾏行類別的⾃自動載⼊入。

                    • 每個 request 只會載⼊入⾃自⼰己需要的 class,
                         ⽤用越少,載越少。


Monday, January 14, 13
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 dependencies




Monday, January 14, 13
Package dependencies




Monday, January 14, 13
Package dependencies




Monday, January 14, 13
Composer
                                  https://github.com/composer/composer




                         http://www.slideshare.net/naderman/composer-9206307


Monday, January 14, 13
Composer
                                  https://github.com/composer/composer



                    • composer.json 取材於 Node.js NPM




                         http://www.slideshare.net/naderman/composer-9206307


Monday, January 14, 13
Composer
                                     https://github.com/composer/composer



                    • composer.json 取材於 Node.js NPM
                    • 更好的相依性解決⽅方案 SAT,取材於
                         OpenSuse 的 minisat / libzypper




                            http://www.slideshare.net/naderman/composer-9206307


Monday, January 14, 13
Composer
                                     https://github.com/composer/composer



                    • composer.json 取材於 Node.js NPM
                    • 更好的相依性解決⽅方案 SAT,取材於
                         OpenSuse 的 minisat / libzypper

                    • Satis package repository 可架設套件庫

                            http://www.slideshare.net/naderman/composer-9206307


Monday, January 14, 13
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-9206307


Monday, January 14, 13
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-9206307


Monday, January 14, 13
Onion
                         http://github.com/c9s/Onion




Monday, January 14, 13
Onion
                            http://github.com/c9s/Onion




                    • PEAR 向後相容⼯工具




Monday, January 14, 13
Onion
                             http://github.com/c9s/Onion




                    • PEAR 向後相容⼯工具
                    • 提供簡易的套件定義 package.ini




Monday, January 14, 13
Onion
                             http://github.com/c9s/Onion




                    • PEAR 向後相容⼯工具
                    • 提供簡易的套件定義 package.ini
                    • 可快速打包成 PEAR 套件



Monday, January 14, 13
Onion
                                    http://github.com/c9s/Onion




                    • PEAR 向後相容⼯工具
                    • 提供簡易的套件定義 package.ini
                    • 可快速打包成 PEAR 套件
                    • 可 Bundle 安裝 PEAR 套件 (like Ruby
                         Bundler)



Monday, January 14, 13
PHP 版本環境⼯工具


Monday, January 14, 13
phpbrew
                         http://github.com/c9s/phpbrew




Monday, January 14, 13
phpbrew
                              http://github.com/c9s/phpbrew



                    • 取材⾃自 @gugod perlbrew




Monday, January 14, 13
phpbrew
                              http://github.com/c9s/phpbrew



                    • 取材⾃自 @gugod perlbrew
                    • 易於切換 PHP 相關版本




Monday, January 14, 13
phpbrew
                                http://github.com/c9s/phpbrew



                    • 取材⾃自 @gugod perlbrew
                    • 易於切換 PHP 相關版本
                    • 提供 variant 建置選項 +mysql, +pgsql...etc



Monday, January 14, 13
phpbrew
                                http://github.com/c9s/phpbrew



                    • 取材⾃自 @gugod perlbrew
                    • 易於切換 PHP 相關版本
                    • 提供 variant 建置選項 +mysql, +pgsql...etc
                    • 不需 root 權限


Monday, January 14, 13
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
PHP library/app from
                              corneltek


Monday, January 14, 13
PHP Projects
                    •    phpbrew          •   PEARX

                    •    CLIFramework     •   Universal

                    •    Onion            •   FormKit

                    •    Roller Router    •   ValidationKit

                    •    LazyRecord       •   ClassMap

                    •    ActionKit        •   GetOptionKit

                                              族繁不及備載...



Monday, January 14, 13
為什麼要重造輪⼦子?



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
                    • WordPress
                    • Joomla
                    • etc...
Monday, January 14, 13
使⽤用⼀一個架構快速⼤大幅修改的框架


                         FW 1.0




Monday, January 14, 13
使⽤用⼀一個架構快速⼤大幅修改的框架


                         FW 1.0




                         App A




                           這個 FW 好像不錯
                             來⽤用⽤用看



Monday, January 14, 13
使⽤用⼀一個架構快速⼤大幅修改的框架


                         FW 1.0   FW 2.0




                         App A




Monday, January 14, 13
使⽤用⼀一個架構快速⼤大幅修改的框架


                         FW 1.0   FW 2.0




                         App A    App B




                 改太多              2.0 有個功能 X 實在
               沒時間升級啦              太棒了,趕快來⽤用
                 不管了


Monday, January 14, 13
使⽤用⼀一個架構快速⼤大幅修改的框架


                         FW 1.0   FW 2.0   FW 3.0




                         App A    App B




Monday, January 14, 13
使⽤用⼀一個架構快速⼤大幅修改的框架


                         FW 1.0   FW 2.0     FW 3.0




                         App A    App B



                                                      Migration is hard!
                                  相依於 FW2.0 的 X 功能
                                   但 FW3.0 卻拿掉了 X



Monday, January 14, 13
使⽤用⼀一個架構快速⼤大幅修改的框架


                         FW 1.0   FW 2.0      FW 3.0




                         App A    App B       App C



                                                無形之中增加的維護成本
                                  怕跟不上潮流,於是
                                  新網站⼜又使⽤用 FW 3.0



Monday, January 14, 13
使⽤用⼀一個架構快速⼤大幅修改的框架

                                                             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
使⽤用 FullStack 框架之侷限




Monday, January 14, 13
使⽤用 FullStack 框架之侷限
                    • 隨著框架不斷修改內建⾏行為, 升級
                         的過程,就會有越多不確定因素
                         (bug, security)




Monday, January 14, 13
使⽤用 FullStack 框架之侷限
                    • 隨著框架不斷修改內建⾏行為, 升級
                         的過程,就會有越多不確定因素
                         (bug, security)
                    • 網站規模越⼤大,升級越苦。


Monday, January 14, 13
使⽤用 FullStack 框架之侷限
                    • 隨著框架不斷修改內建⾏行為, 升級
                         的過程,就會有越多不確定因素
                         (bug, security)
                    • 網站規模越⼤大,升級越苦。
                    • 功能開發及系統效能會因為框架⽽而
                         有所限制。


Monday, January 14, 13
Allen Own 不安定因素
Monday, January 14, 13
Allen Own 不安定因素
Monday, January 14, 13
So how do we do that?



Monday, January 14, 13
Divide and Conquer




Monday, January 14, 13
Framework should just
                      be “framework”


Monday, January 14, 13
Components should be
                  easy to adapt/swap


Monday, January 14, 13
Each component should
                  have a package state
                     - API stability
                   -Package stability

Monday, January 14, 13
Component A




          The core is pretty small,
          we don’t need to change     Framework         Component B


            core API frequently

                                                   Component C




Monday, January 14, 13
Component A 2.0

                                                            API Lock
                                                             Stable




                                    Framework          Component B
                         API Lock
                          Stable
                                                                        API Lock
                                                                       Beta Stability




                                                  Component C

                                                                  API Beta
                                                                Beta Stability




Monday, January 14, 13
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 Stability




Monday, January 14, 13
How do we build CLI
                            applications?


Monday, January 14, 13
CLIFramework
                          https://github.com/c9s/CLIFramework




Monday, January 14, 13
CLIFramework


                    • 提供最快最簡易的⽅方式建置⼀一個命令列
                         的⼯工具

                    • phpbrew, onion, classmap ... etc


Monday, January 14, 13
CLIFramework




                               ⽀支持⼦子命令及⼦子命令選項


Monday, January 14, 13
CLIFramework
                         <?php
                         namespace TestAppCommand;
                         use CLIFrameworkCommand;
                         class ListCommand extends Command
                         {
                             function execute($arg1,$arg2)
                             {
                                 // .. do something here...
                             }
                         }



Monday, January 14, 13
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
CLIFramework

                         <?php

                         $app = new TestAppApplication;
                         $app->run($argv);




Monday, January 14, 13
CLIFramework




                         ⾃自動產⽣生的 Command-line help
Monday, January 14, 13
How do we generate
                              forms?


Monday, January 14, 13
FormKit
                         https://github.com/c9s/FormKit




Monday, January 14, 13
FormKit

                    • A powerful form widget generator.
                    • Simple API for defining widgets and layout.
                    • Customizable layout engine.


Monday, January 14, 13
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; // render




Monday, January 14, 13
FormKit
         <?php
         $countries = new FormKitWidgetSelectInput( 'country' , array(
             'label' => 'Country',
             'options' => array(
                 'Test' => 'Test',
                 'Asia' => array(
                     'Taiwan',
                     'Taipei',
                     'Tainan',
                     'Tokyo',
                     'Korea',
                 )
             )
         ));




Monday, January 14, 13
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
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
Available Widgets
                    •    TextareaInput
                                         •   Label
                    •    TextInput
                                         •   PasswordInput
                    •    ButtonInput
                                         •   RadioInput
                    •    CheckboxInput
                                         •   ResetInput
                    •    ColorInput
                                         •   SelectInput
                    •    DateInput
                                         •   SubmitInput
                    •    DatetimeInput
                                         •   AjaxCompleteInput
                    •    FileInput
                                         •   CanvasInput
                    •    HiddenInput




Monday, January 14, 13
For more details
                          http://github.com/c9s/FormKit




Monday, January 14, 13
How do we define
                          logics for forms?


Monday, January 14, 13
ActionKit
                         https://github.com/c9s/ActionKit




Monday, January 14, 13
ActionKit

                    • Let you define logics and form field
                         definitions.
                    • Use FormKit to render form fields
                         automatically.




Monday, January 14, 13
If I have a login form
                             and login logics


Monday, January 14, 13
<?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
<?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
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
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
How do we dispatch
                               URL?


Monday, January 14, 13
Roller Router
                           https://github.com/c9s/Roller




Monday, 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, 13
Roller Router
                    • A fast router for PHP.
                    • Designed for performance.
                    • Let you define plugins, routes easily.




Monday, January 14, 13
Roller Router
                    • A fast router for PHP.
                    • Designed for performance.
                    • Let you define plugins, routes easily.
                    • APC / File Cache.



Monday, January 14, 13
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
Roller Router
                    • A fast router for PHP.
                    • Designed for performance.
                    • Let you define plugins, routes easily.
                    • APC / File Cache.
                    • Annotation Reader support.
                    • RESTful plugin

Monday, January 14, 13
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
Roller Router
              <?php
              $router = new RollerRouter( null, array(
                  'cache_id' => 'router_demo'
              ));




Monday, January 14, 13
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
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
Roller: Add routes

                  <?php
                  $router->add( '/posts/:id',
                        array('PostController','readPostAction') );




Monday, January 14, 13
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
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 = $_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 here




Monday, January 14, 13
$ php -S localhost:8888 router.php




Monday, January 14, 13
How about RESTful?



Monday, January 14, 13
<?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
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/=/book


Monday, January 14, 13
For more details
                           http://github.com/c9s/Roller




Monday, January 14, 13
LazyRecord
                          https://github.com/c9s/Roller




Monday, January 14, 13
A Fast PHP ORM



Monday, January 14, 13
Why another PHP
                             ORM ?


Monday, January 14, 13
PHP ORMs

                    • Doctrine




Monday, January 14, 13
PHP ORMs

                    • Doctrine
                    • Propel



Monday, January 14, 13
PHP ORMs

                    • Doctrine
                    • Propel
                    • Idiorm / Paris


Monday, 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.



Monday, January 14, 13
Propel / Doctrine

                    • Propel uses XML Schema file.
                    • Doctrine uses XML/YAML/Annotations.
                    • Slow & Fat.


Monday, January 14, 13
Propel / Doctrine

                    • Propel uses XML Schema file.
                    • Doctrine uses XML/YAML/Annotations.
                    • Slow & Fat.
                    • Doctrine is too complicated.

Monday, January 14, 13
Common characteristic



Monday, January 14, 13
• XML for configuration file.
                    • XML for schema file.
                    • XML for everything.
                    • Concepts are from Java, too complicated.

Monday, January 14, 13
Propel XML
                         runtime.conf


Monday, January 14, 13
<?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 postgresql's 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>
<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 postgresql's 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
Monday, January 14, 13
So we designed an
                            easier ORM


Monday, 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 schema via PHP code




Monday, January 14, 13
LazyRecord
                    • Lazy attributes.
                    • Lazy schema loader.
                    • Dynamic schema via PHP code
                    • Static schema class generator



Monday, January 14, 13
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
LazyRecord
                    • Filter / Canonicalizer support.




Monday, January 14, 13
LazyRecord
                    • Filter / Canonicalizer support.
                    • CRUD support via ActionKit.




Monday, January 14, 13
LazyRecord
                    • Filter / Canonicalizer support.
                    • CRUD support via ActionKit.
                    • Form generation via ActionKit.




Monday, January 14, 13
LazyRecord
                    • Filter / Canonicalizer support.
                    • CRUD support via ActionKit.
                    • Form generation via ActionKit.
                    • Migration support.



Monday, January 14, 13
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
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 Pattern




Monday, January 14, 13
LazyRecord: Collection

                         <?php
                         $authors = new AuthorCollection;
                         foreach( $authors as $author ) {
                             echo $author->name , "n"
                         }

                                                  Collection Iterating




Monday, January 14, 13
LazyRecord: Collection


                         $authors = new AuthorCollection;
                         $authors->where()
                             ->equal('name','Foo')
                             ->groupBy('name','address');


                                                SQL Conditions via
                                                   SQLBuilder




Monday, January 14, 13
LazyRecord: Collection

               $newAuthors = $authors->filter(function($item) {
                   // do something else
               })->filter(function($item) {
                   return $item->confirmed;
               });




Monday, January 14, 13
Powerful features



Monday, January 14, 13
Model Schema ->
                         CRUD Actions ->
                           Form Layout


Monday, January 14, 13
LazyRecord


                         Model Schema




Monday, January 14, 13
LazyRecord


          Model Schema ⇛ Action




Monday, January 14, 13
LazyRecord


       Model Schema ⇛ Action ⇛


                                 CRUD


Monday, January 14, 13
LazyRecord
                         App::Model::Phone ☚ write once




Monday, January 14, 13
LazyRecord
                              App::Model::Phone
                         App::Model::PhoneCollection




Monday, January 14, 13
LazyRecord
                              App::Model::Phone
                         App::Model::PhoneCollection

                          App::Action::CreatePhone




Monday, January 14, 13
LazyRecord
                              App::Model::Phone
                         App::Model::PhoneCollection

                          App::Action::CreatePhone
                          App::Action::UpdatePhone




Monday, January 14, 13
LazyRecord
                              App::Model::Phone
                         App::Model::PhoneCollection

                          App::Action::CreatePhone
                          App::Action::UpdatePhone
                          App::Action::DeletePhone




Monday, January 14, 13
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
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
Migration



Monday, January 14, 13
2013 年
                    還在⾃自⼰己⼿手動下 SQL
                     做 migration 嗎?


Monday, January 14, 13
Monday, January 14, 13
Schema Upgrade



Monday, January 14, 13
Monday, January 14, 13
For more details
                          http://github.com/c9s/LazyRecord
                         http://www.slideshare.net/c9s/lazyrecord-the-fast-orm-for-php




Monday, January 14, 13
Thank you
                         Find me: Twitter: @c9s




Monday, January 14, 13

More Related Content

Viewers also liked

2013 01 13 webconf milkmidi Flash
2013 01 13 webconf milkmidi Flash2013 01 13 webconf milkmidi Flash
2013 01 13 webconf milkmidi Flash綠茶 奶
 
Gamification vs UX
Gamification vs UXGamification vs UX
Gamification vs UXHana Chang
 
130113 why.&.how.smb.running.ux-light
130113 why.&.how.smb.running.ux-light130113 why.&.how.smb.running.ux-light
130113 why.&.how.smb.running.ux-lightDavid Liu
 
WebConf 2013「Best Practices - The Upload」
WebConf 2013「Best Practices - The Upload」WebConf 2013「Best Practices - The Upload」
WebConf 2013「Best Practices - The Upload」Orange Tsai
 
Designing physical and digital experience in social web
Designing physical and digital experience in social webDesigning physical and digital experience in social web
Designing physical and digital experience in social webJanet Huang
 
20130112用原型驅動設計@webconf
20130112用原型驅動設計@webconf20130112用原型驅動設計@webconf
20130112用原型驅動設計@webconfJustin Lee
 
那些mockup沒告訴你的事@WebConf.tw 2013
那些mockup沒告訴你的事@WebConf.tw 2013那些mockup沒告訴你的事@WebConf.tw 2013
那些mockup沒告訴你的事@WebConf.tw 2013Adam Wang
 
超理性使用者介面設計 - Data-driven A/B Testing
超理性使用者介面設計 - Data-driven A/B Testing超理性使用者介面設計 - Data-driven A/B Testing
超理性使用者介面設計 - Data-driven A/B TestingYing-Hsiang Liao
 
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式Will Huang
 
A brief introduction to SPDY - 邁向 HTTP/2.0
A brief introduction to SPDY - 邁向 HTTP/2.0A brief introduction to SPDY - 邁向 HTTP/2.0
A brief introduction to SPDY - 邁向 HTTP/2.0Wen-Tien Chang
 
使用Javascript及HTML5打造協同運作系統
使用Javascript及HTML5打造協同運作系統使用Javascript及HTML5打造協同運作系統
使用Javascript及HTML5打造協同運作系統Hsu Ping Feng
 
借力使力的乾坤挪移大法-以使用者為中心的設計決策奧妙
借力使力的乾坤挪移大法-以使用者為中心的設計決策奧妙 借力使力的乾坤挪移大法-以使用者為中心的設計決策奧妙
借力使力的乾坤挪移大法-以使用者為中心的設計決策奧妙 悠識學院
 
Webconf2013-非典型貧窮網站維運經驗分享
Webconf2013-非典型貧窮網站維運經驗分享Webconf2013-非典型貧窮網站維運經驗分享
Webconf2013-非典型貧窮網站維運經驗分享Mu-Fan Teng
 

Viewers also liked (14)

2013 01 13 webconf milkmidi Flash
2013 01 13 webconf milkmidi Flash2013 01 13 webconf milkmidi Flash
2013 01 13 webconf milkmidi Flash
 
BDD in .NET
BDD in .NETBDD in .NET
BDD in .NET
 
Gamification vs UX
Gamification vs UXGamification vs UX
Gamification vs UX
 
130113 why.&.how.smb.running.ux-light
130113 why.&.how.smb.running.ux-light130113 why.&.how.smb.running.ux-light
130113 why.&.how.smb.running.ux-light
 
WebConf 2013「Best Practices - The Upload」
WebConf 2013「Best Practices - The Upload」WebConf 2013「Best Practices - The Upload」
WebConf 2013「Best Practices - The Upload」
 
Designing physical and digital experience in social web
Designing physical and digital experience in social webDesigning physical and digital experience in social web
Designing physical and digital experience in social web
 
20130112用原型驅動設計@webconf
20130112用原型驅動設計@webconf20130112用原型驅動設計@webconf
20130112用原型驅動設計@webconf
 
那些mockup沒告訴你的事@WebConf.tw 2013
那些mockup沒告訴你的事@WebConf.tw 2013那些mockup沒告訴你的事@WebConf.tw 2013
那些mockup沒告訴你的事@WebConf.tw 2013
 
超理性使用者介面設計 - Data-driven A/B Testing
超理性使用者介面設計 - Data-driven A/B Testing超理性使用者介面設計 - Data-driven A/B Testing
超理性使用者介面設計 - Data-driven A/B Testing
 
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
 
A brief introduction to SPDY - 邁向 HTTP/2.0
A brief introduction to SPDY - 邁向 HTTP/2.0A brief introduction to SPDY - 邁向 HTTP/2.0
A brief introduction to SPDY - 邁向 HTTP/2.0
 
使用Javascript及HTML5打造協同運作系統
使用Javascript及HTML5打造協同運作系統使用Javascript及HTML5打造協同運作系統
使用Javascript及HTML5打造協同運作系統
 
借力使力的乾坤挪移大法-以使用者為中心的設計決策奧妙
借力使力的乾坤挪移大法-以使用者為中心的設計決策奧妙 借力使力的乾坤挪移大法-以使用者為中心的設計決策奧妙
借力使力的乾坤挪移大法-以使用者為中心的設計決策奧妙
 
Webconf2013-非典型貧窮網站維運經驗分享
Webconf2013-非典型貧窮網站維運經驗分享Webconf2013-非典型貧窮網站維運經驗分享
Webconf2013-非典型貧窮網站維運經驗分享
 

Similar to Secret sauce of building php applications

Php Symfony and software-life-cycle
Php Symfony and software-life-cyclePhp Symfony and software-life-cycle
Php Symfony and software-life-cycleSwatantra Kumar
 
Debugging LAMP Apps on Linux/UNIX Using Open Source Tools - Jess Portnot - OS...
Debugging LAMP Apps on Linux/UNIX Using Open Source Tools - Jess Portnot - OS...Debugging LAMP Apps on Linux/UNIX Using Open Source Tools - Jess Portnot - OS...
Debugging LAMP Apps on Linux/UNIX Using Open Source Tools - Jess Portnot - OS...Zohar Babin
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.jsTroy Miles
 
Dynamic Languages In The Enterprise (4developers march 2009)
Dynamic Languages In The Enterprise (4developers march 2009)Dynamic Languages In The Enterprise (4developers march 2009)
Dynamic Languages In The Enterprise (4developers march 2009)Ivo Jansch
 
How the Web Works
How the Web WorksHow the Web Works
How the Web Workszachwise
 
PHP Doesn't Suck
PHP Doesn't SuckPHP Doesn't Suck
PHP Doesn't SuckJohn Hobbs
 
WordCamp Victoria 2013: Plugin Development 2013
WordCamp Victoria 2013: Plugin Development 2013WordCamp Victoria 2013: Plugin Development 2013
WordCamp Victoria 2013: Plugin Development 2013Joey Kudish
 
Go is your friend - Reppucci
Go is your friend - Reppucci Go is your friend - Reppucci
Go is your friend - Reppucci Codemotion
 
Web Application Testing. A Quick Guide to Testing and Security
Web Application Testing. A Quick Guide to Testing and SecurityWeb Application Testing. A Quick Guide to Testing and Security
Web Application Testing. A Quick Guide to Testing and SecurityThe Software House
 
Introduction to node.js by Ran Mizrahi @ Reversim Summit
Introduction to node.js by Ran Mizrahi @ Reversim SummitIntroduction to node.js by Ran Mizrahi @ Reversim Summit
Introduction to node.js by Ran Mizrahi @ Reversim SummitRan Mizrahi
 
Node.js Patterns and Opinions
Node.js Patterns and OpinionsNode.js Patterns and Opinions
Node.js Patterns and OpinionsIsaacSchlueter
 
YAPC::EU::2009 - How Opera Software uses Perl
YAPC::EU::2009 - How Opera Software uses PerlYAPC::EU::2009 - How Opera Software uses Perl
YAPC::EU::2009 - How Opera Software uses PerlCosimo Streppone
 
Scaling PHP to 40 Million Uniques
Scaling PHP to 40 Million UniquesScaling PHP to 40 Million Uniques
Scaling PHP to 40 Million UniquesJonathan Klein
 
PHP, LAMP Stack & WordPress
PHP, LAMP Stack & WordPressPHP, LAMP Stack & WordPress
PHP, LAMP Stack & WordPressSuman Srinivasan
 
DiUS Computing Lca Rails Final
DiUS  Computing Lca Rails FinalDiUS  Computing Lca Rails Final
DiUS Computing Lca Rails FinalRobert Postill
 
Native Javascript apps with PhoneGap
Native Javascript apps with PhoneGapNative Javascript apps with PhoneGap
Native Javascript apps with PhoneGapMartin de Keijzer
 

Similar to Secret sauce of building php applications (20)

Php Symfony and software-life-cycle
Php Symfony and software-life-cyclePhp Symfony and software-life-cycle
Php Symfony and software-life-cycle
 
Php myths
Php mythsPhp myths
Php myths
 
Debugging LAMP Apps on Linux/UNIX Using Open Source Tools - Jess Portnot - OS...
Debugging LAMP Apps on Linux/UNIX Using Open Source Tools - Jess Portnot - OS...Debugging LAMP Apps on Linux/UNIX Using Open Source Tools - Jess Portnot - OS...
Debugging LAMP Apps on Linux/UNIX Using Open Source Tools - Jess Portnot - OS...
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.js
 
Dynamic Languages In The Enterprise (4developers march 2009)
Dynamic Languages In The Enterprise (4developers march 2009)Dynamic Languages In The Enterprise (4developers march 2009)
Dynamic Languages In The Enterprise (4developers march 2009)
 
How the Web Works
How the Web WorksHow the Web Works
How the Web Works
 
PHP Doesn't Suck
PHP Doesn't SuckPHP Doesn't Suck
PHP Doesn't Suck
 
WordCamp Victoria 2013: Plugin Development 2013
WordCamp Victoria 2013: Plugin Development 2013WordCamp Victoria 2013: Plugin Development 2013
WordCamp Victoria 2013: Plugin Development 2013
 
Go is your friend
Go is your friendGo is your friend
Go is your friend
 
Go is your friend - Reppucci
Go is your friend - Reppucci Go is your friend - Reppucci
Go is your friend - Reppucci
 
Web Application Testing. A Quick Guide to Testing and Security
Web Application Testing. A Quick Guide to Testing and SecurityWeb Application Testing. A Quick Guide to Testing and Security
Web Application Testing. A Quick Guide to Testing and Security
 
Introduction to node.js by Ran Mizrahi @ Reversim Summit
Introduction to node.js by Ran Mizrahi @ Reversim SummitIntroduction to node.js by Ran Mizrahi @ Reversim Summit
Introduction to node.js by Ran Mizrahi @ Reversim Summit
 
Adhearsion @ eComm 2009 Final
Adhearsion @ eComm 2009   FinalAdhearsion @ eComm 2009   Final
Adhearsion @ eComm 2009 Final
 
Node.js Patterns and Opinions
Node.js Patterns and OpinionsNode.js Patterns and Opinions
Node.js Patterns and Opinions
 
Ruby - The Hard Bits
Ruby - The Hard BitsRuby - The Hard Bits
Ruby - The Hard Bits
 
YAPC::EU::2009 - How Opera Software uses Perl
YAPC::EU::2009 - How Opera Software uses PerlYAPC::EU::2009 - How Opera Software uses Perl
YAPC::EU::2009 - How Opera Software uses Perl
 
Scaling PHP to 40 Million Uniques
Scaling PHP to 40 Million UniquesScaling PHP to 40 Million Uniques
Scaling PHP to 40 Million Uniques
 
PHP, LAMP Stack & WordPress
PHP, LAMP Stack & WordPressPHP, LAMP Stack & WordPress
PHP, LAMP Stack & WordPress
 
DiUS Computing Lca Rails Final
DiUS  Computing Lca Rails FinalDiUS  Computing Lca Rails Final
DiUS Computing Lca Rails Final
 
Native Javascript apps with PhoneGap
Native Javascript apps with PhoneGapNative Javascript apps with PhoneGap
Native Javascript apps with PhoneGap
 

More from Lin Yo-An

Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Lin Yo-An
 
Getting merged
Getting mergedGetting merged
Getting mergedLin Yo-An
 
OSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersOSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersLin Yo-An
 
OSDC.TW 2014 building popular open source projects
OSDC.TW 2014   building popular open source projectsOSDC.TW 2014   building popular open source projects
OSDC.TW 2014 building popular open source projectsLin Yo-An
 
Happy Go Programming
Happy Go ProgrammingHappy Go Programming
Happy Go ProgrammingLin Yo-An
 
Happy Go Programming Part 1
Happy Go Programming Part 1Happy Go Programming Part 1
Happy Go Programming Part 1Lin Yo-An
 
LazyRecord: The Fast ORM for PHP
LazyRecord: The Fast ORM for PHPLazyRecord: The Fast ORM for PHP
LazyRecord: The Fast ORM for PHPLin Yo-An
 
Vim Script Programming
Vim Script ProgrammingVim Script Programming
Vim Script ProgrammingLin Yo-An
 
CPAN 模組二三事
CPAN 模組二三事CPAN 模組二三事
CPAN 模組二三事Lin Yo-An
 
Vim Hacks (OSSF)
Vim Hacks (OSSF)Vim Hacks (OSSF)
Vim Hacks (OSSF)Lin Yo-An
 
Perl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim PerlchinaPerl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim PerlchinaLin Yo-An
 
Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.VimLin Yo-An
 

More from Lin Yo-An (13)

Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015
 
Getting merged
Getting mergedGetting merged
Getting merged
 
OSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersOSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP haters
 
OSDC.TW 2014 building popular open source projects
OSDC.TW 2014   building popular open source projectsOSDC.TW 2014   building popular open source projects
OSDC.TW 2014 building popular open source projects
 
Happy Go Programming
Happy Go ProgrammingHappy Go Programming
Happy Go Programming
 
Happy Go Programming Part 1
Happy Go Programming Part 1Happy Go Programming Part 1
Happy Go Programming Part 1
 
LazyRecord: The Fast ORM for PHP
LazyRecord: The Fast ORM for PHPLazyRecord: The Fast ORM for PHP
LazyRecord: The Fast ORM for PHP
 
Vim Script Programming
Vim Script ProgrammingVim Script Programming
Vim Script Programming
 
CPAN 模組二三事
CPAN 模組二三事CPAN 模組二三事
CPAN 模組二三事
 
Vim Hacks (OSSF)
Vim Hacks (OSSF)Vim Hacks (OSSF)
Vim Hacks (OSSF)
 
Perl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim PerlchinaPerl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim Perlchina
 
Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.Vim
 
Vim Hacks
Vim HacksVim Hacks
Vim Hacks
 

Recently uploaded

[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...BookNet Canada
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observabilityitnewsafrica
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkPixlogix Infotech
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Mark Simos
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFMichael Gough
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Karmanjay Verma
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...Karmanjay Verma
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 

Recently uploaded (20)

[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App Framework
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDF
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 

Secret sauce of building php applications

  • 1. Secret sauce of building PHP applications 林佑安 (Yo-An Lin) aka c9s Monday, January 14, 13
  • 2. About • GitHub, Twitter, Plurk: @c9s • 220+ GitHub repository in Perl, VimL, PHP, JavaScript and Go. Monday, January 14, 13
  • 3. 為什麼是 PHP? Monday, January 14, 13
  • 4. Hey! PHP Sucks Monday, January 14, 13
  • 6. 2000 年開始使⽤用 PHP websites ⼤大幅成⻑⾧長 Monday, January 14, 13
  • 8. ⾼高流量 PHP 網站 High traffic PHP websites Monday, January 14, 13
  • 26. Applications developed with Symfony. http://trac.symfony-project.org/wiki/ ApplicationsDevelopedWithSymfony 1000+ websites listed. Monday, January 14, 13
  • 27. Yii powered applications http://www.yiiframework.com/forum/ index.php/forum/14-yii-powered- applications/ Monday, January 14, 13
  • 28. ⼤大家都跑 PHP Monday, January 14, 13
  • 30. 劣即是夯 唐鳳 - OSDC 2012 Monday, January 14, 13
  • 33. ⼗十個有九個 都會寫 PHP Monday, January 14, 13
  • 34. 你Grandma都會寫 PHP 我也寫 PHP Monday, January 14, 13
  • 36. 你還在使⽤用⽯石器時代 的 PHP 嗎? Monday, January 14, 13
  • 40. ⽯石器時代 PHP • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂) Monday, January 14, 13
  • 41. ⽯石器時代 PHP • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂) • Copy & Paste (品質低落) Monday, January 14, 13
  • 42. ⽯石器時代 PHP • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂) • Copy & Paste (品質低落) • .inc 附檔名 (安全漏洞) Monday, January 14, 13
  • 43. ⽯石器時代 PHP • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂) • Copy & Paste (品質低落) • .inc 附檔名 (安全漏洞) • ⼤大量的 require 呼叫循環 (效能問題) Monday, January 14, 13
  • 44. ⽯石器時代 PHP • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂) • Copy & Paste (品質低落) • .inc 附檔名 (安全漏洞) • ⼤大量的 require 呼叫循環 (效能問題) • HTML Render 不做 Escape (XSS 漏洞) Monday, January 14, 13
  • 45. ⽯石器時代 PHP • Dreamweaver PHP 產⽣生器 (⻤⿁鬼才看得懂) • Copy & Paste (品質低落) • .inc 附檔名 (安全漏洞) • ⼤大量的 require 呼叫循環 (效能問題) • HTML Render 不做 Escape (XSS 漏洞) • POST/GET 從不過濾 (SQL Injection) Monday, January 14, 13
  • 48. 24⼩小時學會 PHP • 語⾔言學習⼊入⾨門⾨門檻低 Monday, January 14, 13
  • 49. 24⼩小時學會 PHP • 語⾔言學習⼊入⾨門⾨門檻低 • 隨便寫,丟給 Apache 就可以執⾏行了 Monday, January 14, 13
  • 50. 24⼩小時學會 PHP • 語⾔言學習⼊入⾨門⾨門檻低 • 隨便寫,丟給 Apache 就可以執⾏行了 • $_POST, $_GET 是什麼⻤⿁鬼 (管他,可以跑 就好了) Monday, January 14, 13
  • 51. 24⼩小時學會 PHP • 語⾔言學習⼊入⾨門⾨門檻低 • 隨便寫,丟給 Apache 就可以執⾏行了 • $_POST, $_GET 是什麼⻤⿁鬼 (管他,可以跑 就好了) • 義⼤大利麵好煮⼜又好吃,維護是什麼?沒 聽過! Monday, January 14, 13
  • 52. 寫這樣的 PHP 您⼼心安嗎? Monday, January 14, 13
  • 53. 現代 PHP 解決⽅方案 The Modern PHP Solution Monday, January 14, 13
  • 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
  • 56. Zend Engine Compilation Monday, January 14, 13
  • 57. Request File a.php Scanning Zend Engine Lexing Compilation AST Parsing Compilation Execution Output Monday, January 14, 13
  • 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 Output Monday, January 14, 13
  • 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 Output Monday, January 14, 13
  • 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 Output Monday, January 14, 13
  • 61. 那 APC 呢? Monday, January 14, 13
  • 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 Output Monday, January 14, 13
  • 64. 這就是 WordPress 慢的原因 http://talks.php.net/presentations/slides/intro/wp_inclued1.png Monday, January 14, 13
  • 65. PHP spl_autoload_* • PHP 5.3+ 的新功能。 Monday, January 14, 13
  • 66. PHP spl_autoload_* • PHP 5.3+ 的新功能。 • 可註冊⾃自訂的類別載⼊入策略 (autoloading strategy) Monday, January 14, 13
  • 67. PHP spl_autoload_* • PHP 5.3+ 的新功能。 • 可註冊⾃自訂的類別載⼊入策略 (autoloading strategy) • 對於找不到定義的類別,⾃自動呼叫 class loader 進⾏行類別的⾃自動載⼊入。 Monday, January 14, 13
  • 68. PHP spl_autoload_* • PHP 5.3+ 的新功能。 • 可註冊⾃自訂的類別載⼊入策略 (autoloading strategy) • 對於找不到定義的類別,⾃自動呼叫 class loader 進⾏行類別的⾃自動載⼊入。 • 每個 request 只會載⼊入⾃自⼰己需要的 class, ⽤用越少,載越少。 Monday, January 14, 13
  • 69. PSR ⾞車同軌,書同⽂文 Monday, January 14, 13
  • 70. PSR-0 for PHP class 定義了 ClassLoader 的規範 Monday, January 14, 13
  • 71. $bar = new FooBar; spl_autoload_call(“FooBar”) Monday, January 14, 13
  • 72. Package dependency 套件相依性 Monday, January 14, 13
  • 77. Composer https://github.com/composer/composer http://www.slideshare.net/naderman/composer-9206307 Monday, January 14, 13
  • 78. Composer https://github.com/composer/composer • composer.json 取材於 Node.js NPM http://www.slideshare.net/naderman/composer-9206307 Monday, January 14, 13
  • 79. Composer https://github.com/composer/composer • composer.json 取材於 Node.js NPM • 更好的相依性解決⽅方案 SAT,取材於 OpenSuse 的 minisat / libzypper http://www.slideshare.net/naderman/composer-9206307 Monday, January 14, 13
  • 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-9206307 Monday, January 14, 13
  • 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-9206307 Monday, January 14, 13
  • 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-9206307 Monday, January 14, 13
  • 83. Onion http://github.com/c9s/Onion Monday, January 14, 13
  • 84. Onion http://github.com/c9s/Onion • PEAR 向後相容⼯工具 Monday, January 14, 13
  • 85. Onion http://github.com/c9s/Onion • PEAR 向後相容⼯工具 • 提供簡易的套件定義 package.ini Monday, January 14, 13
  • 86. Onion http://github.com/c9s/Onion • PEAR 向後相容⼯工具 • 提供簡易的套件定義 package.ini • 可快速打包成 PEAR 套件 Monday, January 14, 13
  • 87. Onion http://github.com/c9s/Onion • PEAR 向後相容⼯工具 • 提供簡易的套件定義 package.ini • 可快速打包成 PEAR 套件 • 可 Bundle 安裝 PEAR 套件 (like Ruby Bundler) Monday, January 14, 13
  • 89. phpbrew http://github.com/c9s/phpbrew Monday, January 14, 13
  • 90. phpbrew http://github.com/c9s/phpbrew • 取材⾃自 @gugod perlbrew Monday, January 14, 13
  • 91. phpbrew http://github.com/c9s/phpbrew • 取材⾃自 @gugod perlbrew • 易於切換 PHP 相關版本 Monday, January 14, 13
  • 92. phpbrew http://github.com/c9s/phpbrew • 取材⾃自 @gugod perlbrew • 易於切換 PHP 相關版本 • 提供 variant 建置選項 +mysql, +pgsql...etc Monday, January 14, 13
  • 93. phpbrew http://github.com/c9s/phpbrew • 取材⾃自 @gugod perlbrew • 易於切換 PHP 相關版本 • 提供 variant 建置選項 +mysql, +pgsql...etc • 不需 root 權限 Monday, January 14, 13
  • 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. PHP library/app from corneltek Monday, January 14, 13
  • 96. PHP Projects • phpbrew • PEARX • CLIFramework • Universal • Onion • FormKit • Roller Router • ValidationKit • LazyRecord • ClassMap • ActionKit • GetOptionKit 族繁不及備載... Monday, January 14, 13
  • 99. It’s not that simple 並⾮非像輪⼦子那樣的簡單 Monday, January 14, 13
  • 100. 軟體有相依性 但輪⼦子沒有 Monday, January 14, 13
  • 101. ⼀一旦應⽤用程式相依了他⼈人的框架 你的開發模式也將受到侷限 Monday, January 14, 13
  • 102. 開發⼯工具與⼈人息息相關 但輪⼦子只需透過輪軸傳動 Monday, January 14, 13
  • 106. 什麼是 FullStack Framework ? Monday, January 14, 13
  • 108. FullStack Framework • Rails • Zend Framework • Symfony • WordPress • Joomla • etc... Monday, January 14, 13
  • 110. 使⽤用⼀一個架構快速⼤大幅修改的框架 FW 1.0 App A 這個 FW 好像不錯 來⽤用⽤用看 Monday, January 14, 13
  • 111. 使⽤用⼀一個架構快速⼤大幅修改的框架 FW 1.0 FW 2.0 App A Monday, January 14, 13
  • 112. 使⽤用⼀一個架構快速⼤大幅修改的框架 FW 1.0 FW 2.0 App A App B 改太多 2.0 有個功能 X 實在 沒時間升級啦 太棒了,趕快來⽤用 不管了 Monday, January 14, 13
  • 113. 使⽤用⼀一個架構快速⼤大幅修改的框架 FW 1.0 FW 2.0 FW 3.0 App A App B Monday, January 14, 13
  • 114. 使⽤用⼀一個架構快速⼤大幅修改的框架 FW 1.0 FW 2.0 FW 3.0 App A App B Migration is hard! 相依於 FW2.0 的 X 功能 但 FW3.0 卻拿掉了 X Monday, January 14, 13
  • 115. 使⽤用⼀一個架構快速⼤大幅修改的框架 FW 1.0 FW 2.0 FW 3.0 App A App B App C 無形之中增加的維護成本 怕跟不上潮流,於是 新網站⼜又使⽤用 FW 3.0 Monday, January 14, 13
  • 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
  • 118. 使⽤用 FullStack 框架之侷限 • 隨著框架不斷修改內建⾏行為, 升級 的過程,就會有越多不確定因素 (bug, security) Monday, January 14, 13
  • 119. 使⽤用 FullStack 框架之侷限 • 隨著框架不斷修改內建⾏行為, 升級 的過程,就會有越多不確定因素 (bug, security) • 網站規模越⼤大,升級越苦。 Monday, January 14, 13
  • 120. 使⽤用 FullStack 框架之侷限 • 隨著框架不斷修改內建⾏行為, 升級 的過程,就會有越多不確定因素 (bug, security) • 網站規模越⼤大,升級越苦。 • 功能開發及系統效能會因為框架⽽而 有所限制。 Monday, January 14, 13
  • 123. So how do we do that? Monday, January 14, 13
  • 124. Divide and Conquer Monday, January 14, 13
  • 125. Framework should just be “framework” Monday, January 14, 13
  • 126. Components should be easy to adapt/swap Monday, January 14, 13
  • 127. Each component should have a package state - API stability -Package stability Monday, January 14, 13
  • 128. Component A The core is pretty small, we don’t need to change Framework Component B core API frequently Component C Monday, January 14, 13
  • 129. Component A 2.0 API Lock Stable Framework Component B API Lock Stable API Lock Beta Stability Component C API Beta Beta Stability Monday, January 14, 13
  • 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 Stability Monday, January 14, 13
  • 131. How do we build CLI applications? Monday, January 14, 13
  • 132. CLIFramework https://github.com/c9s/CLIFramework Monday, January 14, 13
  • 133. CLIFramework • 提供最快最簡易的⽅方式建置⼀一個命令列 的⼯工具 • phpbrew, onion, classmap ... etc Monday, January 14, 13
  • 134. CLIFramework ⽀支持⼦子命令及⼦子命令選項 Monday, January 14, 13
  • 135. CLIFramework <?php namespace TestAppCommand; use CLIFrameworkCommand; class ListCommand extends Command { function execute($arg1,$arg2) { // .. do something here... } } Monday, January 14, 13
  • 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. CLIFramework <?php $app = new TestAppApplication; $app->run($argv); Monday, January 14, 13
  • 138. CLIFramework ⾃自動產⽣生的 Command-line help Monday, January 14, 13
  • 139. How do we generate forms? Monday, January 14, 13
  • 140. FormKit https://github.com/c9s/FormKit Monday, January 14, 13
  • 141. FormKit • A powerful form widget generator. • Simple API for defining widgets and layout. • Customizable layout engine. Monday, January 14, 13
  • 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; // render Monday, January 14, 13
  • 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. 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. 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. Available Widgets • TextareaInput • Label • TextInput • PasswordInput • ButtonInput • RadioInput • CheckboxInput • ResetInput • ColorInput • SelectInput • DateInput • SubmitInput • DatetimeInput • AjaxCompleteInput • FileInput • CanvasInput • HiddenInput Monday, January 14, 13
  • 147. For more details http://github.com/c9s/FormKit Monday, January 14, 13
  • 148. How do we define logics for forms? Monday, January 14, 13
  • 149. ActionKit https://github.com/c9s/ActionKit Monday, January 14, 13
  • 150. ActionKit • Let you define logics and form field definitions. • Use FormKit to render form fields automatically. Monday, January 14, 13
  • 151. If I have a login form and login logics Monday, January 14, 13
  • 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. <?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. 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. 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. How do we dispatch URL? Monday, January 14, 13
  • 157. Roller Router https://github.com/c9s/Roller Monday, January 14, 13
  • 158. Roller Router • A fast router for PHP. Monday, January 14, 13
  • 159. Roller Router • A fast router for PHP. • Designed for performance. Monday, January 14, 13
  • 160. Roller Router • A fast router for PHP. • Designed for performance. • Let you define plugins, routes easily. Monday, January 14, 13
  • 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. 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. Roller Router • A fast router for PHP. • Designed for performance. • Let you define plugins, routes easily. • APC / File Cache. • Annotation Reader support. • RESTful plugin Monday, January 14, 13
  • 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. Roller Router <?php $router = new RollerRouter( null, array( 'cache_id' => 'router_demo' )); Monday, January 14, 13
  • 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. 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. Roller: Add routes <?php $router->add( '/posts/:id', array('PostController','readPostAction') ); Monday, January 14, 13
  • 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. One more thing! Monday, January 14, 13
  • 171. If you’re using PHP5.4+ Monday, January 14, 13
  • 172. You can even use the built-in HTTP server. Monday, January 14, 13
  • 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 here Monday, January 14, 13
  • 174. $ php -S localhost:8888 router.php Monday, January 14, 13
  • 175. How about RESTful? Monday, January 14, 13
  • 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. 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/=/book Monday, January 14, 13
  • 178. For more details http://github.com/c9s/Roller Monday, January 14, 13
  • 179. LazyRecord https://github.com/c9s/Roller Monday, January 14, 13
  • 180. A Fast PHP ORM Monday, January 14, 13
  • 181. Why another PHP ORM ? Monday, January 14, 13
  • 182. PHP ORMs • Doctrine Monday, January 14, 13
  • 183. PHP ORMs • Doctrine • Propel Monday, January 14, 13
  • 184. PHP ORMs • Doctrine • Propel • Idiorm / Paris Monday, January 14, 13
  • 185. Propel / Doctrine • Propel uses XML Schema file. Monday, January 14, 13
  • 186. Propel / Doctrine • Propel uses XML Schema file. • Doctrine uses XML/YAML/Annotations. Monday, January 14, 13
  • 187. Propel / Doctrine • Propel uses XML Schema file. • Doctrine uses XML/YAML/Annotations. • Slow & Fat. Monday, January 14, 13
  • 188. Propel / Doctrine • Propel uses XML Schema file. • Doctrine uses XML/YAML/Annotations. • Slow & Fat. • Doctrine is too complicated. Monday, January 14, 13
  • 190. • XML for configuration file. • XML for schema file. • XML for everything. • Concepts are from Java, too complicated. Monday, January 14, 13
  • 191. Propel XML runtime.conf Monday, January 14, 13
  • 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 postgresql's 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. <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 postgresql's 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
  • 195. So we designed an easier ORM Monday, January 14, 13
  • 196. LazyRecord • Lazy attributes. Monday, January 14, 13
  • 197. LazyRecord • Lazy attributes. • Lazy schema loader. Monday, January 14, 13
  • 198. LazyRecord • Lazy attributes. • Lazy schema loader. • Dynamic schema via PHP code Monday, January 14, 13
  • 199. LazyRecord • Lazy attributes. • Lazy schema loader. • Dynamic schema via PHP code • Static schema class generator Monday, January 14, 13
  • 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. LazyRecord • Filter / Canonicalizer support. Monday, January 14, 13
  • 202. LazyRecord • Filter / Canonicalizer support. • CRUD support via ActionKit. Monday, January 14, 13
  • 203. LazyRecord • Filter / Canonicalizer support. • CRUD support via ActionKit. • Form generation via ActionKit. Monday, January 14, 13
  • 204. LazyRecord • Filter / Canonicalizer support. • CRUD support via ActionKit. • Form generation via ActionKit. • Migration support. Monday, January 14, 13
  • 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. 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 Pattern Monday, January 14, 13
  • 207. LazyRecord: Collection <?php $authors = new AuthorCollection; foreach( $authors as $author ) { echo $author->name , "n" } Collection Iterating Monday, January 14, 13
  • 208. LazyRecord: Collection $authors = new AuthorCollection; $authors->where() ->equal('name','Foo') ->groupBy('name','address'); SQL Conditions via SQLBuilder Monday, January 14, 13
  • 209. LazyRecord: Collection $newAuthors = $authors->filter(function($item) { // do something else })->filter(function($item) { return $item->confirmed; }); Monday, January 14, 13
  • 211. Model Schema -> CRUD Actions -> Form Layout Monday, January 14, 13
  • 212. LazyRecord Model Schema Monday, January 14, 13
  • 213. LazyRecord Model Schema ⇛ Action Monday, January 14, 13
  • 214. LazyRecord Model Schema ⇛ Action ⇛ CRUD Monday, January 14, 13
  • 215. LazyRecord App::Model::Phone ☚ write once Monday, January 14, 13
  • 216. LazyRecord App::Model::Phone App::Model::PhoneCollection Monday, January 14, 13
  • 217. LazyRecord App::Model::Phone App::Model::PhoneCollection App::Action::CreatePhone Monday, January 14, 13
  • 218. LazyRecord App::Model::Phone App::Model::PhoneCollection App::Action::CreatePhone App::Action::UpdatePhone Monday, January 14, 13
  • 219. LazyRecord App::Model::Phone App::Model::PhoneCollection App::Action::CreatePhone App::Action::UpdatePhone App::Action::DeletePhone Monday, January 14, 13
  • 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. 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
  • 223. 2013 年 還在⾃自⼰己⼿手動下 SQL 做 migration 嗎? Monday, January 14, 13
  • 227. For more details http://github.com/c9s/LazyRecord http://www.slideshare.net/c9s/lazyrecord-the-fast-orm-for-php Monday, January 14, 13
  • 228. Thank you Find me: Twitter: @c9s Monday, January 14, 13