Aspect Oriented Programming in PHP

Aspect Oriented Programming in PHP

AOP is a programming paradigm that aims to separate supporting functionality from the business logic. In this talk I'll explain in more detail what AOP is, how we can apply it in PHP, and what kind of solutions are currently available.

Link to Go! AOP: http://go.aopphp.com/
Link to PHP-AOP: http://pecl.php.net/package/AOP

6cb44ef5130d89b22582aa680aab4268?s=128

Frank van den Brink

June 14, 2013
Tweet

Transcript

  1. 8.

    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; } }
  2. 10.

    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
  3. 11.

    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
  4. 12.

    Intertwined code is hard to understand because of the above

    lack of abstraction. Source: Separation of Concerns - Hürsch, Lopes - 1995
  5. 13.

    Commingled code is hard to maintain and modify because the

    concerns are strongly coupled. Source: Separation of Concerns - Hürsch, Lopes - 1995
  6. 14.

    The intertwined code gives rise to inheritance anomalies due to

    the strong coupling of different concerns. Source: Separation of Concerns - Hürsch, Lopes - 1995
  7. 15.

    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
  8. 16.

    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; } }
  9. 20.
  10. 22.

    class Awesome { } 89 50 4e 47 0d 0a

    1a fe c3 1b 6c 88 COMPILER
  11. 24.

    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!'); } } }
  12. 25.

    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!'); } }
  13. 26.

    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; } }
  14. 28.
  15. 29.
  16. 44.
  17. 45.
  18. 46.
  19. 47.
  20. 48.
  21. 58.
  22. 60.
  23. 69.

    class LoggingAspect implements Aspect { /** * @After("execution(public SecretService->getSecret(*))") */

    public function logAfterGetSecret(MethodInvocation $invocation) { $args = $invocation->getArguments(); $this->logger->info('Secret ' . $args[0] . ' accessed!'); } }
  24. 70.

    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; } }