Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Easy HTTP Clients with Guzzle

Easy HTTP Clients with Guzzle

Easily create tailored HTTP clients using the popular PHP library.

Nathaniel McHugh

October 05, 2013
Tweet

More Decks by Nathaniel McHugh

Other Decks in Technology

Transcript

  1. NATHANIEL MCHUGH PHP Developer at Plusnet Live in Sheffield @natmchugh

    PLUSNET ISP based in Sheffield Mixed teams of Java and PHP We're recruiting ™
  2. WHAT IS GUZZLE? A wrapper for CURL A quick way

    to send HTTP requests A framework for creating web service clients A nice way to separate your application logic from the service api Works with real services not just perfect REST ones
  3. TALK DETAIL https://api.joind.in/v2.1/talks/9294? format=json&verbose=yes { " t a l k

    s " : [ { " t a l k _ t i t l e " : " E a s y H T T P C l i e n t s w i t h G u z z l e " , " t a l k _ d e s c r i p t i o n " : " W i t h a p p l i c a t i o n a r c h i t e c t u r e s s u c h a s R E S T i n c r e a s i n g l y m a k i n g u s e o f w e b s e r v i c e s , s e n d i n g H T T P r e q u e s t s f r o m P H P h a s b e c o m e a c o m m o n r e q u i r e m e n t . W i t h t h i s i n m i n d a r e u s a b l e c o m p o n e n t t h a t c a n t a l k H T T P f o r u s h a s b e c o m e a m u s t . \ n \ n O r i g i n a t i n g a s p a r t o f t h e A W S S D K f o r P H P G u z z l e i s a l i b r a r y t h a t h a s b e c o m e a p o p u l a r c h o i c e a n d i s n o w i n t e g r a t e d i n t o s e v e r a l o t h e r p r o j e c t s i n c l u d i n g D r u p a l 8 . W h a t m a k e s G u z z l e s o a t t r a c t i v e f o r d e v e l o p e r s i s a s w e l l a s a c t i n g a s a v e r s a t i l e H T T P C l i e n t i t o f f e r s a f r a m e w o r k t o t a i l o r c l i e n t s t o a p a r t i c u l a r w e b s e r v i c e b y d e s c r i b i n g t h e m i n G u z z l e \ u 2 0 1 9 s o w n D S L . \ n \ n S t a r t i n g w i t h a R E S T l i k e s e r v i c e w e w a n t t o t a l k t o , t h i s t a l k w i l l g o t h r o u g h t h e p r o c e s s o f b u i l d i n g a H T T P c l i e n t t h a t a l l o w s t h e
  4. STARTING A NEW HTTP CLIENT m k d i r

    g u z z l e - j o i n d . i n v i m c o m p o s e r . j s o n { " n a m e " : " g u z z l e - j o i n d - i n " , " t y p e " : " h t t p c l i e n t " , " d e s c r i p t i o n " : " G u z z l e J o i n d . i n A P I c l i e n t " , " k e y w o r d s " : [ " G u z z l e " ] , " r e q u i r e " : { " p h p " : " > = 5 . 3 . 2 " , " g u z z l e / g u z z l e " : " > = 3 . 7 . 0 " , } } p h p c o m p o s e r . p h a r i n s t a l l
  5. STATIC FACADE r e q u i r e _

    o n c e ' v e n d o r / a u t o l o a d . p h p ' ; G u z z l e \ H t t p \ S t a t i c C l i e n t : : m o u n t ( ) ; $ r e s p o n s e = G u z z l e : : g e t ( ' h t t p s : / / a p i . j o i n d . i n / v 2 . 1 / t a l k s / 9 2 9 4 ? f o r m a t = j s o n & v e r b o s e = y e s ' ) ; v a r _ d u m p ( $ r e s p o n s e - > j s o n ( ) ) ; G E T / v 2 . 1 / t a l k s / 9 2 9 4 ? f o r m a t = j s o n & v e r b o s e = y e s H T T P / 1 . 1 H o s t : a p i . j o i n d . i n U s e r - A g e n t : G u z z l e / 3 . 7 . 3 c u r l / 7 . 2 4 . 0 P H P / 5 . 5 . 0
  6. CLIENT OBJECT r e q u i r e _

    o n c e ' v e n d o r / a u t o l o a d . p h p ' ; u s e G u z z l e \ H t t p \ C l i e n t ; $ c l i e n t = n e w C l i e n t ( ' h t t p s : / / a p i . j o i n d . i n / v 2 . 1 / ' ) ; $ r e q u e s t = $ c l i e n t - > g e t ( ' t a l k s / 9 2 9 4 ? f o r m a t = j s o n & v e r b o s e = y e s ' ) ; $ r e s p o n s e = $ r e q u e s t - > s e n d ( ) ; v a r _ d u m p ( $ r e s p o n s e - > j s o n ( ) ) ; G E T / v 2 . 1 / t a l k s / 9 2 9 4 ? f o r m a t = j s o n & v e r b o s e = y e s H T T P / 1 . 1 H o s t : a p i . j o i n d . i n U s e r - A g e n t : G u z z l e / 3 . 7 . 3 c u r l / 7 . 2 4 . 0 P H P / 5 . 5 . 0
  7. EXCEPTIONS t r y { $ r e s p

    o n s e = G u z z l e : : g e t ( ' h t t p : / / e x a m p l e . c o m / n o n - e x i s t a n t - u r l ' ) ; } c a t c h ( G u z z l e \ H t t p \ E x c e p t i o n \ C l i e n t E r r o r R e s p o n s e E x c e p t i o n $ e ) { e c h o ' Y o u r f a u l t : ' . $ e - > g e t M e s s a g e ( ) ; } c a t c h ( G u z z l e \ H t t p \ E x c e p t i o n \ S e r v e r E r r o r R e s p o n s e E x c e p t i o n $ e ) { e c h o ' O u r f a u l t : ' . $ e - > g e t M e s s a g e ( ) ; } c a t c h ( G u z z l e \ H t t p \ E x c e p t i o n \ C u r l E x c e p t i o n $ e ) { e c h o ' I n t e r n e t s j u s t h a t e s u s : ' . $ e - > g e t M e s s a g e ( ) ; } Y o u r f a u l t : C l i e n t e r r o r r e s p o n s e [ s t a t u s c o d e ] 4 0 4 [ r e a s o n p h r a s e ] N o t F o u n d [ u r l ] h t t p : / / e x a m p l e . c o m / n o n - e x i s t a n t - u r l
  8. URI TEMPLATES $ c l i e n t =

    n e w C l i e n t ( ' h t t p : / / t o o l s . i e t f . o r g / ' ) ; $ r e q u e s t = $ c l i e n t - > g e t ( a r r a y ( ' { o u t p u t _ t y p e } / r f c { r f c _ n u m b e r } ' , a r r a y ( ' o u t p u t _ t y p e ' = > ' h t m l ' , ' r f c _ n u m b e r ' = > 6 5 7 0 , ) ) ) ; s t r i n g ( 3 4 ) " h t t p : / / t o o l s . i e t f . o r g / h t m l / r f c 6 5 7 0 "
  9. URI TEMPLATES There's a RFC! 6570 Guzzle has a full

    implementation Guzzle can use pecl uri_template
  10. POST REQUESTS r e q u i r e _

    o n c e ' v e n d o r / a u t o l o a d . p h p ' ; $ c l i e n t = n e w C l i e n t ( ' h t t p s : / / a p i . j o i n d . i n / v 2 . 1 / ' ) ; $ u r l = [ ' / v 2 . 1 / t a l k s / { t a l k _ i d } / c o m m e n t s ' , [ ' t a l k _ i d ' = > 9 2 9 4 ] ] ; $ h e a d e r s = [ ' A u t h o r i z a t i o n ' = > ' O A u t h 6 c 1 9 0 d 0 6 c 5 0 6 8 d 7 b ' ] ; $ p a r a m s = [ ' r a t i n g ' = > 5 , ' c o m m e n t ' = > ' L o v e l y s t u f f ! ' , ] ; $ r e q u e s t = $ c l i e n t - > p o s t ( $ u r l , $ h e a d e r s , $ p a r a m s ) ; P O S T / v 2 . 1 / t a l k s / 9 2 9 4 / c o m m e n t s H T T P / 1 . 1 H o s t : a p i . j o i n d . i n A u t h o r i z a t i o n : O A u t h 6 c 1 9 0 d 0 6 c 5 0 6 8 d 7 b C o n t e n t - T y p e : a p p l i c a t i o n / x - w w w - f o r m - u r l e n c o d e d ; c h a r s e t = u t f - 8 U s e r - A g e n t : G u z z l e / 3 . 7 . 3 c u r l / 7 . 2 4 . 0 P H P / 5 . 5 . 0 r a t i n g = 5 & c o m m e n t = L o v e l y % 2 0 s t u f f % 2 1
  11. SENDING FILES r e q u i r e _

    o n c e ' v e n d o r / a u t o l o a d . p h p ' ; $ c l i e n t = n e w C l i e n t ( ' h t t p s : / / a p i . j o i n d . i n / v 2 . 1 / ' ) ; $ u r l = [ ' / v 2 . 1 / t a l k s / { t a l k _ i d } / c o m m e n t s ' , [ ' t a l k _ i d ' = > 9 2 9 4 ] ] ; $ h e a d e r s = a r r a y ( ) ; $ p a r a m s = a r r a y ( ' f i l e ' = > ' @ / t m p / t e s t _ f i l e ' ) ; $ r e q u e s t = $ c l i e n t - > p o s t ( $ u r l , $ h e a d e r s , $ p a r a m s ) ; e c h o $ r e q u e s t ; P O S T / p o s t H T T P / 1 . 1 H o s t : h t t p b i n . o r g C o n t e n t - T y p e : m u l t i p a r t / f o r m - d a t a E x p e c t : 1 0 0 - C o n t i n u e U s e r - A g e n t : G u z z l e / 3 . 7 . 3 c u r l / 7 . 2 4 . 0 P H P / 5 . 5 . 0
  12. COMMANDS An easy to use object for each action on

    a API $ c o m m a n d = $ c l i e n t - > g e t C o m m a n d ( ' C o m m a n d N a m e ' , $ c o m m a n d P a r a m s ) ; $ r e s u l t = $ c o m m a n d - > e x e c u t e ( ) ; $ r e q u e s t = $ c o m m a n d - > g e t R e q u e s t ( ) ; $ r e s p o n s e = $ c o m m a n d - > g e t R e s p o n s e ( ) ; $ c o m m a n d = $ c l i e n t - > g e t C o m m a n d ( ' G e t U s e r s ' , a r r a y ( ' c o u n t ' = > 5 ) ) ; $ r e s u l t = $ c o m m a n d - > e x e c u t e ( ) ; $ r e s u l t = $ c l i e n t - > G e t U s e r s ( a r r a y ( ' c o u n t ' = > 5 ) ) ;
  13. CONCRETE COMMANDS u s e G u z z l

    e \ S e r v i c e \ C o m m a n d \ A b s t r a c t C o m m a n d ; c l a s s U s e r D e t a i l e x t e n d s A b s t r a c t C o m m a n d { p r o t e c t e d f u n c t i o n b u i l d ( ) { $ p a r a m s = a r r a y ( ' u s e r _ i d ' = > $ t h i s [ ' u s e r _ i d ' ] ) ; $ t h i s - > r e q u e s t = $ t h i s - > c l i e n t - > g e t ( ' v 2 . 1 / u s e r s / { u s e r _ i d } ' , $ p a r a m s ) ; $ q u e r y = $ t h i s - > r e q u e s t - > g e t Q u e r y ( ) ; i f ( $ t h i s [ ' f o r m a t ' ] ) { $ q u e r y - > s e t ( ' f o r m a t ' , $ t h i s [ ' f o r m a t ' ] ) ; } } }
  14. OPERATION COMMANDS u s e G u z z l

    e \ S e r v i c e \ D e s c r i p t i o n \ S e r v i c e D e s c r i p t i o n ; $ d e s c r i p t i o n = S e r v i c e D e s c r i p t i o n : : f a c t o r y ( ' p a t h / t o / j o i n d i n . j s o n ' ) ; $ c l i e n t - > s e t D e s c r i p t i o n ( $ d e s c r i p t i o n ) ; $ r e s u l t = $ c l i e n t - > G e t U s e r s ( a r r a y ( ' c o u n t ' = > 5 ) ) ;
  15. SERVICE DESCRIPTORS Swagger Lite Defines web service APIs by documenting

    operations. Either in form of JSON document or PHP array. Specified by a JSON schema. { " n a m e " : " s t r i n g " , " a p i V e r s i o n " : " s t r i n g | n u m b e r " , " b a s e U r l " : " s t r i n g " , " d e s c r i p t i o n " : " s t r i n g " , " o p e r a t i o n s " : { } , " m o d e l s " : { } , " i n c l u d e s " : [ " s t r i n g . p h p " , " s t r i n g . j s o n " ] }
  16. OPERATIONS h t t p : / / a p

    i . j o i n d . i n / v 2 . 1 / u s e r s / 1 1 8 ? v e r b o s e = y e s & f o r m a t = j s o n { " o p e r a t i o n s " : { " U s e r D e t a i l " : { " h t t p M e t h o d " : " G E T " , " u r i " : " v 2 . 1 / u s e r s / { u s e r _ i d } " , " r e s p o n s e C l a s s " : " U s e r O u t p u t " , " p a r a m e t e r s " : { " f o r m a t " : { " l o c a t i o n " : " q u e r y " , " d e f a u l t " : " j s o n " } , " v e r b o s e " : { " l o c a t i o n " : " q u e r y " , } , " u s e r _ i d " : { " l o c a t i o n " : " u r i " , } } }
  17. RESPONSE MODELS { " m o d e l s

    " : { " U s e r O u t p u t " : { " t y p e " : " o b j e c t " , " p r o p e r t i e s " : { " i d " : { " l o c a t i o n " : " h e a d e r " , " t y p e " : " i n t e g e r " , " s e n t A s " : " u s e r I d " } , " u s e r n a m e " : { " l o c a t i o n " : " j s o n " , " t y p e " : " s t r i n g " , } } } } }
  18. RESPONSE MODELS n a m e s p a c

    e G u z z l e \ J o i n d I n ; u s e G u z z l e \ S e r v i c e \ C o m m a n d \ R e s p o n s e C l a s s I n t e r f a c e ; u s e G u z z l e \ S e r v i c e \ C o m m a n d \ O p e r a t i o n C o m m a n d ; c l a s s U s e r i m p l e m e n t s R e s p o n s e C l a s s I n t e r f a c e { p u b l i c s t a t i c f u n c t i o n f r o m C o m m a n d ( O p e r a t i o n C o m m a n d $ c o m m a n d ) { $ r e s p o n s e = $ c o m m a n d - > g e t R e s p o n s e ( ) ; $ u s e r D a t a = c u r r e n t ( c u r r e n t ( $ r e s p o n s e - > j s o n ( ) ) ) ; r e t u r n n e w s e l f ( $ u s e r D a t a ) ; } p u b l i c f u n c t i o n _ _ c o n s t r u c t ( A r r a y $ u s e r D a t a ) { p r e g _ m a t c h ( ' / ( [ \ d ] + ) $ / ' , $ u s e r D a t a [ ' u r i ' ] , $ m a t c h e s ) ; $ t h i s - > i d = $ m a t c h e s [ 0 ] ; }
  19. WHAT CAN YOU UNIT TEST IN A HTTP CLIENT? Is

    the request generated correctly i.e. url and headers? Are responses handled correclty including failure?
  20. TESTING A REQUEST u s e G u z z

    l e \ T e s t s \ G u z z l e T e s t C a s e ; u s e G u z z l e \ J o i n d I n \ J o i n d I n C l i e n t ; u s e G u z z l e \ S e r v i c e \ D e s c r i p t i o n \ S e r v i c e D e s c r i p t i o n ; c l a s s U s e r D e t a i l T e s t s e x t e n d s G u z z l e T e s t C a s e { p u b l i c f u n c t i o n t e s t U s e r D e t a i l T e s t R e q u e s t ( ) { $ c l i e n t = n e w J o i n d I n C l i e n t ( ) ; $ p a r a m s = [ ' u s e r _ i d ' = > 7 9 3 ] ; $ c o m m a n d = $ c l i e n t - > g e t C o m m a n d ( ' U s e r D e t a i l ' , $ p a r a m s ) ; $ t h i s - > s e t M o c k R e s p o n s e ( $ c l i e n t , ' u s e r . d e t a i l ' ) ; $ r e s p o n s e = $ c l i e n t - > e x e c u t e ( $ c o m m a n d ) ; $ t h i s - > a s s e r t C o n t a i n s ( ' a p i . j o i n d . i n / v 2 . 1 / u s e r s / 7 9 3 ? v e r b o s e = y e s & f o r m a t = j s o n ' , $ c o m m a n d - > g e t R e q u e s t ( ) - > g e t U r l ( ) ) ; } }
  21. MOCK RESPONSE H T T P / 1 . 1

    2 0 0 O K D a t e : W e d , 0 1 A p r 2 0 1 3 1 2 : 0 0 : 0 0 G M T C o n n e c t i o n : c l o s e S e r v e r : A p a c h e C o n t e n t - T y p e : a p p l i c a t i o n / j s o n { " u s e r s " : [ { " u s e r n a m e " : " n a t m c h u g h " , " f u l l _ n a m e " : " N a t h a n i e l M c H u g h " , " t w i t t e r _ u s e r n a m e " : n u l l , " l a s t _ l o g i n " : 1 3 6 5 6 9 6 7 0 3 , " u r i " : " h t t p : / / t e s t . a p i . j o i n d . i n / v 2 . 1 / u s e r s / 7 9 3 " , c u r l - i h t t p : / / a p i . d e v . j o i n d . i n : 8 0 8 0 / v 2 . 1 / u s e r s / 7 9 3
  22. TESTING THE RESPONSE c l a s s U s

    e r D e t a i l T e s t s e x t e n d s G u z z l e T e s t C a s e { p u b l i c f u n c t i o n t e s t U s e r D e t a i l T e s t R e s p o n s e ( ) { $ c l i e n t = n e w J o i n d I n C l i e n t ( ) ; $ p a r a m s = [ ' u s e r _ i d ' = > 7 9 3 ] ; $ t h i s - > s e t M o c k R e s p o n s e ( $ c l i e n t , ' u s e r . d e t a i l ' ) ; $ r e s p o n s e = $ c l i e n t - > U s e r D e t a i l s ( $ p a r a m s ) ; $ u s e r s = $ r e s p o n s e [ ' u s e r s ' ] ; $ u s e r = a r r a y _ p o p ( $ u s e r s ) ; $ t h i s - > a s s e r t S a m e ( " N a t h a n i e l M c H u g h " , $ u s e r [ ' f u l l _ n a m e ' ] ) ; } }
  23. PUTTING IT ALL TOGETHER ├ ─ ─ c o m

    p o s e r . j s o n ├ ─ ─ s r c │ └ ─ ─ J o i n d I n │ ├ ─ ─ J o i n d I n C l i e n t . p h p │ └ ─ ─ c l i e n t . j s o n ├ ─ ─ t e s t s │ │ └ ─ ─ J o i n d I n │ │ └ ─ ─ T e s t s │ │ └ ─ ─ C o m m a n d │ │ └ ─ ─ U s e r D e t a i l T e s t . p h p │ ├ ─ ─ J o i n d I n C l i e n t T e s t . p h p │ └ ─ ─ m o c k │ └ ─ ─ u s e r . d e t a i l
  24. CONSTRUCTOR n a m e s p a c e

    G u z z l e \ J o i n d I n ; u s e G u z z l e \ C o m m o n \ C o l l e c t i o n ; u s e G u z z l e \ S e r v i c e \ C l i e n t ; u s e G u z z l e \ S e r v i c e \ D e s c r i p t i o n \ S e r v i c e D e s c r i p t i o n ; c l a s s J o i n d I n C l i e n t e x t e n d s C l i e n t { p u b l i c f u n c t i o n _ _ c o n s t r u c t ( $ b a s e U r l = ' ' , $ c o n f i g = a r r a y ( ) ) { $ c o n f i g = C o l l e c t i o n : : f r o m C o n f i g ( $ c o n f i g , a r r a y ( ) , a r r a y ( ) ) ; p a r e n t : : _ _ c o n s t r u c t ( $ b a s e U r l , $ c o n f i g ) ; $ d e s c r i p t i o n = S e r v i c e D e s c r i p t i o n : : f a c t o r y ( _ _ D I R _ _ . ' / c l i e n t . j s o n ' ) ; $ t h i s - > s e t D e s c r i p t i o n ( $ d e s c r i p t i o n ) ; } }
  25. USING YOUR NEW CLIENT r e q u i r

    e _ _ D I R _ _ . ' / . . / v e n d o r / a u t o l o a d . p h p ' ; u s e G u z z l e \ J o i n d I n \ J o i n d I n C l i e n t ; $ c l i e n t = n e w J o i n d I n C l i e n t ( ) ; $ u s e r s = $ c l i e n t - > U s e r D e t a i l ( a r r a y ( ' u s e r _ i d ' = > 7 9 3 ) ) ; e c h o $ u s e r s ;
  26. = = = = = = = = = =

    = = = = = = = = = = = D e b u g o u t p u t o f m o d e l = = = = = = = = = = = = = = = = = = = = = M o d e l d a t a - - - - - - - - - - - T h i s d a t a c a n b e r e t r i e v e d f r o m t h e m o d e l o b j e c t u s i n g t h e g e t ( ) m e t h o d o f t h e m o d e l ( e . g . $ m o d e l - > g e t ( $ k e y ) ) o r a c c e s s i n g t h e m o d e l l i k e a n a s s o c i a t i v e a r r a y ( e . g . $ m o d e l [ ' k e y ' ] ) . [ u s e r s ] = > A r r a y ( [ 0 ] = > A r r a y ( [ u s e r n a m e ] = > n a t m c h u g h [ f u l l _ n a m e ] = > N a t h a n i e l M c H u g h [ t w i t t e r _ u s e r n a m e ] = > [ u r i ] = > h t t p : / / a p i . j o i n d . i n / v 2 . 1 / u s e r s / 7 9 3 [ v e r b o s e _ u r i ] = > h t t p : / / a p i . j o i n d . i n / v 2 . 1 / u s e r s / 7 9 3 ? v e r b o s e = y e s [ w e b s i t e _ u r i ] = > h t t p : / / j o i n d . i n / u s e r / v i e w / 7 9 3 [ t a l k s _ u r i ] = > h t t p : / / a p i . j o i n d . i n / v 2 . 1 / u s e r s / 7 9 3 / t a l k s / [ a t t e n d e d _ e v e n t s _ u r i ] = > h t t p : / / a p i . j o i n d . i n / v 2 . 1 / u s e r s / 7 9 3 / a t t e n d e d / ) ) [ m e t a ] = > A r r a y ( [ c o u n t ] = > 1 [ t h i s _ p a g e ] = > h t t p : / / a p i . j o i n d . i n / v 2 . 1 / u s e r s / 7 9 3 ? s t a r t = 0 & r e s u l t s p e r
  27. (OTHER) PLUGINS Mock plugin HTTP Cache plugin Async plugin Backoff

    retry plugin Cookie plugin History plugin Log plugin MD5 validator plugin OAuth plugin
  28. USING A PLUGIN u s e G u z z

    l e \ H t t p \ C l i e n t ; u s e D o c t r i n e \ C o m m o n \ C a c h e \ F i l e s y s t e m C a c h e ; u s e G u z z l e \ C a c h e \ D o c t r i n e C a c h e A d a p t e r ; u s e G u z z l e \ P l u g i n \ C a c h e \ C a c h e P l u g i n ; u s e G u z z l e \ P l u g i n \ C a c h e \ D e f a u l t C a c h e S t o r a g e ; $ c l i e n t = n e w C l i e n t ( ' h t t p : / / j o i n d . i n ' ) ; $ c a c h e P l u g i n = n e w C a c h e P l u g i n ( a r r a y ( ' s t o r a g e ' = > n e w D e f a u l t C a c h e S t o r a g e ( n e w D o c t r i n e C a c h e A d a p t e r ( n e w F i l e s y s t e m C a c h e ( ' / p a t h / t o / c a c h e / f i l e s ' ) ) ) ) ) ; $ c l i e n t - > a d d S u b s c r i b e r ( $ c a c h e P l u g i n ) ; $ c l i e n t - > g e t ( ' / ' ) - > s e n d ( ) ; / / I f w e g e t a 3 0 4 r e s p o n s e s e r v e d f r o m f i l e s y s t e m $ c l i e n t - > g e t ( ' / ' ) - > s e n d ( ) ;
  29. CREATING PLUGINS EVENTS u s e S y m f

    o n y \ C o m p o n e n t \ E v e n t D i s p a t c h e r \ E v e n t S u b s c r i b e r I n t e r f a c e ; c l a s s E c h o P l u g i n i m p l e m e n t s E v e n t S u b s c r i b e r I n t e r f a c e { p u b l i c s t a t i c f u n c t i o n g e t S u b s c r i b e d E v e n t s ( ) { r e t u r n a r r a y ( ' r e q u e s t . b e f o r e _ s e n d ' = > ' o n B e f o r e S e n d ' ) ; } p u b l i c f u n c t i o n o n B e f o r e S e n d ( G u z z l e \ C o m m o n \ E v e n t $ e v e n t ) { e c h o ' A b o u t t o s e n d a r e q u e s t : ' . $ e v e n t [ ' r e q u e s t ' ] ; } }
  30. COOL STUFF PARALLEL REQUESTS r e q u i r

    e _ _ D I R _ _ . ' / v e n d o r / a u t o l o a d . p h p ' ; u s e G u z z l e \ J o i n d I n \ J o i n d I n C l i e n t ; $ c l i e n t = n e w J o i n d I n C l i e n t ( ) ; $ o p C o m m a n d s = a r r a y ( $ c l i e n t - > g e t C o m m a n d ( ' U s e r D e t a i l ' , a r r a y ( ' u s e r _ i d ' = > 1 ) ) , $ c l i e n t - > g e t C o m m a n d ( ' U s e r D e t a i l ' , a r r a y ( ' u s e r _ i d ' = > 2 ) ) , $ c l i e n t - > g e t C o m m a n d ( ' U s e r D e t a i l ' , a r r a y ( ' u s e r _ i d ' = > 3 ) ) , ) ; $ c o m m a n d s = $ c l i e n t - > e x e c u t e ( $ o p C o m m a n d s ) ; f o r e a c h ( $ c o m m a n d s a s $ c o m m a n d ) { $ u s e r = $ c o m m a n d - > g e t R e s p o n s e ( ) - > j s o n ( ) ; v a r _ d u m p ( $ u s e r [ ' u s e r s ' ] [ 0 ] ) ; }
  31. STREAMS $ r e s p o n s e

    = G u z z l e : : g e t ( $ t a l k U R I ) ; $ b o d y = $ r e s p o n s e - > g e t B o d y ( ) ; v a r _ d u m p ( g e t _ c l a s s ( $ b o d y ) ) ; $ s t r e a m = $ b o d y - > g e t S t r e a m ( ) ; s t r e a m _ f i l t e r _ a p p e n d ( $ s t r e a m , ' s t r i n g . t o u p p e r ' ) ; $ b o d y - > r e w i n d ( ) ; v a r _ d u m p ( $ b o d y - > r e a d ( 5 0 ) ) ; s t r i n g ( 2 2 ) " G u z z l e \ H t t p \ E n t i t y B o d y " s t r i n g ( 5 0 ) " { " T A L K S " : [ { " T A L K _ T I T L E " : " E A S Y H T T P C L I E N T S W I T H G U "
  32. FINALLY … IF YOU ARE A CRIMINAL MASTERMIND $ c

    l i e n t = n e w G u z z l e \ H t t p \ C l i e n t ( ' h t t p : / / j h i w j j l q p y a w m p j x . o n i o n / ' , a r r a y ( ' c u r l . o p t i o n s ' = > a r r a y ( ' C U R L O P T _ S S L _ V E R I F Y H O S T ' = > f a l s e , ' C U R L O P T _ S S L _ V E R I F Y P E E R ' = > f a l s e , ' C U R L O P T _ P R O X Y ' = > ' h t t p : / / 1 2 7 . 0 . 0 . 1 : 9 0 5 0 / ' , ' C U R L O P T _ P R O X Y T Y P E ' = > 7 , ) ) ) ;