objects for the masses
play

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


  1. A little abstraction 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 om 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 23

  2. A little abstraction 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 om 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 24

  3. PHP & OOP Marcus Börger Objects for the Masses 25

  4. PHP 4 and OOP ? ¤ Poor Object model � Methods � No visibility � No abstracts, no final � Static without declaration � Properties � No static properties � No constants � Inheritance � No abstract, final inheritance, no interfaces � No prototype checking, no types � Object handling � Copied by value � No destructors Marcus Börger Objects for the Masses 26

  5. ZE2's revamped object model � Objects are referenced by identifiers � Constructors and Destructors � Static members � Constants � Visibility � Interfaces � Final and abstract members � Interceptors � Exceptions � Reflection API � Iterators � Namespaces (5.3) � Closures (5.3) . . . Prototypes (5.4/ 6.0/ never?) Marcus Börger Objects for the Masses 27

  6. Revamped Object Model � PHP 5 has really good OOP support � Better code reuse � Better for team development � Easier to refactor � Some patterns lead to much more efficient code � Fits better in marketing scenarios Marcus Börger Objects for the Masses 28

  7. PHP 5 OOP I n Detail Marcus Börger Objects for the Masses 29

  8. Objects referenced by identifiers � Objects are no longer somewhat special arrays � Objects are no longer copied by default � Objects may be copied using clone/ __clone() c l a s s Obj e c t {}; $obj $ref $dup $obj = ne w Obj e c t ( ) ; Instance 1 Instance 2 $r e f = $obj ; $dup = c l one $obj ; Class Object Marcus Börger Objects for the Masses 30

  9. Constructors and Destructors � Constructors/ Destructors control object lifetime � Constructors may have both new OR old style name � New style constructors are preferred � Constructors must not use inherited protocol � Destructors are called when deleting the last reference � No particular or controllable order during shutdown � Destructors cannot have parameters � Since PHP 5.0.1 destructors can work with resources 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 31

  10. Constructors and Destructors � Parents must be called manually 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 32

  11. Default property values � Properties can have default values � Bound to the class not to the object � Default values cannot be changed but overwritten c l a s s Obj e c t { $obj1 $obj2 va r $pr op = " He l l o\ n" ; } Instance 1 Instance 2 $prop $prop $obj 1 = ne w Obj e c t ; $obj 1- >pr op = " He l l o W or l d\ n" ; Class Object $obj 2 = ne w Obj e c t ; $prop/default e c ho $obj 2- >pr op; / / He l l o Marcus Börger Objects for the Masses 33

  12. Static members � Static methods and properties � Bound to the class not to the object � Only exists once per class rather than per instance � Can be initialized $obj1 $obj2 c l a s s Obj e c t { Instance 1 Instance 2 va r $pr op; $prop $prop 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 ; } Class Object } $stat Obj e c t : : t e s t ( ) ; $obj 1 = ne w Obj e c t ; $obj 2 = ne w Obj e c t ; Marcus Börger Objects for the Masses 34

  13. Pseudo constants � shows the current class name __CLASS__ � __M ETH O D__ shows class and method or function � references the class itself s e l f � par e nt references the parent class � $t hi s 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 35

  14. Visibility � Controlling member visibility / Information hiding � A derived class doesn't know parents private m embers � An inherited protected member can be made public c l a s s Ba s e { publ i c $a ; Derived pr ot e c t e d $b; Base pr i vat e $c ; $a } $b c l a s s De r i ve d e xt e nds Ba s e { $c publ i c $a ; publ i c $b; $a pr i vat e $c ; $b } $c Base::$c Marcus Börger Objects for the Masses 36

  15. Constructor visibility � A protected constructor prevents instantiation 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 37

  16. The Singleton pattern � Sometimes you want only a single instance of aclass to ever exist. � DB connections � An object representing the user or connection. 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 38

  17. Constants � Constants are read only static properties � Constants are always public 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 or l d\ n" ; 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 39

  18. Abstract members � Methods can be abstract � They don’t have a body � A class with an abstract method must be abstract � Classes can be made abstract � The class cannot be instantiated � Properties cannot be made abstract 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 40

  19. Final members � Methods can be final � They cannot be overwritten � They are class invariants � Classes can be final � They cannot be inherited 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 41

  20. Different Object same behavior � Often different objects have the same interface without having the same base class 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( ) { Line Ellipse f or e a c h( $t hi s - >l i ne s a s $l i ne) $l i ne - >dr a w( ) ; } } $lines c l a s s Re c t a ngl e e xt e nds Pol ygon { } Circle Polygon 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( ) ; Rectangle } } Marcus Börger Objects for the Masses 42

  21. Interfaces � Interfaces describe an abstract class protocol � Classes may inherit multiple Interfaces i nt e r f a c e Dr a wa bl e { f unc t i on dr a w( ) ; } Drawable 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( ) { Line Ellipse f or e a c h( $t hi s - >l i ne s a s $l i ne) $l i ne - >dr a w( ) ; } } $lines c l a s s Re c t a ngl e e xt e nds Pol ygon { } Circle Polygon 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( ) ; Rectangle } } Marcus Börger Objects for the Masses 43

  22. Property kinds � Declared properties � May have a default value � Can have selected visibility � Implicit public properties � Declared by simply using them in ANY method � Virtual properties � Handled by interceptor methods � Static properties � Bound to the class rather than to the instance Marcus Börger Objects for the Masses 44

  23. Object to String conversion � __toString(): semi-automatic object to string conversion with echo and print (automatic starting with 5.2) 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 45

  24. Interceptors � Allow to dynamically handle non class members � Lazy initialization of properties � Simulating Object aggregation and Multiple inheritance 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 46

  25. Typehinting � PHP 5 allows to easily force a type of a parameter � PHP does not allow NULL for typehints � Typehints must be inherited as given in base class � PHP 5.1 offers typehinting with arrays � PHP 5.2 offers optional typehinted parameters (= NULL) 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 47

  26. Class Design � It is important to think about your class hierarchy � Avoid very deep or broad inheritance graphs � PHP only supports is-a and has-a relations Tires Bicycle Vehicle Engine Car Bus Truck Diesel Gasoline Tank Turbine Plane Marcus Börger Objects for the Masses 48

  27. Too Strict or too Weak? � PHP tries to prevent you from doing some errors � You are bound to keep inherited signatures � You cannot change from ref to non-ref return � Yet PHP allows absolute flexibility � Just do not define a signature � Warning: This is extrem ely error prone Marcus Börger Objects for the Masses 49

  28. Dynam ic Class Loading Marcus Börger Objects for the Masses 50

  29. Dynamic class loading � � __a ut ol oa d( ) is good when you're alone __a ut ol oa d( ) is good � Requires a single file for each class � Only load class files when necessary � No need to parse/ compile unneeded classes � No need to check which class files to load � Additional user space code N Only one single loader model is possible Marcus Börger Objects for the Masses 51

  30. __a ut ol oa d & r e qui r e _onc e � St or e t he c l a s s l oa de r i n a n i nc l ude f i l e � I n e a c h s c r i pt : r e qui r e _onc e ( ' <pa t h>/ a ut ol oa d. i nc ' ) � Us e I NI opt i on: 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 52

  31. SPL's class loading � Supports fast default implementation � Look into path's specified by INI option include_path � Look for specified file extensions (.inc, .php) � Ability to register multiple user defined loaders � Overwrites ZEND engine's __autoload() cache � You need to register __autoload if using spl's autoload <? 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 53

  32. SPL's class loading � s pl _a ut ol oa d( $c l a s s _na m e , $e xt e ns i ons =NULL) Load a class from a file in include path Fast C code implementation � s pl _a ut ol oa d_e xt e ns i ons ( $e xt e ns i ons =NULL) Get or set filename extensions � s pl _a ut ol oa d_r e gi s t e r ( $l oa de r _f unc t i on) Register a single loader function � s pl _a ut ol oa d_unr e gi s t e r ( $l oa de r _f unc t i on) Unregister a single loader function � s pl _a ut ol oa d_f unc t i ons ( ) List all registered loader functions � s pl _a ut ol oa d_c a l l ( $c l a s s _na m e ) Load a class through registered class loaders Uses s pl _a ut ol oa d( ) as fallback Marcus Börger Objects for the Masses 54

  33. Exceptions Marcus Börger Objects for the Masses 55

  34. Exceptions � Respect these rules 1. Exceptions are exceptions 2. Never use exceptions for control flow 3. Never ever use exceptions for param eter passing <? 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 56

  35. Exception specialization � Exceptions should be specialized � Exceptions should inherit built in class exception 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 57

  36. Exception specialization � Exception blocks can be nested � Exceptions can be re thrown 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 58

  37. Practical use of exceptions � Constructor failure � Converting errors/ warnings to exceptions � Simplify error handling � Provide additional error information by tagging Marcus Börger Objects for the Masses 59

  38. Constructor failure � In PHP 4.4 you would simply uns e t ( $t hi s ) � Provide an argument to receive the error condition <? 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 60

  39. Constructor failure � In 5 constructors do not return the created object � Exceptions allow to handle failed constructors <? 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 61

  40. Convert Errors to Exceptions � Implementing PHP 5.1 class ErrorException <? 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 62

  41. Convert Errors to Exceptions � Implementing the error handler <? 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 63

  42. Simplify error handling � Typical database access code contains lots of if's <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 64

  43. Simplify error handling � Trade code simplicity with a new complexity <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 65

  44. SPL Exceptions � SPL provides a standard set of exceptions � Class Exception must be the root of all exceptions Marcus Börger Objects for the Masses 66

  45. General distinguishing � Logi c Exc e pt i on Ł Anything that could have been detected at compile time, during application design or by the good old technology: "look closely" � Runt i m e Exc e pt i on Ł Anything that is unexpected during runtime Ł Base Exception for all database extensions Marcus Börger Objects for the Masses 67

  46. LogicException � Function not found or similar Ba dM e t hodCa l l Exc e pt i on � Value not in allowed domain � Argument not valid � Length exceeded � Some index is out of range Marcus Börger Objects for the Masses 68

  47. RunTimeException � An actual value is out of bounds � Buffer or other overflow situation � Value outside expected range � Buffer or other underflow situation � Any other unexpected values Marcus Börger Objects for the Masses 69

  48. Overloading __call � If using __call, ensure only valid calls are made 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 ) { Compile-Time: $t hi s - >i t = $i t ; } Error in design 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 ) ; } } Marcus Börger Objects for the Masses 70

  49. Interfaces and __call � Interface functions cannot be handled by __call � Either mark the class abstract... 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 { I nt e r f a c e 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 ) f unc t i on r e wi nd( ) ; { f unc t i on va l i d( ) ; $t hi s - >i t = $i t ; f unc t i on c ur r e nt ( ) ; } f unc t i on __c a l l ( $f unc , $a r gs ) f unc t i on ke y( ) ; { f unc t i on ne xt ( ) ; $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 ) ; } } Marcus Börger Objects for the Masses 71

  50. Interfaces and __call � Interface functions cannot be handled by __call � ...or provide the functions (here as proxy/ forward) 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 { I nt e r f a c e 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 ) f unc t i on r e wi nd( ) ; { f unc t i on va l i d( ) ; $t hi s - >i t = $i t ; f unc t i on c ur r e nt ( ) ; } f unc t i on __c a l l ( $f unc , $a r gs ) f unc t i on ke y( ) ; { f unc t i on ne xt ( ) ; $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 ( ) ; } } Marcus Börger Objects for the Masses 72

  51. Expecting formatted data � Opening a file for reading Run-Time: File might not be accessible or exist $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( ) ; Marcus Börger Objects for the Masses 73

  52. Expecting formatted data � Reading a formatted file line by line Run-Time: File might not be accessible or exist $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 ( ) ; Run-Time: } data is different for $da t a [ ] = $l ; every execution } � ! pr e g_m a t c h( $r e ge x, $l ) Une xpe c t Va l ue Exc e pt i on � c ount ( $l =s pl i t ( ' , ' , $l ) ) ! = 3 Ra nge Exc e pt i on � c ount ( $da t a ) > 100 Ove r f l owExc e pt i on Marcus Börger Objects for the Masses 74

  53. Expecting formatted data � Cehcking data after pre-processing Run-Time: Filemight not be accessible or exist $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( ) ; Run-Time: } data is different for $da t a [ ] = $l ; every execution } / / 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 � i f ( c ount ( $da t a ) < 10) t hr ow ne w Unde r f l owExc e pt i on( ) ; � i f ( c ount ( $da t a ) > 99) t hr ow ne w Ove r f l owExc e pt i on( ) ; � i f ( c ount ( $da t a ) < 10 | | c ount ( $da t a ) > 99) t hr ow ne w Out Of Bounds Exc e pt i on( ) ; Marcus Börger Objects for the Masses 75

  54. Expecting formatted data � Processing pre-checked data Run-Time: File might not be accessible or exist $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( ) ; Run-Time: } data is different for $da t a [ ] = $l ; every execution } 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 or e pr e c e s s i ng c ode f or e a c h( $da t a a s & $v) { Compile-Time: i f ( c ount ( $v) == 2) { exception signals t hr ow ne w Dom a i nExc e pt i on( ) ; failed precondition } $v = $v[ 0] * $v[ 1] ; } Marcus Börger Objects for the Masses 76

  55. Reflection Marcus Börger Objects for the Masses 77

  56. Reflection API � Can reflect nearly all aspects of your PHP code � Functions � Classes, Methods, Properties � Extensions 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 78

  57. Dynamic object creation � Reflection allows dynamic object creation 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 79

  58. Built-in I nterfaces Marcus Börger Objects for the Masses 80

  59. Built-in Interfaces � PHP 5 contains built-in interfaces that allow you to change the way the engine treats objects. � Ar r a yAc c e s s � I t e r a t or � I t e r a t or Aggr e ga t e � Built-in extension SPL provides more I nterfaces and Classes � Ar r a yObj e c t , Ar r a yI t e r a t or � Fi l t e r I t e r a t or � Re c ur s i ve I t e r a t or � Use CLI: php - - r e SPL php - - r c Ar r a yAc c e s s Marcus Börger Objects for the Masses 81

  60. ArrayAccess � Allows for creating objects that can be transparently accessed by array syntax. � When combined with the iterator interface, it allows for creating ‘arrays with special properties’. 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 82

  61. ArrayAccess � ArrayAccess does not allow references (the following is an error) 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 & 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 ) { / * . . . */ } } Marcus Börger Objects for the Masses 83

  62. ArrayAccess Example � We want to create variables which can be shared between processes. � We will set up interception so that access attempts on the variable are actually performed through a DBM file. Marcus Börger Objects for the Masses 84

  63. Binding Access to a DBM <? 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 85

  64. A Trivial Example <? 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 86

  65. Iterators � Normal objects behave like arrays when used with the foreach construct � Specialized I terator objects can be iterated differently <? 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 or l d\ n" ; } 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 87

  66. What are Iterators � Iterators are a concept to iterate anything that contains other things. � Iterators allow to encapsulate algorithms Marcus Börger Objects for the Masses 88

  67. What are Iterators � Iterators are a concept to iterate anything that contains other things. Examples: � Values and Keys in an array Ar r a yObj e c t , Ar r a yI t e r a t or � Text lines in a file Spl Fi l e Obj e c t � Files in a directory [ Re c ur s i ve ] Di r e c t or yI t e r a t or � XML Elements or Attributes ext: SimpleXML, DOM � Database query results ext: PDO, SQLite, MySQLi � Dates in a calendar range PECL/ date (?) � Bits in an image ? � Iterators allow to encapsulate algorithms Marcus Börger Objects for the Masses 89

  68. What are Iterators � Iterators are a concept to iterate anything that contains other things. Examples: � Values and Keys in an array Ar r a yObj e c t , Ar r a yI t e r a t or � Text lines in a file Spl Fi l e Obj e c t � Files in a directory [ Re c ur s i ve ] Di r e c t or yI t e r a t or � XML Elements or Attributes ext: SimpleXML, DOM � Database query results ext: PDO, SQLite, MySQLi � Dates in a calendar range PECL/ date (?) � Bits in an image ? � Iterators allow to encapsulate algorithms � Classes and Interfaces provided by SPL: 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 90

  69. Array vs. Iterator � An array in PHP $a r = a r r a y( ) � can be rewound: r e s e t ( $a r ) � is valid unless it's key is NULL: ! i s _nul l ( ke y( $a r ) ) � have current values: c ur r e nt ( $a r ) � have keys: ke y( $a r ) � can be forwarded: ne xt ( $a r ) � Something that is traversable $i t = ne w I t e r a t or ; � m ay know how to be rewound: $i t - >r e wi nd( ) ( doe s not r e t ur n t he e l e m e nt ) � should know if there is a value: $i t - >va l i d( ) � m ay have a current value: $i t - >c ur r e nt ( ) � m ay have a key: $i t - >ke y( ) ( m a y r e t ur n NULL a t a ny t i m e ) � can forward to its next element: $i t - >ne xt () Marcus Börger Objects for the Masses 91

  70. The big difference � Arrays � require memory for all elements � allow to access any element directly � I terators � only know one element at a time � only require mem ory for the current elem ent � forward access only � Access done by m ethod calls � Containers � require memory for all elements � allow to access any element directly � can create external Iterators or are internal Iterators Marcus Börger Objects for the Masses 92

  71. The basic concepts � Iterators can be internal or external also referred to as active or passive � An internal iterator modifies the object itself � An external iterator points to another object without modifying it � PHP always uses external iterators at engine-level � Iterators may iterate over other iterators Marcus Börger Objects for the Masses 93

  72. PHP Iterators � Anything that can be iterated implements Tr ave r s abl e � Objects implementing Tr ave r s abl e can be used in f or e ac h � User classes cannot implement Tr ave r s abl e � I t e r at or Aggr e gat e is for objects that use external iterators � I t e r at or is for internal traversal or external iterators Traversable Iterator IteratorAggregate + rewind () : void + valid () : boolean + current () : mixed + getIterator () : Iterator + key () : mixed + next () : void Marcus Börger Objects for the Masses 94

  73. Implementing Iterators Traversable Iterator IteratorAggregate + rewind () : void + valid () : boolean + getIterator () : Iterator + current () : mixed + key () : mixed + next () : void IteratorImpl AggregateImpl + <<Implement>> rewind () : void + <<Implement>> valid () : boolean + <<Implement>> getIterator () : Iterator + <<Implement>> current () : mixed + <<Implement>> key () : mixed + <<Implement>> next () : void Marcus Börger Objects for the Masses 95

  74. How Iterators work � Iterators can be used manually � Iterators can be used implicitly with foreach <? 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 96

  75. How Iterators work � Internal I terators � User Iterators < ?php interface Iterator { function rewind(); function valid(); function current(); function key(); function next(); } ?> < ?php $it = get_resource(); for ($it-> rewind(); $it-> valid(); $it-> next()) { $value = $it-> current(); $key = $it-> key(); } ?> Marcus Börger Objects for the Masses 97

  76. How Iterators work � Internal I terators � User Iterators < ?php interface Iterator { function rewind(); function valid(); < ?php function current(); $it = get_resource(); function key(); foreach($it as $key= > $val) { function next(); / / access data } } ?> ?> Marcus Börger Objects for the Masses 98

  77. How Iterators work � Internal I terators � User Iterators < ?php class FilterIterator implements Iterator { < ?php function __construct(Iterator $input)... interface Iterator { function rewind()... function rewind(); function accept()... function valid(); function valid()... function current(); function current()... function key(); function key()... function next(); function next()... } } ?> ?> < ?php $it = get_resource(); foreach(new Filter($it, $filter_param) as $key= > $val) { / / access filtered data only } ?> Marcus Börger Objects for the Masses 99

  78. Debug Session <? php <? php PHP 5.1 c l a s s Ar r a yI t er a t or { $a = a r r a y( 1, 2, 3) ; pr ot e c t e d $a r ; $o = ne w Ar r a yI t e r a t or ( $a ) ; f unc t i on __c ons t r uc t ( Ar r a y $ar ) { f or e a c h( $o a s $ke y => $va l ) { $t hi s - >a r = $ar ; e c ho " $ke y => $va \ n" ; } } 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( ) { 0 => 1 r e t ur n ! i s _nul l ( ke y( $t hi s - >a r ) ) ; 1 => 2 } 2 => 3 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 ) ; } } ? > Marcus Börger Objects for the Masses 100

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend