Annotating with Annotations - ForumPHP 2012
Upcoming SlideShare
Loading in...5
×
 

Annotating with Annotations - ForumPHP 2012

on

  • 12,841 views

What exactly are annotations? How can they change the way you code and make life simpler? Annotations allow you to implement new functionality into code using "notes" this allows you to easily ...

What exactly are annotations? How can they change the way you code and make life simpler? Annotations allow you to implement new functionality into code using "notes" this allows you to easily maintain your own architecture but benefit from external tools. Let's look at how annotations are used today in PHP and how we can develop our own solutions based on the existing libraries.

Statistics

Views

Total Views
12,841
Views on SlideShare
10,708
Embed Views
2,133

Actions

Likes
1
Downloads
18
Comments
0

8 Embeds 2,133

http://www.lafermeduweb.net 2041
http://protalk.me 70
http://blog.jetbrains.com 13
http://m.lafermeduweb.net 3
http://us-w1.rockmelt.com 2
http://www.php-talks.com 2
http://pigeindexermau 1
http://pigeindexeroff2 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Annotating with Annotations - ForumPHP 2012 Annotating with Annotations - ForumPHP 2012 Presentation Transcript

    • *
    •   Forum
    •   PHP
    •   Paris
    •   2012Annotating
    •   with
    •    Annotations A
    •   look
    •   into
    •   Annotations
    •   in
    •   PHP on
    •   twitter Rafael
    •   Dohms @rdohms
    • Rafael Dohms photo credit: Eli White @rdohms Evangelist, Speaker and Contributor. Podcaster, User Group Leader.Developer at WEBclusive.
    • a
    •   little
    •   history existing
    •   uses What? Why? Where? How? ustom
    •   ann otations Impl ementing
    •   c DMSFilter based
    •   on
    •    show
    •   me
    •   the
    •   code!
    • http://ecdesignrebels.blogspot.com w h a t? ta tio ns? re 
    •   an noW ha t
    •   a
    • -- In English --"An annotation is a note that is made while reading any form of text."
    • something
    •   that
    •   describes
    •   an
    •   aspect
    •   of
    •   the
    •   subject -- In English --"An annotation is a note that is made while reading any form of text."
    • -- In Code Speak --“An annotation describes behavior of code and affects your application in runtime.” “Annotations do not directly affect program semantics”
    • -- In Code Speak --“An annotation describes behavior of code and affects your application in runtime.” “Annotations do not directly affect program semantics” just
    •   like
    •   your
    •   notes
    • In
    •   2004:
    •   Metadata
    •   or
    •   “General
    •   purpose
    •   Annotations”
    • In
    •   2004:
    •   Metadata
    •   or
    •   “General
    •   purpose
    •   Annotations” available
    •   at
    •   Runtime
    •   using
    •   Reflection
    • In
    •   2004:
    •   Metadata
    •   or
    •   “General
    •   purpose
    •   Annotations” @Entity @Table(name = "people") class Person implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @Column(length = 32) private String name; available
    •   at
    •   Runtime
    •   using
    •   Reflection
    • In
    •   2004:
    •   Metadata
    •   or
    •   “General
    •   purpose
    •   Annotations” specific
    •   syntax @Entity @Table(name = "people") class Person implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @Column(length = 32) private String name; available
    •   at
    •   Runtime
    •   using
    •   Reflection
    • No
    •   core
    •   annotation
    •   support
    • Questions?
    • Questions?I’m
    •   kidding!
    • phpDoc~2000
    • PHP
    •   5.1 Reflection
    •   supports
    •    getDocComments()phpDoc~2000 2005
    • PHP
    •   5.1 Reflection
    •   supports
    •    getDocComments()phpDoc~2000 2005 First
    •    Annotation
    •   Engines
    •   in
    •   PHP
    • PHP
    •   5.1 Reflection
    •   supports
    •    getDocComments()phpDoc~2000 2005 2008 First
    •    Annotation
    •   Engines
    •   in
    •   PHP
    • PHP
    •   5.1 Reflection
    •   supports
    •    getDocComments()phpDoc~2000 2005 2008 First
    •    Doctrine
    •   2
    •    Annotation Annotation
    •   Engine
    •   Engines
    •   in
    •   PHP
    • PHP
    •   5.1 Reflection
    •   supports
    •    getDocComments() RFC:
    •   Annotations
    •    in
    •   core
    •   w/
    •   custom
    •   phpDoc syntax~2000 2005 2008 2010 First
    •    Doctrine
    •   2
    •    Annotation Annotation
    •   Engine
    •   Engines
    •   in
    •   PHP
    • PHP
    •   5.1 Reflection
    •   supports
    •    getDocComments() RFC:
    •   Annotations
    •    ED CTustom
    •    in
    •   core
    •   JE/
    •   c wphpDoc E Rsyntax~2000 2005 2008 2010 First
    •    Doctrine
    •   2
    •    Annotation Annotation
    •   Engine
    •   Engines
    •   in
    •   PHP
    • PHP
    •   5.1 RFC:
    •   DocBlock
    •    Reflection
    •   supports
    •    Annotations getDocComments() “in
    •   discussion” RFC:
    •   Annotations
    •    ED CTustom
    •    in
    •   core
    •   JE/
    •   c wphpDoc E Rsyntax~2000 2005 2008 2010 2011 First
    •    Doctrine
    •   2
    •    Annotation Annotation
    •   Engine
    •   Engines
    •   in
    •   PHP
    • PHP
    •   5.1 RFC:
    •   DocBlock
    •    Reflection
    •   supports
    •    Annotations getDocComments() “in
    •   discussion” RFC:
    •   Annotations
    •    ED CTustom
    •    in
    •   core
    •   JE/
    •   c wphpDoc E Rsyntax~2000 2005 2008 2010 2011 ? First
    •    Doctrine
    •   2
    •    Annotation Annotation
    •   Engine
    •   Engines
    •   in
    •   PHP
    • PHP
    •   5.1 RFC:
    •   DocBlock
    •    Reflection
    •   supports
    •    Annotations getDocComments() /** * CaasBundleFundingBundleEntityReward “in
    •   discussion” * RFC:
    •   Annotations
    •    ED * @ORMTable("reward") CTustom
    •    * @ORMEntity(repositoryClass="CaasBundleFundingBundleEntityRewardRepository") */ class Reward in
    •   core
    •   JE/
    •   c w E {phpDoc /** Rsyntax ? * @var integer $id * * @ORMColumn(name="id", type="integer") * @ORMId * @ORMGeneratedValue(strategy="AUTO")~2000 */ protected $id; 2005 2008 2010 2011 /** * @var string $title * * @ORMColumn(name="title", type="string", length=150, nullable=true) * First
    •    * @AssertMaxLength(150) */ protected $title; Doctrine
    •   2
    •    Annotation Annotation
    •   Engine
    •   Engines
    •   in
    •   PHP
    • Note:
    • Note://
    •   This
    •   is
    •   a
    •   comment T_COMMENT/*
    •   This
    •   is
    •   a
    •   multiline
    •   comment
    •   */
    • Note://
    •   This
    •   is
    •   a
    •   comment T_COMMENT/*
    •   This
    •   is
    •   a
    •   multiline
    •   comment
    •   *//**
    •   
    •   *
    •   This
    •   is
    •   a
    •   doc
    •   block T_DOC_COMMENT
    •   */
    • /** * @deprecated * * @ORMColumn(‘string’, length=255) */public function method()
    • marker/** * @deprecated * * @ORMColumn(‘string’, length=255) */public function method()
    • marker parameterized/** * @deprecated * * @ORMColumn(‘string’, length=255) */public function method()
    • http://ecdesignrebels.blogspot.com Wh y ? 
    •   an no tatio ns? uld 
    •   I
    •    use /co ns? hy 
    •    sho e
    •   p rosW t
    •    are 
    •   th w ha
    • -
    • Harder
    •   to
    •   debug
    •   (dynamic
    •   code)-
    • Harder
    •   to
    •   debug
    •   (dynamic
    •   code)- Performance
    •   hit
    •   (non-native
    •   code)
    • Harder
    •   to
    •   debug
    •   (dynamic
    •   code)- Performance
    •   hit
    •   (non-native
    •   code) Its
    •   implemented
    •   in
    •   comments
    •   docblocks!
    • +
    • Easier
    •   to
    •   inject
    •   behavior
    •   without
    •   extending+
    • Easier
    •   to
    •   inject
    •   behavior
    •   without
    •   extending Doctrine
    •   1
    •   vs
    •   Doctrine
    •   2+
    • Easier
    •   to
    •   inject
    •   behavior
    •   without
    •   extending Doctrine
    •   1
    •   vs
    •   Doctrine
    •   2 Contextualizes
    •   behavior/config
    •   in
    •   the
    •   object+
    • Easier
    •   to
    •   inject
    •   behavior
    •   without
    •   extending Doctrine
    •   1
    •   vs
    •   Doctrine
    •   2 Contextualizes
    •   behavior/config
    •   in
    •   the
    •   object+ In
    •   object
    •   vs.
    •   external
    •   configuration
    •   file
    • Easier
    •   to
    •   inject
    •   behavior
    •   without
    •   extending Doctrine
    •   1
    •   vs
    •   Doctrine
    •   2 Contextualizes
    •   behavior/config
    •   in
    •   the
    •   object+ In
    •   object
    •   vs.
    •   external
    •   configuration
    •   file Its
    •   documented/stored
    •   by
    •   phpDocumentor
    • Easier
    •   to
    •   inject
    •   behavior
    •   without
    •   extending Doctrine
    •   1
    •   vs
    •   Doctrine
    •   2 Contextualizes
    •   behavior/config
    •   in
    •   the
    •   object+ In
    •   object
    •   vs.
    •   external
    •   configuration
    •   file Its
    •   documented/stored
    •   by
    •   phpDocumentor Its
    •   in
    •   docblocks,
    •   so
    •   its
    •   parsed
    • <?phpclass User{ protected $name ...}
    • <?php -
    •   persist
    •   as
    •   varchar length
    •   should
    •   not
    •   be
    •   class User{ -
    •    more
    •   then
    •   255 -
    •   should
    •   not
    •   be
    •   blank -
    •   only
    •   letters protected $name ...}
    • persistence DoctrineTestsORMMappingUser: type: entity table: cms_users<?php id: id: -
    •   persist
    •   as
    •   varchar type: integer length
    •   should
    •   not
    •   be
    •   class User generator:{ -
    •    strategy: AUTO more
    •   then
    •   255 fields: name: -
    •   should
    •   not
    •   be
    •   blank type: string -
    •   only
    •   letters length: 255 protected $name Validation AcmeBlogBundleEntityAuthor: properties: name: ... - NotBlank: ~ - MaxLength: 255 filter AcmeBlogBundleEntityAuthor:} filters: name: - alpha
    • persistence Validation<?phpclass User filter{ /** * @ORMColumn(‘string’, length=255) * @AssertNotBlank() * @AssertMaxLength(255) * @FilterAlpha() */ protected $name ...}
    • ? http://ecdesignrebels.blogspot.comW h e r e tions 
    •   used? 
    •   ann ota er e
    •    areWh
    • class DataTest extends PHPUnit_Framework_TestCase{ /** * @dataProvider provider repetition * * @expectedException InvalidArgumentException * @expectedExceptionMessage Right Message */ public function testAdd($a, $b, $c) expectations { /* Test code */ } public function provider() { return array( array(0, 0, 0), ); }}
    • /** * @ORMTable("myentity") * @ORMEntity(repositoryClass="MyEntityRepository") */class MyEntity{ /** * @var integer $id * * @ORMColumn(name="id", type="integer") * @ORMId * @ORMGeneratedValue(strategy="AUTO") persistance */ protected $id; /** * @var string $title * * @ORMColumn(name="title", type="string", length=255) association * @AssertMaxLength(255) * @AssertNotBlank() */ protected $title; /** * @var DoctrineCommonCollectionsArrayCollection $users * * @ORMOneToMany(targetEntity="OtherEntity", mappedBy="myEntity", cascade={"persist","remove"}) */ protected $otherEntities;}
    • /** * @Route("/myaction/{id}", name="myaction") * @Method("POST") * * @Template("MyBundle:MyController:my.html.twig") * * @param int $id * @return array routing */public function myAction($id){ /* Controller Logic */ templating return array(data => $data);}class MyEntity{ /** * @var string $title * * @ORMColumn(name="title", type="string", length=255) * @AssertMaxLength(255) * @AssertNotBlank() */ protected $title;} Validation
    • /** Dependency
    •   Injection * @FLOW3Aspect */class LoggingAspect { /** * @FLOW3Inject * @var ExamplesForumLoggerApplicationLoggerInterface AOP */ protected $applicationLogger; /** * Log a message if a post is deleted * * @param TYPO3FLOW3AOPJoinPointInterface $joinPoint * @FLOW3Before("method(ExamplesForumDomainModelForum->deletePost())") * @return void */ public function logDeletePost(TYPO3FLOW3AOPJoinPointInterface $joinPoint) { $post = $joinPoint->getMethodArgument(post); $this->applicationLogger->log(Removing post . $post->getTitle(), LOG_INFO); }}
    • http://ecdesignrebels.blogspot.comH o w ? e
    •    my 
    •   ow n
    •    rit 
    •   i
    •   w ns?How
    •    can tio a nno ta
    • My
    •   ProjectAnnotations
    • Annotation
    •    Engine My
    •   ProjectAnnotations
    • /** * @tag parameters */public function method() Code
    • /**ReflectionClass->getDocComment() * @tag parameters */ public function method() Code
    • /** ReflectionClass->getDocComment() * @tag parameters */ public function method() Code/** * @tag parameters */DOCBlock
    • /** ReflectionClass->getDocComment() * @tag parameters */ public function method() Code/** * @tag parameters */DOCBlock
    • /** ReflectionClass->getDocComment() * @tag parameters */ public function method() Code/** * @tag parameters */DOCBlock Tag() + parameters Annotation
    •   Instances
    • Annotation EnginesDoctrine
    •   CommonsZF2
    •   AnnotationsphpDocumentor
    •   2 abandoned?Notoj php-annotations addendum Stubble
    • Annotation Engines Notoj 2.3 2.0
    •   -
    •   alpha ?Parameterized marker parameterizedvery
    •   mature maturing new
    • Annotation Engines Notoj 2.3 2.0
    •   -
    •   alpha ?Parameterized marker parameterizedvery
    •   mature maturing new
    • How
    •   it
    •   Works <?php use DoctrineORMMapping as ORM; use SymfonyComponentValidator Constraints as Assert; /** * @ORMColumn(‘string’) * @AssertNotBlank() */
    • How
    •   it
    •   Works Declare
    •   which
    •   Annotations
    •    you
    •   will
    •   use <?php use DoctrineORMMapping as ORM; use SymfonyComponentValidator Constraints as Assert; /** * @ORMColumn(‘string’) * @AssertNotBlank() */
    • How
    •   it
    •   Works Declare
    •   which
    •   Annotations
    •    you
    •   will
    •   useAnnotationReader <?php use DoctrineORMMapping as ORM; use SymfonyComponentValidator Constraints as Assert; /** * @ORMColumn(‘string’) * @AssertNotBlank() */
    • How
    •   it
    •   Works Declare
    •   which
    •   Annotations
    •    you
    •   will
    •   useAnnotationReader <?php use DoctrineORMMapping as ORM; use SymfonyComponentValidator Constraints as Assert; /** * @ORMColumn(‘string’) * @AssertNotBlank() “metadata” */new ORMColumn(‘string’)new AssertNotBlank()
    • How
    •   it
    •   Works Declare
    •   which
    •   Annotations
    •    you
    •   will
    •   useAnnotationReader <?php use DoctrineORMMapping as ORM; use SymfonyComponentValidator Constraints as Assert; /** * @ORMColumn(‘string’) * @AssertNotBlank() “metadata” */new ORMColumn(‘string’)new AssertNotBlank() Walker
    •   /
    •   code Cache
    • DMSFilterhttps://github.com/rdohms/DMS
    • The
    •   Gears
    • The
    •   Gears YourApp DoctrineCommons
    • The
    •   Gears Reader YourApp DoctrineCommons
    • The
    •   Gears Parsing Reader YourApp DoctrineCommons
    • The
    •   Gears Parsing Filter Reader YourApp DoctrineCommons
    • The
    •   Gears “Enforcing” Parsing Filter Reader YourApp DoctrineCommons
    • The
    •   Gears “Enforcing” Parsing Filter ReaderAnnotatedObject YourApp DoctrineCommons
    • The
    •   Gears “Enforcing” Parsing Filter ReaderAnnotatedObject MyAnnotation YourApp DoctrineCommons
    • The
    •   Gears “Enforcing” Parsing Filter ReaderAnnotatedObject filter() MyAnnotation YourApp DoctrineCommons
    • The
    •   Gears “Enforcing” Parsing Filter ReaderAnnotatedObject filter() getMethodAnnotation() MyAnnotation YourApp DoctrineCommons
    • The
    •   Gears “Enforcing” Parsing Filter ReaderAnnotatedObject filter() getMethodAnnotation() MyAnnotation YourApp DoctrineCommons
    • The
    •   Gears “Enforcing” Parsing Filter ReaderAnnotatedObject filter() getMethodAnnotation() filtered value MyAnnotation YourApp DoctrineCommons
    • Usage:
    •   @FilterNoDogs()namespace FilterRule;/** * @Annotation */class NoDogs{ public function __construct($options) { /* no options */ } public function filter($value) { return str_replace("dogs", "", (string) $value); }}
    • Usage:
    •   @FilterNoDogs()namespace FilterRule;/** * @Annotation tell
    •   doctrine
    •   this
    •    */class NoDogs is
    •   an
    •   annotation{ public function __construct($options) { /* no options */ } public function filter($value) { return str_replace("dogs", "", (string) $value); }}
    • Usage:
    •   @FilterNoDogs()namespace FilterRule;/** * @Annotation tell
    •   doctrine
    •   this
    •    */class NoDogs is
    •   an
    •   annotation{ public function __construct($options) { /* no options */ } array
    •   of
    •   the
    •   parameters public function filter($value) { return str_replace("dogs", "", (string) $value); }}
    • Usage:
    •   @FilterNoDogs()namespace FilterRule;/** * @Annotation tell
    •   doctrine
    •   this
    •    */class NoDogs is
    •   an
    •   annotation{ public function __construct($options) { /* no options */ } array
    •   of
    •   the
    •   parameters public function filter($value) { return str_replace("dogs", "", (string) $value); }} this
    •   is
    •   the
    •   effect
    •   of
    •    our
    •   annotation
    • namespace Filter;class Filter{ private $reader; public function __construct(DoctrineCommonAnnotationsReader $reader) { $this->reader = $reader; } public function filter($object) { $reflectionObject = new ReflectionObject($object); foreach ($reflectionObject->getProperties() as $reflectionProperty) { $this->filterProperty($object, $reflectionProperty); } } public function filterProperty($object, $reflectionProperty) { // fetch the @NoDog annotation from the annotation reader $annotation = $this->reader->getMethodAnnotation( $reflectionProperty, FilterRuleNoDog); if (null !== $annotation) { return; } $reflectionProperty->setAccessible(true); $value = $reflectionProperty->getValue($object); $filteredValue = $annotation->filter($value); $reflectionProperty->setValue( $filteredValue ); }}
    • namespace Filter;class Filter{ private $reader; public function __construct(DoctrineCommonAnnotationsReader $reader) { $this->reader = $reader; } public function filter($object) { $reflectionObject = new ReflectionObject($object); foreach ($reflectionObject->getProperties() as $reflectionProperty) { $this->filterProperty($object, $reflectionProperty); } } Get
    •   only
    •   our
    •    annotation public function filterProperty($object, $reflectionProperty) { // fetch the @NoDog annotation from the annotation reader $annotation = $this->reader->getMethodAnnotation( $reflectionProperty, FilterRuleNoDog); if (null !== $annotation) { return; } $reflectionProperty->setAccessible(true); $value = $reflectionProperty->getValue($object); $filteredValue = $annotation->filter($value); $reflectionProperty->setValue( $filteredValue ); }}
    • namespace Filter;class Filter{ private $reader; public function __construct(DoctrineCommonAnnotationsReader $reader) { $this->reader = $reader; } public function filter($object) { $reflectionObject = new ReflectionObject($object); foreach ($reflectionObject->getProperties() as $reflectionProperty) { $this->filterProperty($object, $reflectionProperty); } } Get
    •   only
    •   our
    •    annotation public function filterProperty($object, $reflectionProperty) { // fetch the @NoDog annotation from the annotation reader $annotation = $this->reader->getMethodAnnotation( $reflectionProperty, FilterRuleNoDog); if (null !== $annotation) { return; } $reflectionProperty->setAccessible(true); $value = $reflectionProperty->getValue($object); Make
    •   Annotation
    •    $filteredValue = $annotation->filter($value); $reflectionProperty->setValue( $filteredValue );} } affect
    •   application
    • Taking
    •   it
    •   up
    •   a
    •   notch
    • Taking
    •   it
    •   up
    •   a
    •   notch Filter Reader
    • Taking
    •   it
    •   up
    •   a
    •   notch Filter Reader Walker Loader
    • Taking
    •   it
    •   up
    •   a
    •   notch Filter Parsing Using/Walking Reader Walker Loading Loader
    • Taking
    •   it
    •   up
    •   a
    •   notch Filter Parsing Using/Walking Reader Walker Loading Loader Filters
    •   Annotations
    • Taking
    •   it
    •   up
    •   a
    •   notch Filter Parsing Using/Walking Reader Walker Loading Loader navigates
    •   object,
    •    Filters
    •   Annotations reflects
    •   and
    •   filters
    • Taking
    •   it
    •   up
    •   a
    •   notch Filter Parsing Using/Walking Reader Walker Loading Loader navigates
    •   object,
    •    Filters
    •   Annotations reflects
    •   and
    •   filters
    • Taking
    •   it
    •   up
    •   a
    •   notch Filter Parsing Using/Walking Reader Walker Loading Loader annotations navigates
    •   object,
    •    Filters
    •   Annotations reflects
    •   and
    •   filters
    • Taking
    •   it
    •   up
    •   a
    •   notch Filter Parsing Using/Walking Reader Walker Loading Loader annotations metadata navigates
    •   object,
    •    Filters
    •   Annotations reflects
    •   and
    •   filters
    • /** * @MyAnnotation(“name”, nullable=true) */
    • defaultProperty/** * @MyAnnotation(“name”, nullable=true) */
    • defaultProperty/** * @MyAnnotation(“name”, nullable=true) */new MyAnnotation($options);
    • defaultProperty/** * @MyAnnotation(“name”, nullable=true) */ array:
    •   key
    •   =>
    •   value or string:
    •   valuenew MyAnnotation($options);
    • defaultProperty/** * @MyAnnotation(“name”, nullable=true) */ array:
    •   key
    •   =>
    •   value or string:
    •   valuenew MyAnnotation($options); or
    • defaultProperty/** * @MyAnnotation(“name”, nullable=true) */ array:
    •   key
    •   =>
    •   value or string:
    •   valuenew MyAnnotation($options); or$a = new MyAnnotation();$a->nullable = true;$a->{$a->getDefaultProperty()} = “name”;
    • DMSFilter https://github.com/rdohms/DMS/** * FilterAlpha(true) */ Rafael
    •   Dohms23protected $name; Alpha->filter($name); Rafael
    •   Dohms
    • What? Why? Where? How?
    • Questions?
    • Thank You! please! Rate
    •   this
    •   talk
    •   on
    •   Joind.in! https://joind.in/6437on
    •   twitter @rdohms these
    •   slides
    •    will
    •   be
    •   here http://doh.ms http://slides.doh.ms