Slide 1

Slide 1 text

ASPECT ORIENTED PROGRAMMING IN PHP I’m Frank van den Brink. I’m a Pragmatist. @fvdb

Slide 2

Slide 2 text

TODAY’S AGENDA

Slide 3

Slide 3 text

THE ORIGINS

Slide 4

Slide 4 text

THE ORIGINS HOW IT WORKS

Slide 5

Slide 5 text

THE ORIGINS HOW IT WORKS USING IT IN PHP

Slide 6

Slide 6 text

THE ORIGINS

Slide 7

Slide 7 text

Source: http://siliconvalley.sutromedia.com/xerox-parc.html

Slide 8

Slide 8 text

class SecretService { public function getSecret($id) { // Check access if (!$this->isAllowedToAccess($id)) { throw new AccessDeniedException('You cannot do this!'); } // Get the secret $secret = $this->storage->getById($id); // Log that someone’s fetching the secret $this->logger->info('Secret accessed!'); return $secret; } }

Slide 9

Slide 9 text

SEPARATION OF CONCERNS Hürsch, Lopes - 1995

Slide 10

Slide 10 text

Programming intertwined code is hard and complex since all concerns have to be dealt with at the same time and at the same level. Source: Separation of Concerns - Hürsch, Lopes - 1995

Slide 11

Slide 11 text

Programming intertwined code is hard and complex since all concerns have to be dealt with at the same time and at the same level. The extended programming language provides no adequate abstraction of concerns at the implementation level. Source: Separation of Concerns - Hürsch, Lopes - 1995

Slide 12

Slide 12 text

Intertwined code is hard to understand because of the above lack of abstraction. Source: Separation of Concerns - Hürsch, Lopes - 1995

Slide 13

Slide 13 text

Commingled code is hard to maintain and modify because the concerns are strongly coupled. Source: Separation of Concerns - Hürsch, Lopes - 1995

Slide 14

Slide 14 text

The intertwined code gives rise to inheritance anomalies due to the strong coupling of different concerns. Source: Separation of Concerns - Hürsch, Lopes - 1995

Slide 15

Slide 15 text

The intertwined code gives rise to inheritance anomalies due to the strong coupling of different concerns. It becomes impossible to redefine a method implementation or the commingled special concern in a subclass without redefining both. Source: Separation of Concerns - Hürsch, Lopes - 1995

Slide 16

Slide 16 text

class SecretService { public function getSecret($id) { // Check access if (!$this->isAllowedToAccess($id)) { throw new AccessDeniedException('You cannot do this!'); } // Get the secret $secret = $this->storage->getById($id); // Log that someone’s fetching the secret $this->logger->info('Secret accessed!'); return $secret; } }

Slide 17

Slide 17 text

class SecretService { public function getSecret($id) { return $this->storage->getById($id); } }

Slide 18

Slide 18 text

META-LEVEL PROGRAMMING ADAPTIVE PROGRAMMING COMPOSITION FILTERS

Slide 19

Slide 19 text

RG AML ETCML DJ DJAVA

Slide 20

Slide 20 text

AspectJ

Slide 21

Slide 21 text

HOW IT WORKS

Slide 22

Slide 22 text

class Awesome { } 89 50 4e 47 0d 0a 1a fe c3 1b 6c 88 COMPILER

Slide 23

Slide 23 text

class SecretService { public function getSecret($id) { return $this->storage->getById($id); } }

Slide 24

Slide 24 text

class SecretService { public function getSecret($id) { return $this->storage->getById($id); } } class AuthorizationAspect { public function checkAccessBeforeGetSecret($id) { if (!$this->isAllowedToAccess($id)) { throw new AccessDeniedException('You cannot do this!'); } } }

Slide 25

Slide 25 text

class SecretService { public function getSecret($id) { return $this->storage->getById($id); } } class AuthorizationAspect { public function checkAccessBeforeGetSecret($id) { if (!$this->isAllowedToAccess($id)) { throw new AccessDeniedException('You cannot do this!'); } } } class LoggingAspect { public function logAfterGetSecret($id) { $this->logger->info('Secret accessed!'); } }

Slide 26

Slide 26 text

class SecretService { public function getSecret($id) { // Check access if (!$this->isAllowedToAccess($id)) { throw new AccessDeniedException('You cannot do this!'); } // Get the secret $secret = $this->storage->getById($id); // Log that someone’s fetching the secret $this->logger->info('Secret accessed!'); return $secret; } }

Slide 27

Slide 27 text

CROSS CUTTING CONCERN

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

CROSS CUTTING CONCERN

Slide 31

Slide 31 text

CROSS CUTTING CONCERN ASPECTS

Slide 32

Slide 32 text

CROSS CUTTING CONCERN ASPECTS ADVICE

Slide 33

Slide 33 text

class LoggingAspect { public function logAfterGetSecret($id) { $this->logger->info('Secret accessed!'); } }

Slide 34

Slide 34 text

CROSS CUTTING CONCERN ASPECTS ADVICE

Slide 35

Slide 35 text

CROSS CUTTING CONCERN ASPECTS ADVICE JOIN POINTS

Slide 36

Slide 36 text

class SecretService { public function getSecret($id) { return $this->storage->getById($id); } } BEFORE METHOD CALL

Slide 37

Slide 37 text

class SecretService { public function getSecret($id) { return $this->storage->getById($id); } } AFTER METHOD CALL

Slide 38

Slide 38 text

class SecretService { public function getSecret($id) { return $this->storage->getById($id); } } AROUND METHOD CALL

Slide 39

Slide 39 text

CROSS CUTTING CONCERN ASPECTS ADVICE JOIN POINTS

Slide 40

Slide 40 text

CROSS CUTTING CONCERN ASPECTS ADVICE JOIN POINTS POINT CUTS

Slide 41

Slide 41 text

Before( execution( public SecretService->*(*) ) )

Slide 42

Slide 42 text

CROSS CUTTING CONCERN ASPECTS ADVICE JOIN POINTS POINT CUTS

Slide 43

Slide 43 text

CROSS CUTTING CONCERN ASPECTS ADVICE JOIN POINTS POINT CUTS WEAVING

Slide 44

Slide 44 text

WEAVING

Slide 45

Slide 45 text

WEAVING

Slide 46

Slide 46 text

WEAVING

Slide 47

Slide 47 text

WEAVING

Slide 48

Slide 48 text

WEAVING

Slide 49

Slide 49 text

CROSS CUTTING CONCERN ASPECTS ADVICE JOIN POINTS POINT CUTS WEAVING

Slide 50

Slide 50 text

USING IT IN PHP

Slide 51

Slide 51 text

CAN YOU USE IT IN PHP?

Slide 52

Slide 52 text

X X X X X O O O O

Slide 53

Slide 53 text

X X X X X O O O O O

Slide 54

Slide 54 text

AOP-PHP Flow AOP Go! AOP JMSAopBundle

Slide 55

Slide 55 text

AOP-PHP Flow AOP Go! AOP JMSAopBundle ext lib lib lib

Slide 56

Slide 56 text

AOP-PHP Flow AOP Go! AOP JMSAopBundle ext lib lib lib

Slide 57

Slide 57 text

AOP-PHP Flow AOP Go! AOP JMSAopBundle ext lib lib lib

Slide 58

Slide 58 text

AOP-PHP

Slide 59

Slide 59 text

function logAfterGetSecret() { $this->logger->info('Secret accessed!'); } aop_add_after( 'SecretService->getSecret()', 'logAfterGetSecret' );

Slide 60

Slide 60 text

Go! AOP

Slide 61

Slide 61 text

new Example\Foobar Autoloader Weaver

Slide 62

Slide 62 text

new Example\Foobar Autoloader Weaver

Slide 63

Slide 63 text

new Example\Foobar Autoloader Weaver

Slide 64

Slide 64 text

new Example\Foobar Autoloader Weaver

Slide 65

Slide 65 text

new Example\Foobar Autoloader Weaver

Slide 66

Slide 66 text

new Example\Foobar Autoloader Weaver

Slide 67

Slide 67 text

new Example\Foobar Autoloader Weaver

Slide 68

Slide 68 text

new Example\Foobar Autoloader Weaver

Slide 69

Slide 69 text

class LoggingAspect implements Aspect { /** * @After("execution(public SecretService->getSecret(*))") */ public function logAfterGetSecret(MethodInvocation $invocation) { $args = $invocation->getArguments(); $this->logger->info('Secret ' . $args[0] . ' accessed!'); } }

Slide 70

Slide 70 text

class CachingAspect implements Aspect { /** * @Around("execution(public SecretService->getSecret(*))") */ public function cacheGetSecret(MethodInvocation $invocation) { $args = $invocation->getArguments(); if ($this->cache->has($args[0])) { return $this->cache->get($args[0]); } $secret = $invocation->proceed(); $this->cache->set($args[0], $secret); return $secret; } }

Slide 71

Slide 71 text

SHOULD YOU USE AOP?

Slide 72

Slide 72 text

PERFORMANCE

Slide 73

Slide 73 text

PERFORMANCE CLARITY

Slide 74

Slide 74 text

PERFORMANCE CLARITY DON’T GO NUTS

Slide 75

Slide 75 text

AOP ALL THE THINGS!

Slide 76

Slide 76 text

MERCI BIEN @fvdb http://about.me/fvdb http://speakerdeck.com/u/fvdb