Objects for the Masses
Marcus Börger
PHP Quebec 0 9 : http:/ / talks.som abo.de/ 2 0 0 9 0 3 .pdf | .pps
Objects for the Masses Marcus Brger PHP Quebec 0 9 : http:/ / - - PowerPoint PPT Presentation
Objects for the Masses Marcus Brger PHP Quebec 0 9 : http:/ / talks.som abo.de/ 2 0 0 9 0 3 .pdf | .pps Overview 3 What is OOP? 25 PHP & OOP 29 PHP OOP In Detail 48 Class Design 50 Dynamic Class Loading 55 Exceptions 77 Reflection
PHP Quebec 0 9 : http:/ / talks.som abo.de/ 2 0 0 9 0 3 .pdf | .pps
Marcus Börger Objects for the Masses 2
Marcus Börger Objects for the Masses 3
c l a s s Us e l e s s e xt e nds Nons e ns e { a bs t r a c t f unc t i on bl a Bl a ( ) ; }
Marcus Börger Objects for the Masses 4
Marcus Börger Objects for the Masses 5
Marcus Börger Objects for the Masses 6
Marcus Börger Objects for the Masses 7
Marcus Börger Objects for the Masses 8
For instance, if you press a key on your laptop keyboard you do not know what is happening in detail. For you it is the same as if you press the keyboard of an ATM. We say the interface is the sam e. If another person has the same laptop the internal details would be exactly the same.
Marcus Börger Objects for the Masses 9
For instance, if you publish a text that is not really different from publishing a picture. Both are content types and you might want to encapsulate the details on how to do the actual publishing in a class. And once you have that you can easily have content that consists of both pictures and text and yet use the same operations for publishing. Then later you might publish tables using the same interface.
Marcus Börger Objects for the Masses 10
c l a s s Si m pl e { f unc t i on __c ons t r uc t ( ) { / *. . . */ } f unc t i on __de s t r uc t ( ) { / *. . . */ } }
Marcus Börger Objects for the Masses 11
anyone can access it
no one can re-declare it
someone else will implement this Why have these in PHP? Because som etimes self-discipline isn’t enough.
Marcus Börger Objects for the Masses 12
Marcus Börger Objects for the Masses 13
You often end up with code that looks like this: f unc t i on f oo_t o_xm l ( $f oo) { / / ge ne r i c s t uf f / / f oo- s pe c i f i c s t uf f } f unc t i on ba r _t o_xm l ( $ba r ) { / / ge ne r i c s t uf f / / ba r s pe c i f i c s t uf f }
Marcus Börger Objects for the Masses 14
f unc t i on ba s e _t o_xm l ( $da t a ) { / *. . . */ } f unc t i on f oo_t o_xm l ( $f oo) { ba s e _t o_xm l ( $f oo) ; / / f oo s pe c i f i c s t uf f } f unc t i on ba r _t o_xm l ( $ba r ) { ba s e _t o_xm l ( $ba r ) ; / / ba r s pe c i f i c s t uf f }
Marcus Börger Objects for the Masses 15
c l a s s Ba r e xt e nds Ba s e { publ i c f unc t i on t oXM L( ) { pa r e nt : : t oXM L( ) ; / / ba r s pe c i f i c s t uf f } } c l a s s Ba s e { publ i c f unc t i on t oXM L( ) { / *. . . */ } } c l a s s Foo e xt e nds Ba s e { publ i c f unc t i on t oXM L( ) { pa r e nt : : t oXM L( ) ; / / f oo s pe c i f i c s t uf f } }
Marcus Börger Objects for the Masses 16
Procedurally dislpaying all the entries might look like: f or e a c h( $e nt r i e s a s $e nt r y) { s wi t c h( $e nt r y[ ’ t ype ’ ] ) { c a s e ' pr of e s s i ona l ' : di s pl a y_pr of e s s i ona l _e nt r y( $e nt r y) ; br e a k; c a s e ' pe r s ona l ' : di s pl a y_pe r s ona l _e nt r y( $e nt r y) ; br e a k; } }
Marcus Börger Objects for the Masses 17
f or e a c h( $e nt r i e s a s $e nt r y) { $e nt r y- >di s pl a y( ) ; }
Marcus Börger Objects for the Masses 18
f or e a c h( $e nt r i e s a s $e nt r y) { e c ho $e nt r y; }
Marcus Börger Objects for the Masses 19
single toXML() function in a polymorphic way)
Marcus Börger Objects for the Masses 20
c l a s s Hum a ns { publ i c f unc t i on __c ons t r uc t ( $na m e ) { / *. . . */ } publ i c f unc t i on e a t ( ) { / *. . . */ } publ i c f unc t i on s l e e p( ) { / *. . . */ } publ i c f unc t i on s nor e ( ) { / *. . . */ } publ i c f unc t i on wa ke up( ) { / *. . . */ } }
Marcus Börger Objects for the Masses 21
c l a s s Hum a ns { publ i c f unc t i on __c ons t r uc t ( $na m e ) { / *. . . */ } publ i c f unc t i on e a t ( ) { / *. . . */ } publ i c f unc t i on s l e e p( ) { / *. . . */ } publ i c f unc t i on s nor e ( ) { / *. . . */ } publ i c f unc t i on wa ke up( ) { / *. . . */ } } c l a s s W
e n e xt e nds Hum a ns { publ i c f unc t i on gi ve Bi r t h( ) { / *. . . */ } }
Marcus Börger Objects for the Masses 22
c l a s s Hum a ns { publ i c f unc t i on __c ons t r uc t ( $na m e ) { / *. . . */ } publ i c f unc t i on e a t ( ) { / *. . . */ } publ i c f unc t i on s l e e p( ) { / *. . . */ } publ i c f unc t i on wa ke up( ) { / *. . . */ } } c l a s s W
e n e xt e nds Hum a ns { publ i c f unc t i on gi ve Bi r t h( ) { / *. . . */ } } c l a s s M e n e xt e nds Hum a ns { publ i c f unc t i on s nor e ( ) { / *. . . */ } }
Marcus Börger Objects for the Masses 23
a bs t r a c t c l a s s Hum a ns { publ i c f unc t i on __c ons t r uc t ( $na m e ) { / *. . . */ } a bs t r a c t publ i c f unc t i on ge nde r ( ) ; publ i c f unc t i on e a t ( ) { / *. . . */ } publ i c f unc t i on s l e e p( ) { / *. . . */ } publ i c f unc t i on wa ke up( ) { / *. . . */ } } c l a s s W
e n e xt e nds Hum a ns { publ i c f unc t i on ge nde r ( ) { r e t ur n ' f e m a l e ' ; } publ i c f unc t i on gi ve Bi r t h( ) { / *. . . */ } } c l a s s M e n e xt e nds Hum a ns { publ i c f unc t i on ge nde r ( ) { r e t ur n ' m a l e ' ; } publ i c f unc t i on s nor e ( ) { / *. . . */ } }
Marcus Börger Objects for the Masses 24
a bs t r a c t c l a s s Hum a ns { publ i c f unc t i on __c ons t r uc t ( $na m e ) { / *. . . */ } a bs t r a c t publ i c f unc t i on ge nde r ( ) ; publ i c f unc t i on e a t ( ) { / *. . . */ } publ i c f unc t i on s l e e p( ) { / *. . . */ } publ i c f unc t i on wa ke up( ) { / *. . . */ } } c l a s s W
e n e xt e nds Hum a ns { f i na l publ i c f unc t i on ge nde r ( ) { r e t ur n ' f ' ; } publ i c f unc t i on gi ve Bi r t h( ) { / *. . . */ } } c l a s s M e n e xt e nds Hum a ns { f i na l publ i c f unc t i on ge nde r ( ) { r e t ur n ' m ' ; } publ i c f unc t i on s nor e ( ) { / *. . . */ } }
Marcus Börger Objects for the Masses 25
Marcus Börger Objects for the Masses 26
Marcus Börger Objects for the Masses 27
Marcus Börger Objects for the Masses 28
Marcus Börger Objects for the Masses 29
Marcus Börger Objects for the Masses 30
c l a s s Obj e c t {}; $obj = ne w Obj e c t ( ) ; $r e f = $obj ; $dup = c l one $obj ;
Class Object $obj $ref $dup Instance 1 Instance 2
Marcus Börger Objects for the Masses 31
c l a s s Obj e c t { f unc t i on __c ons t r uc t ( ) {} f unc t i on __de s t r uc t ( ) {} } $obj = ne w Obj e c t ( ) ; uns e t ( $obj ) ;
Marcus Börger Objects for the Masses 32
c l a s s Ba s e { f unc t i on __c ons t r uc t ( ) {} f unc t i on __de s t r uc t ( ) {} } c l a s s Obj e c t e xt e nds Ba s e { f unc t i on __c ons t r uc t ( ) { par e nt : : __c ons t r uc t ( ) ; } f unc t i on __de s t r uc t ( ) { par e nt : : __de s t r uc t ( ) ; } } $obj = ne w Obj e c t ( ) ; uns e t ( $obj ) ;
Marcus Börger Objects for the Masses 33
c l a s s Obj e c t { va r $pr op = " He l l o\ n" ; } $obj 1 = ne w Obj e c t ; $obj 1- >pr op = " He l l o W
$obj 2 = ne w Obj e c t ; e c ho $obj 2- >pr op; / / He l l o
Class Object $prop/default $obj2 Instance 2 $prop $obj1 Instance 1 $prop
Marcus Börger Objects for the Masses 34
c l a s s Obj e c t { va r $pr op; s t at i c $s t a t = " Hel l o\ n" ; s t at i c f unc t i on t es t ( ) { e c ho s e l f : : $s t a t ; } } Obj e c t : : t e s t ( ) ; $obj 1 = ne w Obj e c t ; $obj 2 = ne w Obj e c t ;
Class Object $stat $obj2 Instance 2 $prop $obj1 Instance 1 $prop
Marcus Börger Objects for the Masses 35
shows the current class name
ETH O D__ shows class and method or function
references the class itself
references the parent class
references the object itself
c l a s s Ba s e { s t a t i c f unc t i on Show( ) { e c ho __FI LE__. ' ( ' . __LI NE__. ' ) : ' . __M ETHOD__. " \ n" ; } } c l a s s Obj e c t e xt e nds Ba s e { s t a t i c f unc t i on Us e ( ) { Se l f : : Show( ) ; Pa r e nt : : Show( ) ; } s t a t i c f unc t i on Show( ) { e c ho __FI LE__. ' ( ' . __LI NE__. ' ) : ' . __M ETHOD__. " \ n" ; } }
Marcus Börger Objects for the Masses 36
c l a s s Ba s e { publ i c $a ; pr ot e c t e d $b; pr i vat e $c ; } c l a s s De r i ve d e xt e nds Ba s e { publ i c $a ; publ i c $b; pr i vat e $c ; }
Base $a $b $c Derived $a $b $c Base::$c
Marcus Börger Objects for the Masses 37
c l a s s Ba s e { pr ot e c t e d f unc t i on __c ons t r uc t ( ) { } } c l a s s De r i ve d e xt e nds Ba s e { / / c ons t r uc t or i s s t i l l pr ot e c t e d s t a t i c f unc t i on ge t Ba s e ( ) { r e t ur n ne w Ba s e ; / / Fa c t or y pa t t e r n } } c l a s s Thr e e e xt e nds De r i ve d { publ i c f unc t i on __c ons t r uc t ( ) { } }
Marcus Börger Objects for the Masses 38
c l a s s Si ngl e t on { s t a t i c pr i va t e $i ns t a nc e ; pr ot e c t e d f unc t i on __c ons t r uc t ( ) {} f i na l pr i va t e f unc t i on __c l one ( ) {} s t a t i c f unc t i on ge t I ns t a nc e ( ) { i f ( ! s e l f : : $i ns t a nc e ) s e l f : : $i ns t a nc e = ne w Si ngl e t on( ) ; r e t ur n s e l f : : $i ns t a nc e ; } } $a = Si ngl e t on: : ge t I ns t a nc e ( ) ; $a - >i d = 1; $b = Si ngl e t on: : ge t I ns t a nc e ( ) ; pr i nt $b- >i d. " \ n" ;
Marcus Börger Objects for the Masses 39
c l a s s Ba s e { c ons t gr e e t i ng = " He l l o\ n" ; } c l a s s De r vi e d e xt e nds Ba s e { c ons t gr e e t i ng = " He l l o W
s t a t i c f unc t i on f unc ( ) { e c ho pa r e nt : : gr e e t i ng; } } e c ho Ba s e : : gr e e t i ng; e c ho De r i ve d: : gr e e t i ng; De r i ve d: : f unc ( ) ;
Marcus Börger Objects for the Masses 40
abs t r ac t c l a s s Ba s e { abs t r ac t f unc t i on no_body( ) ; } c l a s s De r i ve d e xt e nds Ba s e { f unc t i on no_body( ) { e c ho " Body\ n" ; } }
Marcus Börger Objects for the Masses 41
c l a s s Ba s e { f i nal f unc t i on i nva r i a nt ( ) { e c ho " He l l o\ n" ; } } c l a s s De r i ve d e xt e nds Ba s e { } f i nal c l a s s Le a f e xt e nds De r i ve d { }
Marcus Börger Objects for the Masses 42
c l a s s Li ne { f unc t i on dr a w( ) {}; } c l a s s Pol ygon { pr ot e c t e d $l i ne s ; f unc t i on dr a w( ) { f or e a c h( $t hi s - >l i ne s a s $l i ne) $l i ne - >dr a w( ) ; } } c l a s s Re c t a ngl e e xt e nds Pol ygon { } c l a s s El l i ps e { f unc t i on dr a w( ) {}; } c l a s s Ci r c l e ext e nds El l i ps e { f unc t i on dr a w( ) { pa r e nt : : dr a w( ) ; } }
Polygon Line Ellipse Circle $lines Rectangle
Marcus Börger Objects for the Masses 43
i nt e r f a c e Dr a wa bl e { f unc t i on dr a w( ) ; } c l a s s Li ne i m pl e m e nt s Dr a wa bl e { f unc t i on dr a w( ) {}; } c l a s s Pol ygon i m pl e m e nt s Dr a wa bl e { pr ot e c t e d $l i ne s ; f unc t i on dr a w( ) { f or e a c h( $t hi s - >l i ne s a s $l i ne) $l i ne - >dr a w( ) ; } } c l a s s Re c t a ngl e e xt e nds Pol ygon { } c l a s s El l i ps e i m pl e m e nt s Dr a wa bl e { f unc t i on dr a w( ) {}; } c l a s s Ci r c l e ext e nds El l i ps e { f unc t i on dr a w( ) { pa r e nt : : dr a w( ) ; } }
Drawable Polygon Line Ellipse Circle $lines Rectangle
Marcus Börger Objects for the Masses 44
Marcus Börger Objects for the Masses 45
c l a s s Obj e c t { f unc t i on __t oSt r i ng( ) { r e t ur n ' Obj e c t a s s t r i ng' ; } } $o = ne w Obj e c t ; e c ho $o; / / doe s c a l l __t oSt r i ng $s t r = ( s t r i ng) $o; / / doe s c a l l __t oSt r i ng
Marcus Börger Objects for the Masses 46
c l a s s Obj e c t { pr ot e c t e d $vi r t ua l = a r r a y( ) ; f unc t i on __ge t ( $na m e ) { r e t ur n @ $t hi s - >vi r t ua l [ $na m e ] ; } f unc t i on __s e t ( $na m e , $va l ue ) { $t hi s - >vi r t ua l [ $na m e ] = $va l ue ; } f unc t i on __uns e t ( $na m e ) { uns e t ( $t hi s - >vi r t ua l [ $na m e ] ) ; } f unc t i on __i s s e t ( $na m e ) { r e t ur n i s s e t ( $t hi s - >vi r t ua l [ $na m e ] ) ; } f unc t i on __c al l ( $f unc , $pa r a m s ) { e c ho ' Coul d not c a l l ' . __CLASS__ . ' : : ' . $f unc . " \ n" ; } }
Marcus Börger Objects for the Masses 47
c l a s s Obj e c t { publ i c f unc t i on c om pa r e ( Obj e c t $ot he r ) { / / Som e c ode he r e } publ i c f unc t i on c om pa r e 2( $ot he r ) { i f ( i s _nul l ( $ot he r ) | | $ot he r i ns t a nc e of Obj e c t ) { / / Som e c ode he r e } } }
Marcus Börger Objects for the Masses 48
Vehicle Truck Car Bus Diesel Gasoline Engine Bicycle Plane Tires Turbine Tank
Marcus Börger Objects for the Masses 49
Marcus Börger Objects for the Masses 50
Marcus Börger Objects for the Masses 51
N Only one single loader model is possible
Marcus Börger Objects for the Masses 52
r e qui r e _onc e ( ' <pa t h>/ a ut ol oa d. i nc ' )
a ut o_pr e pe nd_f i l e =<pa t h>/ a ut ol oa d. i nc
<? php f unc t i on __a ut ol oa d( $c l a s s _na m e ) { r e qui r e _onc e ( di r na m e ( __FI LE__) . ' / ' . $c l a s s _na m e . ' . p5c ' ) ; } ? >
Marcus Börger Objects for the Masses 53
<? php s pl _a ut ol oa d_r e gi s t e r ( ' s pl _a ut ol oa d' ) ; i f ( f unc t i on_e xi s t s ( ' __a ut ol oa d' ) ) { s pl _a ut ol oa d_r e gi s t e r ( ' __a ut ol oa d' ) ; } ? >
Marcus Börger Objects for the Masses 54
Marcus Börger Objects for the Masses 55
Marcus Börger Objects for the Masses 56
<? php t r y { / / your c ode t hr ow ne w Exc e pt i on( ) ; } c at c h ( Exc e pt i on $e ) { / / e xc e pt i on ha ndl i ng } ? >
Marcus Börger Objects for the Masses 57
c l a s s Your Exc e pt i on e xt e nds Exc e pt i on { } t r y { / / your c ode t hr ow ne w Your Exc e pt i on( ) ; } c a t c h ( Your Exc e pt i on $e ) { / / e xc e pt i on ha ndl i ng } c a t c h ( Exc e pt i on $e ) { / / e xc e pt i on ha ndl i ng }
Marcus Börger Objects for the Masses 58
c l a s s Your Exc e pt i on e xt e nds Exc e pt i on { } t r y { t r y { / / your c ode t hr ow ne w Your Exc e pt i on( ) ; } c a t c h ( Your Exc e pt i on $e ) { / / e xc e pt i on ha ndl i ng t hr ow $e ; } c a t c h ( Exc e pt i on $e ) { / / e xc e pt i on ha ndl i ng } } c a t c h ( Your Exc e pt i on $e ) { / / e xc e pt i on ha ndl i ng }
Marcus Börger Objects for the Masses 59
Marcus Börger Objects for the Masses 60
<? php c l a s s Obj e c t { f unc t i on __c ons t r uc t ( &$f a i l ur e ) / / " Obj e c t " i n PHP 4 { $f a i l ur e = t r ue ; } } $e r r or = f a l s e ; $o = ne w Obj e c t ( $e r r or ) ; i f ( ! $e r r or ) { / / e r r or ha ndl i ng, NOTE: t he obj e c t wa s c ons t r uc t e d uns e t ( $o) ; } ? >
Marcus Börger Objects for the Masses 61
<? php c l a s s Obj e c t { f unc t i on __c ons t r uc t ( ) { t hr ow ne w Exc e pt i on; } } t r y { $o = ne w Obj e c t ; } c a t c h ( Exc e pt i on $e ) { e c ho " Obj e c t c oul d not be i ns t a nt i a t e d\ n" ; } ? >
Marcus Börger Objects for the Masses 62
<? php i f ( ! c l a s s _e xi s t s ( ' Er r or Exc e pt i on' , f a l s e ) ) { c l a s s Er r or Exc e pt i on e xt e nds Exc e pt i on { pr ot e c t e d $s e ve r i t y; f unc t i on __c ons t r uc t ( $m s g, $c ode , $e r r no, $f i l e , $l i ne ) { pa r e nt : : __c ons t r uc t ( $m s g, $c ode ) ; $t hi s - >s e ve r i t y = $e r r no; $t hi s - >f i l e = $f i l e ; $t hi s - >l i ne = $l i ne ; } f unc t i on ge t Se ve r i t y( ) { r e t ur n $t hi s - >s e ve r i t y; } } } ? >
Marcus Börger Objects for the Masses 63
<? php f unc t i on Er r or s ToExc e pt i ons ( $e r r no, $m s g, $f i l e , $l i ne ) { t hr ow ne w Er r or Exc e pt i on( $m s g, 0, $e r r no, $f i l e , $l i ne ) ; } s e t _e r r or _ha ndl e r ( ' Er r or s ToExc e pt i ons ' ) ; ? >
Marcus Börger Objects for the Masses 64
<ht m l ><body> <? php $ok = f a l s e ; $db = ne w PDO( ' CONNECTI ON' ) ; i f ( $db) { $r e s = $db- >que r y( ' SELECT da t a ' ) ; i f ( $r e s ) { $r e s 2 = $db- >que r y( ' SELECT ot he r ' ) ; i f ( $r e s 2) { / / ha ndl e da t a $ok = t r ue ; / / onl y i f a l l we nt ok } } } i f ( ! $ok) e c ho ' <h1>Se r vi c e c ur r e nt l y una va i l a bl e </ h1>' ; ? > </ body></ ht m l >
Marcus Börger Objects for the Masses 65
<ht m l ><body> <? php t r y { $db = ne w PDO( ' CONNECTI ON' ) ; $db- >s e t At t r i but e ( PDO: : ATTR_ERRM ODE, PDO: : ERRM ODE_EXCEPTI ON) ; $r e s = $db- >que r y( ' SELECT da t a ' ) ; $r e s 2 = $db- >que r y( ' SELECT ot he r ' ) ; / / ha ndl e da t a } c a t c h ( Exc e pt i on $e ) { e c ho ' <h1>Se r vi c e c ur r e nt l y una va i l a bl e </ h1>' ; e r r or _l og( $e - >ge t M e s s a ge ( ) ) ; } ? > </ body></ ht m l >
Marcus Börger Objects for the Masses 66
Marcus Börger Objects for the Masses 67
Marcus Börger Objects for the Masses 68
Ba dM e t hodCa l l Exc e pt i on
Marcus Börger Objects for the Masses 69
Marcus Börger Objects for the Masses 70
a bs t r a c t c l a s s M yI t e r a t or W r a ppe r i m pl e m e nt s I t e r a t or { f unc t i on __c ons t r uc t ( I t e r a t or $i t ) { $t hi s - >i t = $i t ; } f unc t i on __c a l l ( $f unc , $a r gs ) { $c a l l e e = a r r a y( $t hi s - >i t , $f unc ) ; i f ( ! i s _c a l l a bl e ( $c a l l e e ) ) { t hr ow ne w Ba dM e t hodCa l l Exc e pt i on( ) ; } r e t ur n c a l l _us e r _f unc _a r r a y( $c a l l e e , $a r gs ) ; } }
Compile-Time: Error in design
Marcus Börger Objects for the Masses 71
a bs t r a c t
c l a s s M yI t e r a t or W r a ppe r i m pl e m e nt s I t e r a t or { f unc t i on __c ons t r uc t ( I t e r a t or $i t ) { $t hi s - >i t = $i t ; } f unc t i on __c a l l ( $f unc , $a r gs ) { $c a l l e e = a r r a y( $t hi s - >i t , $f unc ) ; i f ( ! i s _c a l l a bl e ( $c a l l e e ) ) { t hr ow ne w Ba dM e t hodCa l l Exc e pt i on( ) ; } r e t ur n c a l l _us e r _f unc _a r r a y( $c a l l e e , $a r gs ) ; } } I nt e r f a c e I t e r a t or { f unc t i on r e wi nd( ) ; f unc t i on va l i d( ) ; f unc t i on c ur r e nt ( ) ; f unc t i on ke y( ) ; f unc t i on ne xt ( ) ; }
Marcus Börger Objects for the Masses 72
c l a s s M yI t e r a t or W r a ppe r i m pl e m e nt s I t e r a t or { f unc t i on __c ons t r uc t ( I t e r a t or $i t ) { $t hi s - >i t = $i t ; } f unc t i on __c a l l ( $f unc , $a r gs ) { $c a l l e e = a r r a y( $t hi s - >i t , $f unc ) ; i f ( ! i s _c a l l a bl e ( $c a l l e e ) ) { t hr ow ne w Ba dM e t hodCa l l Exc e pt i on( ) ; } r e t ur n c a l l _us e r _f unc _a r r a y( $c a l l e e , $a r gs ) ; } f unc t i on r e wi nd( ) { $t hi s - >i t - >r e wi nd( ) ; } f unc t i on va l i d( ) { r e t ur n $t hi s - >i t - >va l i d( ) ; } f unc t i on c ur r e nt ( ) { r e t ur n $t hi s - >i t - >c ur r e nt ( ) ; } f unc t i on ke y( ) { r e t ur n $t hi s - >i t - >ke y( ) ; } f unc t i on ne xt ( ) { $t hi s - >i t - >ne xt ( ) ; } } I nt e r f a c e I t e r a t or { f unc t i on r e wi nd( ) ; f unc t i on va l i d( ) ; f unc t i on c ur r e nt ( ) ; f unc t i on ke y( ) ; f unc t i on ne xt ( ) ; }
Marcus Börger Objects for the Masses 73
$f o = ne w Spl Fi l e Obj e c t ( $f i l e ) ; $f o- >s e t Fl a gs ( Spl Fi l e Obj e c t : : DROP_NEW LI NE) ; $da t a = a r r a y( ) ; Run-Time: File might not be accessible or exist
Marcus Börger Objects for the Masses 74
Run-Time: data is different for every execution
$f o = ne w Spl Fi l e Obj e c t ( $f i l e ) ; $f o- >s e t Fl a gs ( Spl Fi l e Obj e c t : : DROP_NEW LI NE) ; $da t a = a r r a y( ) ; f or e a c h( $f o a s $l ) { i f ( / *** CHECK DATA ***/ ) { t hr ow ne w Ex c e pt i on( ) ; } $da t a [ ] = $l ; }
a t c h( $r e ge x, $l ) Une xpe c t Va l ue Exc e pt i on
$l ) ) ! = 3 Ra nge Exc e pt i on
Ove r f l owExc e pt i on Run-Time: File might not be accessible or exist
Marcus Börger Objects for the Masses 75
$f o = ne w Spl Fi l e Obj e c t ( $f i l e ) ; $f o- >s e t Fl a gs ( Spl Fi l e Obj e c t : : DROP_NEW LI NE) ; $da t a = a r r a y( ) ; f or e a c h( $f o a s $l ) { i f ( ! pr e g_m a t c h( ' / \ d, \ d/ ' , $l ) ) { t hr ow ne w Une xpe c t e dVa l ue Exc e pt i on( ) ; } $da t a [ ] = $l ; } / / Che c ks a f t e r t he f i l e wa s r e a d e nt i r e l y
t hr ow ne w Unde r f l owExc e pt i on( ) ;
t hr ow ne w Ove r f l owExc e pt i on( ) ;
t hr ow ne w Out Of Bounds Exc e pt i on( ) ; Run-Time: data is different for every execution Run-Time: Filemight not be accessible or exist
Marcus Börger Objects for the Masses 76
$f o = ne w Spl Fi l e Obj e c t ( $f i l e ) ; $f o- >s e t Fl a gs ( Spl Fi l e Obj e c t : : DROP_NEW LI NE) ; $da t a = a r r a y( ) ; f or e a c h( $f o a s $l ) { i f ( ! pr e g_m a t c h( ' / \ d, \ d/ ' , $l ) ) { t hr ow ne w Une xpe c t e dVa l ue Exc e pt i on( ) ; } $da t a [ ] = $l ; } i f ( c ount ( $da t a ) < 10) t hr ow ne w Unde r f l owExc e pt i on( ) ; / / m a ybe m
f or e a c h( $da t a a s & $v) { i f ( c ount ( $v) == 2) { t hr ow ne w Dom a i nExc e pt i on( ) ; } $v = $v[ 0] * $v[ 1] ; } Compile-Time: exception signals failed precondition Run-Time: data is different for every execution Run-Time: File might not be accessible or exist
Marcus Börger Objects for the Masses 77
Marcus Börger Objects for the Masses 78
c l a s s Foo { publ i c $pr op; f unc t i on Func ( $na m e ) { e c ho " He l l o $na m e " ; } } Re f l e c t i onCl a s s : : e xpor t ( ' Foo' ) ; Re f l e c t i onObj e c t : : e xpor t ( ne w Foo) ; Re f l e c t i onM e t hod: : e xpor t ( ' Foo' , ' f unc ' ) ; Re f l e c t i onPr ope r t y: : e xpor t ( ' Foo' , ' pr op' ) ; Re f l e c t i onExt e ns i on: : e xpor t ( ' s t a nda r d' ) ;
Marcus Börger Objects for the Masses 79
c l a s s Te s t { f unc t i on __c ons t r uc t ( $x, $y = NULL) { $t hi s - >x = $x; $t hi s - >y = $y; } } f unc t i on ne w_obj e c t _a r r a y( $c l s , $a r gs = NULL) { r e t ur n c a l l _us e r _f unc _a r r a y( a r r a y( ne w Re f l e c t i onCl a s s ( $c l s ) , ' ne wI ns t a nc e ' ) , $a r gs ) ; } ne w_obj e c t _a r r a y( ' s t dCl a s s ' ) ; ne w_obj e c t _a r r a y( ' Te s t ' , a r r a y( 1) ) ; ne w_obj e c t _a r r a y( ' Te s t ' , a r r a y( 1, 2) ) ;
Marcus Börger Objects for the Masses 80
Marcus Börger Objects for the Masses 81
php - - r e SPL php - - r c Ar r a yAc c e s s
Marcus Börger Objects for the Masses 82
i nt e r f a c e Ar r a yAc c e s s { / / @ r e t ur n whe t he r $of f s e t i s va l i d ( t r ue / f a l s e ) f unc t i on of f s e t Exi s t s ( $of f s e t ) ; / / @ r e t ur n t he va l ue a s s oc i a t e d wi t h $of f s e t f unc t i on of f s e t Ge t ( $of f s e t ) ; / / a s s oc i a t e $va l ue wi t h $of f s e t ( s t or e t he da t a ) f unc t i on of f s e t Se t ( $of f s e t , $va l ue ) ; / / uns e t t he da t a a s s oc i a t e d wi t h $of f s e t f unc t i on of f s e t Uns e t ( $of f s e t ) ; }
Marcus Börger Objects for the Masses 83
c l a s s M yAr r a y e xt e nds Ar r a yAc c e s s { f unc t i on &
} f unc t i on of f s e t Se t ( $of f s e t , & $va l ue ) { / * . . . */ } f unc t i on of f s e t Exi s t s ( $of f s e t ) { / * . . . */ } f unc t i on of f s e t Uns e t ( $of f s e t ) { / * . . . */ } }
Marcus Börger Objects for the Masses 84
Marcus Börger Objects for the Masses 85
<? php c l a s s Dba Ac c e s s i m pl e m e nt s Ar r a yAc c e s s { pr ot e c t e d $db = NULL; f unc t i on __c ons t r uc t ( $f i l e , $ha ndl e r ) { i f ( ! $t hi s - >db = dba _ope n( $f i l e , ' c d' , $ha ndl e r ) ) t hr ow ne w e xc e pt i on( ' Coul d not ope n f i l e ' . $f i l e ) ; } f unc t i on __de s t r uc t ( ) { dba _c l os e ( $t hi s - >db) ; } f unc t i on of f s e t Exi s t s ( $of f s e t ) { r e t ur n dba _e xi s t s ( $of f s e t , $t hi s - >db) ; } f unc t i on of f s e t Ge t ( $of f s e t ) { r e t ur n dba _f e t c h( $of f s e t , $t hi s - >db) ; } f unc t i on of f s e t Se t ( $of f s e t , $va l ue ) { r e t ur n dba _r e pl a c e ( $of f s e t , $va l ue , $t hi s - >db) ; } f unc t i on of f s e t Uns e t ( $of f s e t ) { r e t ur n dba _de l e t e ( $of f s e t , $t hi s - >db) ; } } ? >
Marcus Börger Objects for the Masses 86
<? php i f ( ! c l a s s _e xi s t s ( ' Dba Re a de r ' , f a l s e ) ) { r e qui r e _onc e ‘ dba de a de r . i nc ’ ; } $_SHARED = ne w Dba Ac c e s s ( ' / t m p/ . c ount e r ' , ' f l a t f i l e ' ) ; $_SHARED[ ' c ount e r ' ] += 1; pr i nt f ( " PI D: % d\ nCOUNTER: % d\ n" , ge t m ypi d( ) , $_SHARED[ ' c ount e r ' ] ) ; ? >
Marcus Börger Objects for the Masses 87
<? php c l a s s Obj e c t { publ i c $pr op1 = " He l l o " ; publ i c $pr op2 = " W
} f or e a c h( ne w Obj e c t a s $pr op) { e c ho $pr op; } ? >
Marcus Börger Objects for the Masses 88
Marcus Börger Objects for the Masses 89
Ar r a yObj e c t , Ar r a yI t e r a t or
Spl Fi l e Obj e c t
[ Re c ur s i ve ] Di r e c t or yI t e r a t or
ext: SimpleXML, DOM
ext: PDO, SQLite, MySQLi
PECL/ date (?)
?
Marcus Börger Objects for the Masses 90
Ar r a yObj e c t , Ar r a yI t e r a t or
Spl Fi l e Obj e c t
[ Re c ur s i ve ] Di r e c t or yI t e r a t or
ext: SimpleXML, DOM
ext: PDO, SQLite, MySQLi
PECL/ date (?)
?
Appe ndI t e r a t or , Ca c hi ngI t e r a t or , Li m i t I t e r a t or , Fi l t e r I t e r a t or , Em pt yI t e r a t or , I nf i ni t e I t e r a t or , NoRe wi ndI t e r a t or , Out e r I t e r a t or , Pa r e nt I t e r a t or , Re c ur s i ve I t e r a t or , Re c ur s i ve I t e r a t or I t e r a t or , Se e ka bl e I t e r a t or , Spl Fi l e Obj e c t , . . .
Marcus Börger Objects for the Masses 91
$a r = a r r a y( )
r e s e t ( $a r )
! i s _nul l ( ke y( $a r ) )
c ur r e nt ( $a r )
ke y( $a r )
ne xt ( $a r )
$i t = ne w I t e r a t or ;
$i t - >r e wi nd( )
( doe s not r e t ur n t he e l e m e nt )
$i t - >va l i d( )
$i t - >c ur r e nt ( )
$i t - >ke y( )
( m a y r e t ur n NULL a t a ny t i m e )
$i t - >ne xt ()
Marcus Börger Objects for the Masses 92
Marcus Börger Objects for the Masses 93
Marcus Börger Objects for the Masses 94
IteratorAggregate + getIterator () : Iterator Traversable Iterator + + + + + rewind () valid () current () key () next () : void : boolean : mixed : mixed : void
Marcus Börger Objects for the Masses 95
Traversable IteratorAggregate + getIterator () : Iterator Iterator + + + + + rewind () valid () current () key () next () : void : boolean : mixed : mixed : void AggregateImpl + <<Implement>> getIterator () : Iterator IteratorImpl + + + + + <<Implement>> <<Implement>> <<Implement>> <<Implement>> <<Implement>> rewind () valid () current () key () next () : void : boolean : mixed : mixed : void
Marcus Börger Objects for the Masses 96
<? php $o = ne w Ar r a yI t e r a t or ( ar r a y( 1, 2, 3) ) ; $o- >r e wi nd( ) ; whi l e ( $o- >va l i d( ) ) { $ke y = $o- >ke y( ) ; $va l = $o- >c ur r e nt ( ) ; / / s om e c ode $o- >ne xt ( ) ; } ? > <? php $o = ne w Ar r a yI t e r a t or ( ar r a y( 1, 2, 3) ) ; f or e a c h( $o a s $ke y => $va l ) { / / s om e c ode } ? >
Marcus Börger Objects for the Masses 97
< ?php $it = get_resource(); for ($it-> rewind(); $it-> valid(); $it-> next()) { $value = $it-> current(); $key = $it-> key(); } ?>
< ?php interface Iterator { function rewind(); function valid(); function current(); function key(); function next(); } ?>
Marcus Börger Objects for the Masses 98
< ?php $it = get_resource(); foreach($it as $key= > $val) { / / access data } ?> < ?php interface Iterator { function rewind(); function valid(); function current(); function key(); function next(); } ?>
Marcus Börger Objects for the Masses 99
< ?php $it = get_resource(); foreach(new Filter($it, $filter_param) as $key= > $val) { / / access filtered data only } ?> < ?php class FilterIterator implements Iterator { function __construct(Iterator $input)... function rewind()... function accept()... function valid()... function current()... function key()... function next()... } ?>
< ?php interface Iterator { function rewind(); function valid(); function current(); function key(); function next(); } ?>
Marcus Börger Objects for the Masses 100
<? php c l a s s Ar r a yI t er a t or { pr ot e c t e d $a r ; f unc t i on __c ons t r uc t ( Ar r a y $ar ) { $t hi s - >a r = $ar ; } f unc t i on r e wi nd( ) { r e wi nd( $t hi s - >a r ) ; } f uc nt i on va l i d( ) { r e t ur n ! i s _nul l ( ke y( $t hi s - >a r ) ) ; } f unc t i on ke y( ) { r e t ur n ke y( $t hi s - >a r ) ; } f uc nt i on c ur r ent ( ) { r e t ur n c ur r e nt ( $t hi s - >a r ) ; } f unc t i on ne xt ( ) { ne xt ( $t hi s - >a r ) ; } } ? > <? php $a = a r r a y( 1, 2, 3) ; $o = ne w Ar r a yI t e r a t or ( $a ) ; f or e a c h( $o a s $ke y => $va l ) { e c ho " $ke y => $va \ n" ; } ? > 0 => 1 1 => 2 2 => 3
PHP 5.1
Marcus Börger Objects for the Masses 101
Marcus Börger Objects for the Masses 102
Marcus Börger Objects for the Masses 103
/ / Re m e m be r Dba Ac c e s s f r om pa ge 86? / / c l a s s Dba Ac c e s s i m pl e m e nt s Ar r a yAc c e s s . . . c l a s s Dba Re a de r e xt e nds Dba Ac c e s s i m pl e m e nt s I t e r a t or { pr i va t e $ke y = f a l s e , $va l = f a l s e ; pr i va t e f unc t i on f e t c h_da t a ( $ke y) { i f ( ( $t hi s - >ke y = $ke y) ! == f a l s e ) $t hi s - >va l = dba _f e t c h( $t hi s - >ke y, $t hi s - >db) ; } f unc t i on r e wi nd( ) { $t hi s - >f e t c h_da t a ( dba _f i r s t ke y( $t hi s - >db) ) ; } f unc t i on ne xt ( ) { $t hi s - >f e t c h_da t a ( dba _ne xt ke y( $t hi s - >db) ) ; } f unc t i on c ur r e nt ( ) { r e t ur n $t hi s - >va l ; } f unc t i on va l i d( ) { r e t ur n $t hi s - >ke y ! == f a l s e ; } f unc t i on ke y( ) { r e t ur n $t hi s - >ke y; } } c l a s s I ni Fi l e e xt e nds Dba Re a de r { f unc t i on __c ons t r uc t ( $f i l e na m e ) { pa r e nt : : __c ons t r uc t ( $f i l e na m e , ' i ni f i l e ' ) ; } }
Marcus Börger Objects for the Masses 104
<? php c l a s s Ke yFi l t e r e xt e nds Fi l t e r I t e r a t or { pr i va t e $r x; f unc t i on __c ons t r uc t ( I t e r a t or $i t , $r e ge x) { pa r e nt : : __c ons t r uc t ( $i t ) ; $t hi s - >r x = $r e ge x; } f unc t i on a c c e pt ( ) { r e t ur n e r e g( $t hi s - >r x, $t hi s - >ge t I nne r I t e r a t or ( ) - >ke y( ) ) ; } f unc t i on ge t Re ge x( ) { r e t ur n $t hi s - >r x; } pr ot e c t e d f unc t i on __c l one ( $t ha t ) { / / di s a l l ow c l one } } ? >
Marcus Börger Objects for the Masses 105
<? php i f ( ! c l a s s _e xi s t s ( ' Ke yFi l t e r ' , f a l s e ) ) { r e qui r e _onc e ( ' ke yf i l t e r . i nc ' ) ; } c l a s s I ni Gr oups e xt e nds Ke yFi l t e r { f unc t i on __c ons t r uc t ( $f i l e na m e ) { pa r e nt : : __c ons t r uc t ( ne w I ni Fi l e ( $f i l e na m e ) , ' ^\ [ . *\ ] $' ) ; } f unc t i on c ur r e nt ( ) { r e t ur n s ubs t r ( pa r e nt : : ke y( ) , 1, - 1) ; } f unc t i on ke y( ) { r e t ur n s ubs t r ( pa r e nt : : ke y( ) , 1, - 1) ; } } ? >
Marcus Börger Objects for the Masses 106
<? php i f ( ! c l a s s _e xi s t s ( ' Ke yFi l t e r ' , f a l s e ) ) { r e qui r e _onc e ( ' ke yf i l t e r . i nc ' ) ; } i f ( ! c l a s s _e xi s t s ( ' I ni Gr oups ' , f a l s e ) ) { r e qui r e _onc e ( ' i ni gr oups . i nc ' ) ; } $i t = ne w I ni Gr oups ( $a r gv[ 1] ) ; i f ( $a r gc > 2) { $i t = ne w Ke yFi l t e r ( $i t , $a r gv[ 2] ) ; } f or e a c h( $i t a s $gr oup) { e c ho $gr oup . " \ n" ; } ? >
Avoid calling __a ut ol oa d( )
Marcus Börger Objects for the Masses 107
Marcus Börger Objects for the Masses 108
Marcus Börger Objects for the Masses 109
Marcus Börger Objects for the Masses 110
Marcus Börger Objects for the Masses 111
Marcus Börger Objects for the Masses 112
f or e a c h( $e nt r i e s a s $e nt r y) { e c ho $e nt r y; }
Marcus Börger Objects for the Masses 113
Marcus Börger Objects for the Masses 114
Marcus Börger Objects for the Masses 115
<? php c l a s s SOAP_Cl i e nt { publ i c $ws dl ; publ i c f unc t i on __c ons t r uc t ( $e ndpoi nt ) { $t hi s - >ws dl = W SDLM a na ge r : : ge t ( $e ndpoi nt ) ; } publ i c f unc t i on __c a l l ( $m e t hod, $a r gs ) { $por t = $t hi s - >ws dl - >ge t Por t For Ope r a t i on( $m e t hod) ; $t hi s - >e ndpoi nt =$t hi s - >ws dl - >ge t Por t Endpoi nt ( $por t ) ; $r e que s t = SOAP_Enve l ope : : r e que s t ( $t hi s - >ws dl ) ; $r e que s t - >a ddM e t hod( $m e t hod, $a r gs ) ; $da t a = $r e que s t - >s a ve XM L( ) ; r e t ur n SOAP_Enve l ope : : pa r s e ( $t hi s - >e ndpoi nt , $da t a ) ; } } ? >
Marcus Börger Objects for the Masses 116
Marcus Börger Objects for the Masses 117
Marcus Börger Objects for the Masses 118
$obs e r ve r s [ ] = $obs e r ve r ;
f or e a c h( $obs e r ve r s a s $o) { i f ( $o === $obs e r ve r ) r e t ur n; } $obs e r ve r s [ ] = $obs e r ve r ;
f or e a c h( $obs e r ve r s a s $k => $o) { i f ( $o === $obs e r ve r ) { uns e t ( $obs e r ve r [ $k] ) ; br e a k; } }
Marcus Börger Objects for the Masses 119
c l a s s Obj e c t St or a ge { pr ot e c t e d $s t or a ge = a r r a y( ) ; f unc t i on a t t a c h( $obj ) { f or e a c h( $t hi s - >s t or a ge a s $o) { i f ( $o === $obj ) r e t ur n; } $t hi s - >s t or a ge [ ] = $obj ; } f unc t i on de t a t c h( $obj ) { f or e a c h( $t hi s - >s t or a ge a s $k => $o) { i f ( $o === $obj ) { uns e t ( $t hi s - >s t or a ge [ $k] ) ; r e t ur n; } } } }
Marcus Börger Objects for the Masses 120
c l a s s Obj e c t St or a ge { pr ot e c t e d $s t or a ge = a r r a y( ) ; f unc t i on a t t a c h( $obj ) { $t hi s - >s t or a ge [ s pl _obj e c t _ha s h( $obj ) ] = $obj ; } f unc t i on de t a t c h( $obj ) { uns e t ( $t hi s - >s t or a ge [ s pl _obj e c t _ha s h( $obj ) ] ) ; } }
Marcus Börger Objects for the Masses 121
c l a s s M ySubj e c t i m pl e m e nt s Subj e c t { pr ot e c t e d $obs e r ve r s ; publ i c f unc t i on __c ons t r uc t ( ) { $t hi s - >obs e r ve r = ne w Obj e c t St or a ge ; } publ i c f unc t i on a t t a c h( Obs e r ve r $o) { $t hi s - >obs e r ve r s - >a t t a c h( $o) ; } publ i c f unc t i on de t a c h( Obs e r ve r $o) { $t hi s - >obs e r ve r s - >de t a c h( $o) ; } publ i c f unc t i on not i f y( ) { f or e a c h( $t hi s - >obs e r ve r s a s $o) $o- >upda t e ( $t hi s ) ; } } c l a s s M yObs e r ve r i m pl e m e nt s Obs e r ve r { publ i c f unc t i on upda t e ( Subj e c t $s ) { / / do l oggi ng or s om e ot he r a c t i on } }
Marcus Börger Objects for the Masses 122
Marcus Börger Objects for the Masses 123
i nt e r f a c e Da t a Ac c e s s e xt e nds Ar r a yAc c e s s { f unc t i on c onne c t ( $c onne c t i on) ; / / f unc t i on of f s e t Ge t ( $of f s e t ) ; / / f unc t i on of f s e t Se t ( $of f s e t , $va l ue ) ; / / f unc t i on of f s e t Exi s t s ( $of f s e t ) ; / / f unc t i on of f s e t Uns e t ( $of f s e t ) ; } / / c l a s s Dba Ac c e s s f r om pa ge 86 a ga i n c l a s s Dba Da t a e xt e nds Dba Ac c e s s i m pl e m e nt s Da t a Ac c e s s { f unc t i on __c ons t r uc t ( ) { pa r e nt : : __c ons t r uc t ( ‘ / de v/ nul l ' , ‘ i ni f i l e ' ) ; } f unc t i on c onne c t ( Ar r a y $c onne c t i on) { $c onne c t i on = s pl i t ( ‘ : ' , $c onne c t i on) ; $t hi s - >db = dba _ope n( $c onne c t i on[ 0] ' c d' , $c onne c t i on[ 1] ) ) } } c l a s s a pp { f unc t i on __c ons t r uc t ( Da t a Ac c e s s $db) { $t hi s - >db = $db; $db- >c onne c t ( ‘ / us r / l oc a l / m yf i l e . db4: db4' ) ; } }
Marcus Börger Objects for the Masses 124
i nt e r f a c e Da t a Ac c e s s e xt e nds Ar r a yAc c e s s { f unc t i on c onne c t ( $c onne c t i on) ; / / f unc t i on of f s e t Ge t ( $of f s e t ) ; / / f unc t i on of f s e t Se t ( $of f s e t , $va l ue ) ; / / f unc t i on of f s e t Exi s t s ( $of f s e t ) ; / / f unc t i on of f s e t Uns e t ( $of f s e t ) ; } / / How a bout s om e t e s t da t a you c a n r e l y on? c l a s s Te s t Da t a e xt e nds Ar r a yObj e c t i m pl e m e nt s Da t a Ac c e s s { f unc t i on c onne c t ( $f i l e na m e ) { $t hi s [ ‘ ke y1’ ] = ‘ va l ue 1’ ; $t hi s [ ‘ ke y2’ ] = ‘ va l ue 2’ ; $t hi s [ ‘ ke y3’ ] = ‘ va l ue 3’ ; $t hi s [ ‘ ke y4’ ] = ‘ va l ue 4’ ; $t hi s [ ‘ ke y5’ ] = ‘ va l ue 5’ ; } } c l a s s a pp { f unc t i on __c ons t r uc t ( Da t a Ac c e s s $db) { $t hi s - >db = $db; $db- >c onne c t ( ‘ / us r / l oc a l / m yf i l e . db4: db4' ) ; } }
Marcus Börger Objects for the Masses 125
php –r ' pr i nt _r ( a r r a y_ke ys ( s pl _c l a s s e s ( ) ) ) ; '
php - - r c <Cl as s >
php - - r f <Func t i on>
php - - r e <Ex t e ns i on>
php - - r i <Ex t e ns i on>
Marcus Börger Objects for the Masses 126