• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Annotating with Annotations
 

Annotating with Annotations

on

  • 5,036 views

Annotations are more than phpdoc comments, they're a fully-featured way of including additional information alongside your code. We might have rejected an RFC to add support into the PHP core, but ...

Annotations are more than phpdoc comments, they're a fully-featured way of including additional information alongside your code. We might have rejected an RFC to add support into the PHP core, but the community has embraced this tool anyway! This session shows you who is doing what with annotations, and will give you some ideas on how to use the existing tools in your own projects to keep life simple. Developers, architects and anyone responsible for the technical direction of an application should attend this session.

Statistics

Views

Total Views
5,036
Views on SlideShare
4,993
Embed Views
43

Actions

Likes
11
Downloads
199
Comments
0

10 Embeds 43

http://blog.jetbrains.com 18
http://lanyrd.com 8
http://www.php-talks.com 4
http://beta.codiki.com 4
https://twitter.com 4
http://twitter.com 1
http://www.onlydoo.com 1
https://courseinfo.livingstone.edu 1
https://my.berkeleycollege.edu 1
http://ampliatrademarketing.com.br 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

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
  • \n
  • \n
  • \n
  • \n
  • \n
  • Overview of how annotations are just descriptions of static resources. Like HTML syntax can describe text with bold, italic\n
  • Overview of how annotations are just descriptions of static resources. Like HTML syntax can describe text with bold, italic\n
  • phpDoc vs. Annotation: docs do not have influence in how a app runs.\nAnnotation by itself does not “act” its used to be acted on by another class.\n\nJust putting an annotation is not going to work, you need someone to act on it.\n
  • phpDoc vs. Annotation: docs do not have influence in how a app runs.\nAnnotation by itself does not “act” its used to be acted on by another class.\n\nJust putting an annotation is not going to work, you need someone to act on it.\n
  • Java: annotations since 2004, same syntax for javadocs and annotations\nRuntime uses reflection to read annnotations\nJavadoc Vs. Annotations: same as PHPDoc mentioned before\n
  • Java: annotations since 2004, same syntax for javadocs and annotations\nRuntime uses reflection to read annnotations\nJavadoc Vs. Annotations: same as PHPDoc mentioned before\n
  • Java: annotations since 2004, same syntax for javadocs and annotations\nRuntime uses reflection to read annnotations\nJavadoc Vs. Annotations: same as PHPDoc mentioned before\n
  • Java: annotations since 2004, same syntax for javadocs and annotations\nRuntime uses reflection to read annnotations\nJavadoc Vs. Annotations: same as PHPDoc mentioned before\n
  • Java: annotations since 2004, same syntax for javadocs and annotations\nRuntime uses reflection to read annnotations\nJavadoc Vs. Annotations: same as PHPDoc mentioned before\n
  • Java: annotations since 2004, same syntax for javadocs and annotations\nRuntime uses reflection to read annnotations\nJavadoc Vs. Annotations: same as PHPDoc mentioned before\n
  • Java: annotations since 2004, same syntax for javadocs and annotations\nRuntime uses reflection to read annnotations\nJavadoc Vs. Annotations: same as PHPDoc mentioned before\n
  • PHP has no support for Annotations.\n
  • PHP has no support for Annotations.\n
  • Pretend its the end of the talk.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Mentions stubbles and other engines.\nTie in D2 Annotation Engine and Gulherme as the author of both.\n
  • Make a note that PHP does have a custom token for DOCBLOCKS so annotations are not in “documents” and docblocks are even stored in opcode caches.\n
  • Make a note that PHP does have a custom token for DOCBLOCKS so annotations are not in “documents” and docblocks are even stored in opcode caches.\n
  • Make a note that PHP does have a custom token for DOCBLOCKS so annotations are not in “documents” and docblocks are even stored in opcode caches.\n
  • Make a note that PHP does have a custom token for DOCBLOCKS so annotations are not in “documents” and docblocks are even stored in opcode caches.\n
  • Make a note that PHP does have a custom token for DOCBLOCKS so annotations are not in “documents” and docblocks are even stored in opcode caches.\n
  • Diferentiate between Marker Type and Parametrized type\n\nParameterized has more details and complex syntax , marker has no content or simple string syntax\n
  • Diferentiate between Marker Type and Parametrized type\n\nParameterized has more details and complex syntax , marker has no content or simple string syntax\n
  • Diferentiate between Marker Type and Parametrized type\n\nParameterized has more details and complex syntax , marker has no content or simple string syntax\n
  • Diferentiate between Marker Type and Parametrized type\n\nParameterized has more details and complex syntax , marker has no content or simple string syntax\n
  • \n
  • T_DOC_COMMENTS since PHP 5.3 - APC support\n\nDebugging is harder but really a problem.\nPerformance is much better with cache\n\nTesting: can be done by feeding annotation “action” service with populated entities for example\n
  • T_DOC_COMMENTS since PHP 5.3 - APC support\n\nDebugging is harder but really a problem.\nPerformance is much better with cache\n\nTesting: can be done by feeding annotation “action” service with populated entities for example\n
  • T_DOC_COMMENTS since PHP 5.3 - APC support\n\nDebugging is harder but really a problem.\nPerformance is much better with cache\n\nTesting: can be done by feeding annotation “action” service with populated entities for example\n
  • Pros:\n- Compare D1 to D2, you no longer need to extend an object to have persistence behaviour\n- 1 config file with 1000 objects vs. 1000 objects with all their own config\n
  • Pros:\n- Compare D1 to D2, you no longer need to extend an object to have persistence behaviour\n- 1 config file with 1000 objects vs. 1000 objects with all their own config\n
  • Pros:\n- Compare D1 to D2, you no longer need to extend an object to have persistence behaviour\n- 1 config file with 1000 objects vs. 1000 objects with all their own config\n
  • Pros:\n- Compare D1 to D2, you no longer need to extend an object to have persistence behaviour\n- 1 config file with 1000 objects vs. 1000 objects with all their own config\n
  • Pros:\n- Compare D1 to D2, you no longer need to extend an object to have persistence behaviour\n- 1 config file with 1000 objects vs. 1000 objects with all their own config\n
  • Pros:\n- Compare D1 to D2, you no longer need to extend an object to have persistence behaviour\n- 1 config file with 1000 objects vs. 1000 objects with all their own config\n
  • \n
  • \n
  • \n
  • So imagine you are planning a new entity, your mind usually puts a post it on it with all this information\nYou would then have to put persistance in one config, validation in another...\n\nNote how all validations rules are now in a single place.\nEasier to maintain, since its easier to analyse all aspects\n
  • So imagine you are planning a new entity, your mind usually puts a post it on it with all this information\nYou would then have to put persistance in one config, validation in another...\n\nNote how all validations rules are now in a single place.\nEasier to maintain, since its easier to analyse all aspects\n
  • So imagine you are planning a new entity, your mind usually puts a post it on it with all this information\nYou would then have to put persistance in one config, validation in another...\n\nNote how all validations rules are now in a single place.\nEasier to maintain, since its easier to analyse all aspects\n
  • So imagine you are planning a new entity, your mind usually puts a post it on it with all this information\nYou would then have to put persistance in one config, validation in another...\n\nNote how all validations rules are now in a single place.\nEasier to maintain, since its easier to analyse all aspects\n
  • So imagine you are planning a new entity, your mind usually puts a post it on it with all this information\nYou would then have to put persistance in one config, validation in another...\n\nNote how all validations rules are now in a single place.\nEasier to maintain, since its easier to analyse all aspects\n
  • So imagine you are planning a new entity, your mind usually puts a post it on it with all this information\nYou would then have to put persistance in one config, validation in another...\n\nNote how all validations rules are now in a single place.\nEasier to maintain, since its easier to analyse all aspects\n
  • So imagine you are planning a new entity, your mind usually puts a post it on it with all this information\nYou would then have to put persistance in one config, validation in another...\n\nNote how all validations rules are now in a single place.\nEasier to maintain, since its easier to analyse all aspects\n
  • So imagine you are planning a new entity, your mind usually puts a post it on it with all this information\nYou would then have to put persistance in one config, validation in another...\n\nNote how all validations rules are now in a single place.\nEasier to maintain, since its easier to analyse all aspects\n
  • So imagine you are planning a new entity, your imnd usually puts a post it on it with all this information\nYou would then have to put persistance in one config, validation in another...\n\nNote how all validations rules are now in a single place.\nEasier to maintain, since its easier to analyse all aspects\n
  • \n
  • Common uses for annotations in PHP\n\nPersistence, grouping, routing, docs, validation, filtering, expectations, API Generation\n
  • phpDoc uses just marker annotations which arguably are not annotations\nPHPUnit uses it for a long time\nnew frameworks have their own engines and D2 was Hibernate based.\n
  • Example from PHPUnit\n
  • Example from D2\n
  • Example from SF2\n
  • Example in Typo3\n
  • \n
  • So what do you need to have annotations in you application?\n
  • So what do you need to have annotations in you application?\n
  • So what do you need to have annotations in you application?\n
  • How annotations (text) become actual rules/objects.\nReflection to read, and annotation engine to parse and instantiate.\nNOTE: from here another service will use these annotations to “act” upon the code.\n
  • How annotations (text) become actual rules/objects.\nReflection to read, and annotation engine to parse and instantiate.\nNOTE: from here another service will use these annotations to “act” upon the code.\n
  • How annotations (text) become actual rules/objects.\nReflection to read, and annotation engine to parse and instantiate.\nNOTE: from here another service will use these annotations to “act” upon the code.\n
  • How annotations (text) become actual rules/objects.\nReflection to read, and annotation engine to parse and instantiate.\nNOTE: from here another service will use these annotations to “act” upon the code.\n
  • How annotations (text) become actual rules/objects.\nReflection to read, and annotation engine to parse and instantiate.\nNOTE: from here another service will use these annotations to “act” upon the code.\n
  • How annotations (text) become actual rules/objects.\nReflection to read, and annotation engine to parse and instantiate.\nNOTE: from here another service will use these annotations to “act” upon the code.\n
  • How annotations (text) become actual rules/objects.\nReflection to read, and annotation engine to parse and instantiate.\nNOTE: from here another service will use these annotations to “act” upon the code.\n
  • How annotations (text) become actual rules/objects.\nReflection to read, and annotation engine to parse and instantiate.\nNOTE: from here another service will use these annotations to “act” upon the code.\n
  • How annotations (text) become actual rules/objects.\nReflection to read, and annotation engine to parse and instantiate.\nNOTE: from here another service will use these annotations to “act” upon the code.\n
  • How annotations (text) become actual rules/objects.\nReflection to read, and annotation engine to parse and instantiate.\nNOTE: from here another service will use these annotations to “act” upon the code.\n
  • How annotations (text) become actual rules/objects.\nReflection to read, and annotation engine to parse and instantiate.\nNOTE: from here another service will use these annotations to “act” upon the code.\n
  • How annotations (text) become actual rules/objects.\nReflection to read, and annotation engine to parse and instantiate.\nNOTE: from here another service will use these annotations to “act” upon the code.\n
  • How annotations (text) become actual rules/objects.\nReflection to read, and annotation engine to parse and instantiate.\nNOTE: from here another service will use these annotations to “act” upon the code.\n
  • Some of the engines out there.\nZF2 has no docs or use yet.\nNotoj by Cesar Rodas is very new\nphpDocumentor has a new engine\nphp-annotations by Rasmus Schultz\n\n\nSome were abandoned along the way\n
  • No dependencies on any\nNotoj is very “microPHP”\nReming people of parameterized vs. marker\n\nD2 is the best support right now. With caching and the whole load\n
  • How the D2 Engine works .. a high overview.\nThe Reader gets the data from the class which is the parsed by the lexer and finally becomes instances. Which are cached and passed in the format of Metadata classes to your walker/action class\n\n
  • How the D2 Engine works .. a high overview.\nThe Reader gets the data from the class which is the parsed by the lexer and finally becomes instances. Which are cached and passed in the format of Metadata classes to your walker/action class\n\n
  • How the D2 Engine works .. a high overview.\nThe Reader gets the data from the class which is the parsed by the lexer and finally becomes instances. Which are cached and passed in the format of Metadata classes to your walker/action class\n\n
  • How the D2 Engine works .. a high overview.\nThe Reader gets the data from the class which is the parsed by the lexer and finally becomes instances. Which are cached and passed in the format of Metadata classes to your walker/action class\n\n
  • How the D2 Engine works .. a high overview.\nThe Reader gets the data from the class which is the parsed by the lexer and finally becomes instances. Which are cached and passed in the format of Metadata classes to your walker/action class\n\n
  • How the D2 Engine works .. a high overview.\nThe Reader gets the data from the class which is the parsed by the lexer and finally becomes instances. Which are cached and passed in the format of Metadata classes to your walker/action class\n\n
  • How the D2 Engine works .. a high overview.\nThe Reader gets the data from the class which is the parsed by the lexer and finally becomes instances. Which are cached and passed in the format of Metadata classes to your walker/action class\n\n
  • How the D2 Engine works .. a high overview.\nThe Reader gets the data from the class which is the parsed by the lexer and finally becomes instances. Which are cached and passed in the format of Metadata classes to your walker/action class\n\n
  • How the D2 Engine works .. a high overview.\nThe Reader gets the data from the class which is the parsed by the lexer and finally becomes instances. Which are cached and passed in the format of Metadata classes to your walker/action class\n\n
  • How the D2 Engine works .. a high overview.\nThe Reader gets the data from the class which is the parsed by the lexer and finally becomes instances. Which are cached and passed in the format of Metadata classes to your walker/action class\n\n
  • How the D2 Engine works .. a high overview.\nThe Reader gets the data from the class which is the parsed by the lexer and finally becomes instances. Which are cached and passed in the format of Metadata classes to your walker/action class\n\n
  • All examples are going to be from DMS\\Filter\n
  • All you really need is to implement a “Annotation” class and a Enforcer, a class that will be able to get an annotation and know what to do. i.e. call the “filterValue” method with the value from the object and replace the original value with the clean one.\n
  • All you really need is to implement a “Annotation” class and a Enforcer, a class that will be able to get an annotation and know what to do. i.e. call the “filterValue” method with the value from the object and replace the original value with the clean one.\n
  • All you really need is to implement a “Annotation” class and a Enforcer, a class that will be able to get an annotation and know what to do. i.e. call the “filterValue” method with the value from the object and replace the original value with the clean one.\n
  • All you really need is to implement a “Annotation” class and a Enforcer, a class that will be able to get an annotation and know what to do. i.e. call the “filterValue” method with the value from the object and replace the original value with the clean one.\n
  • All you really need is to implement a “Annotation” class and a Enforcer, a class that will be able to get an annotation and know what to do. i.e. call the “filterValue” method with the value from the object and replace the original value with the clean one.\n
  • All you really need is to implement a “Annotation” class and a Enforcer, a class that will be able to get an annotation and know what to do. i.e. call the “filterValue” method with the value from the object and replace the original value with the clean one.\n
  • All you really need is to implement a “Annotation” class and a Enforcer, a class that will be able to get an annotation and know what to do. i.e. call the “filterValue” method with the value from the object and replace the original value with the clean one.\n
  • All you really need is to implement a “Annotation” class and a Enforcer, a class that will be able to get an annotation and know what to do. i.e. call the “filterValue” method with the value from the object and replace the original value with the clean one.\n
  • All you really need is to implement a “Annotation” class and a Enforcer, a class that will be able to get an annotation and know what to do. i.e. call the “filterValue” method with the value from the object and replace the original value with the clean one.\n
  • All you really need is to implement a “Annotation” class and a Enforcer, a class that will be able to get an annotation and know what to do. i.e. call the “filterValue” method with the value from the object and replace the original value with the clean one.\n
  • All you really need is to implement a “Annotation” class and a Enforcer, a class that will be able to get an annotation and know what to do. i.e. call the “filterValue” method with the value from the object and replace the original value with the clean one.\n
  • All you really need is to implement a “Annotation” class and a Enforcer, a class that will be able to get an annotation and know what to do. i.e. call the “filterValue” method with the value from the object and replace the original value with the clean one.\n
  • All you really need is to implement a “Annotation” class and a Enforcer, a class that will be able to get an annotation and know what to do. i.e. call the “filterValue” method with the value from the object and replace the original value with the clean one.\n
  • All you really need is to implement a “Annotation” class and a Enforcer, a class that will be able to get an annotation and know what to do. i.e. call the “filterValue” method with the value from the object and replace the original value with the clean one.\n
  • All you really need is to implement a “Annotation” class and a Enforcer, a class that will be able to get an annotation and know what to do. i.e. call the “filterValue” method with the value from the object and replace the original value with the clean one.\n
  • All you really need is to implement a “Annotation” class and a Enforcer, a class that will be able to get an annotation and know what to do. i.e. call the “filterValue” method with the value from the object and replace the original value with the clean one.\n
  • Simple Annotation that needs no parameters (made simple on purpose)\nMention that parameters come in an array but we will explain later\nShow method of “action” in this case just a filter, could be any action or data\n
  • Simple Annotation that needs no parameters (made simple on purpose)\nMention that parameters come in an array but we will explain later\nShow method of “action” in this case just a filter, could be any action or data\n
  • Simple Annotation that needs no parameters (made simple on purpose)\nMention that parameters come in an array but we will explain later\nShow method of “action” in this case just a filter, could be any action or data\n
  • Simple Annotation that needs no parameters (made simple on purpose)\nMention that parameters come in an array but we will explain later\nShow method of “action” in this case just a filter, could be any action or data\n
  • Simple Annotation that needs no parameters (made simple on purpose)\nMention that parameters come in an array but we will explain later\nShow method of “action” in this case just a filter, could be any action or data\n
  • Simple Annotation that needs no parameters (made simple on purpose)\nMention that parameters come in an array but we will explain later\nShow method of “action” in this case just a filter, could be any action or data\n
  • Explain this simple “Enforcer” class\nIt only gets a single annotation from the reader\nIt makes the action described by the annotation happen.\n\n
  • Explain this simple “Enforcer” class\nIt only gets a single annotation from the reader\nIt makes the action described by the annotation happen.\n\n
  • Explain this simple “Enforcer” class\nIt only gets a single annotation from the reader\nIt makes the action described by the annotation happen.\n\n
  • Explain this simple “Enforcer” class\nIt only gets a single annotation from the reader\nIt makes the action described by the annotation happen.\n\n
  • DMS implements a Loader that loads all annotations and filters for “filter rules” since we have multiple classes\nDMS implements a walker that abstracts away reflection->makeAccessible and knows where to fin annotations (method/properties/etc..)\nFilter becomes a simple service that delegates actions.\n
  • DMS implements a Loader that loads all annotations and filters for “filter rules” since we have multiple classes\nDMS implements a walker that abstracts away reflection->makeAccessible and knows where to fin annotations (method/properties/etc..)\nFilter becomes a simple service that delegates actions.\n
  • DMS implements a Loader that loads all annotations and filters for “filter rules” since we have multiple classes\nDMS implements a walker that abstracts away reflection->makeAccessible and knows where to fin annotations (method/properties/etc..)\nFilter becomes a simple service that delegates actions.\n
  • DMS implements a Loader that loads all annotations and filters for “filter rules” since we have multiple classes\nDMS implements a walker that abstracts away reflection->makeAccessible and knows where to fin annotations (method/properties/etc..)\nFilter becomes a simple service that delegates actions.\n
  • DMS implements a Loader that loads all annotations and filters for “filter rules” since we have multiple classes\nDMS implements a walker that abstracts away reflection->makeAccessible and knows where to fin annotations (method/properties/etc..)\nFilter becomes a simple service that delegates actions.\n
  • DMS implements a Loader that loads all annotations and filters for “filter rules” since we have multiple classes\nDMS implements a walker that abstracts away reflection->makeAccessible and knows where to fin annotations (method/properties/etc..)\nFilter becomes a simple service that delegates actions.\n
  • DMS implements a Loader that loads all annotations and filters for “filter rules” since we have multiple classes\nDMS implements a walker that abstracts away reflection->makeAccessible and knows where to fin annotations (method/properties/etc..)\nFilter becomes a simple service that delegates actions.\n
  • DMS implements a Loader that loads all annotations and filters for “filter rules” since we have multiple classes\nDMS implements a walker that abstracts away reflection->makeAccessible and knows where to fin annotations (method/properties/etc..)\nFilter becomes a simple service that delegates actions.\n
  • DMS implements a Loader that loads all annotations and filters for “filter rules” since we have multiple classes\nDMS implements a walker that abstracts away reflection->makeAccessible and knows where to fin annotations (method/properties/etc..)\nFilter becomes a simple service that delegates actions.\n
  • DMS implements a Loader that loads all annotations and filters for “filter rules” since we have multiple classes\nDMS implements a walker that abstracts away reflection->makeAccessible and knows where to fin annotations (method/properties/etc..)\nFilter becomes a simple service that delegates actions.\n
  • DMS implements a Loader that loads all annotations and filters for “filter rules” since we have multiple classes\nDMS implements a walker that abstracts away reflection->makeAccessible and knows where to fin annotations (method/properties/etc..)\nFilter becomes a simple service that delegates actions.\n
  • DMS implements a Loader that loads all annotations and filters for “filter rules” since we have multiple classes\nDMS implements a walker that abstracts away reflection->makeAccessible and knows where to fin annotations (method/properties/etc..)\nFilter becomes a simple service that delegates actions.\n
  • DMS implements a Loader that loads all annotations and filters for “filter rules” since we have multiple classes\nDMS implements a walker that abstracts away reflection->makeAccessible and knows where to fin annotations (method/properties/etc..)\nFilter becomes a simple service that delegates actions.\n
  • DMS implements a Loader that loads all annotations and filters for “filter rules” since we have multiple classes\nDMS implements a walker that abstracts away reflection->makeAccessible and knows where to fin annotations (method/properties/etc..)\nFilter becomes a simple service that delegates actions.\n
  • DMS implements a Loader that loads all annotations and filters for “filter rules” since we have multiple classes\nDMS implements a walker that abstracts away reflection->makeAccessible and knows where to fin annotations (method/properties/etc..)\nFilter becomes a simple service that delegates actions.\n
  • DMS implements a Loader that loads all annotations and filters for “filter rules” since we have multiple classes\nDMS implements a walker that abstracts away reflection->makeAccessible and knows where to fin annotations (method/properties/etc..)\nFilter becomes a simple service that delegates actions.\n
  • DMS implements a Loader that loads all annotations and filters for “filter rules” since we have multiple classes\nDMS implements a walker that abstracts away reflection->makeAccessible and knows where to fin annotations (method/properties/etc..)\nFilter becomes a simple service that delegates actions.\n
  • the key is assumed to be the “defaultProperty”\n
  • the key is assumed to be the “defaultProperty”\n
  • the key is assumed to be the “defaultProperty”\n
  • the key is assumed to be the “defaultProperty”\n
  • the key is assumed to be the “defaultProperty”\n
  • the key is assumed to be the “defaultProperty”\n
  • the key is assumed to be the “defaultProperty”\n
  • the key is assumed to be the “defaultProperty”\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Annotating with Annotations Annotating with Annotations Presentation Transcript

  • *
  •   TrueNorthPHP
  •   -
  •   Toronto/2012 Annotating
  •   with
  •    Annotations A
  •   look
  •   into
  •   Annotations
  •   in
  •   PHP on
  •   twitter Rafael
  •   Dohms @rdohms
  • *
  •   TrueNorthPHP
  •   -
  •   Toronto/2012 Annotating
  •   with
  •    Annotations A
  •   look
  •   into
  •   Annotations
  •   in
  •   PHP on
  •   twitter Rafael
  •   Dohms @rdohms
  • Rafael Dohms photo credit: Eli White @rdohms Evangelist, Speaker and Contributor.Developer at WEBclusive.Enabler at AmsterdamPHP.
  • 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 Engines Doctrine
  •   Commons ZF2
  •   Annotations phpDocumentor
  •   2 Notoj abandoned? addendum php-annotations 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”;
  • //Get Doctrine Reader$reader = new AnnotationsAnnotationReader();$reader->setEnableParsePhpImports(true);//Load AnnotationLoader$loader = new MappingLoaderAnnotationLoader($reader);$this->loader = $loader;//Get a MetadataFactory$metadataFactory = new MappingClassMetadataFactory($loader);//Get a Filter$filter = new DMSFilterFilter($metadataFactory);//Get your Entity$user = new AppEntityUser();$user->name = "My <b>name</b>";$user->email = " email@mail.com";//Filter you entity$filter->filter($user);echo $user->name; //"My name"echo $user->email; //"email@mail.com"
  • //Get Doctrine Reader$reader = new AnnotationsAnnotationReader();$reader->setEnableParsePhpImports(true); put
  •   this
  •   in
  •   your
  •   DIC//Load AnnotationLoader$loader = new MappingLoaderAnnotationLoader($reader);$this->loader = $loader;//Get a MetadataFactory$metadataFactory = new MappingClassMetadataFactory($loader);//Get a Filter$filter = new DMSFilterFilter($metadataFactory);//Get your Entity$user = new AppEntityUser();$user->name = "My <b>name</b>";$user->email = " email@mail.com";//Filter you entity$filter->filter($user);echo $user->name; //"My name"echo $user->email; //"email@mail.com"
  • //Get Doctrine Reader$reader = new AnnotationsAnnotationReader();$reader->setEnableParsePhpImports(true); put
  •   this
  •   in
  •   your
  •   DIC//Load AnnotationLoader$loader = new MappingLoaderAnnotationLoader($reader);$this->loader = $loader;//Get a MetadataFactory$metadataFactory = new MappingClassMetadataFactory($loader);//Get a Filter$filter = new DMSFilterFilter($metadataFactory);//Get your Entity$user = new AppEntityUser(); Calling
  •   the
  •   Enforcer$user->name = "My <b>name</b>";$user->email = " email@mail.com";//Filter you entity$filter->filter($user);echo $user->name; //"My name"echo $user->email; //"email@mail.com"
  • What? Why? Where? How?
  • Questions? please! Rate
  •   this
  •   talk
  •   on
  •   Joind.in! https://joind.in/7418 on
  •   twitter@rdohms these
  •   slides
  •   http://doh.ms will
  •   be
  •   herehttp://slides.doh.ms