SlideShare a Scribd company logo
Declarative Development using Annotations in PHP Frank Kleine & Stephan Schmidt
Agenda The Speakers Basic Concept of Annotations Annotations in Java Annotations in PHP Annotations in Stubbles Usage examples Defining your own annotations Q&A
Frank Kleine Working at 1&1 Internet Inc. PHP since 2000 Stubbles Lead Developer Co-author of "Exploring PHP"
Stephan Schmidt Team Leader at 1&1 Internet Inc. Contributor to the PHP Open Source Community since 2001 15 PEAR packages, 1 pecl extension Author of „PHP Design Patters“ and co-author of several other PHP-related books Speaker at various conferences since 2001
The audience? Who is using PHP5? Who is using object-oriented development? Who is using PHP‘s reflection features?
Basic concept of Annotations Add metadata to classes, methods, properties Do not (directly) affect program semantics Can be used by tools or libraries Can be parameterized or simple marker annotations
Example scenarios Marking classes/methods as accessible via a web service Marking methods as unit test methods Defining how an object should be persisted or serialized Automating dependency injection
Annotations in Java 4 Doclets, similar to PHPDoc Accessible via a Doclet API and a command line tool Not only used for documentation purposes Xdoclet for creation of EJBs and more
Annotations in Java 5 Also accessible at runtime public @interface MyAnnotation { String myParam(); } @MyAnnotation(myParam="Foo") public class MyClass {} Annotations are part of the language
Annotations in PHP Is this the end of the session? Annotations are not part of any PHP version.
Annotations in PHP (revisited) Probably 90% of you used some kind of annotation /** * My class * *  @author The Stubbles Team *  @see http://www.stubbles.net */ class MyClass {}
History of annotations in PHP There was PHPDoc There was PHPDoc PHP 5 was released Some frameworks accessed PHPDoc tags Some frameworks started using some "specialized" doc comments
Specialized frameworks Annotations embedded in DocBlocks Allow you to use annotations supported by the framework. No generic parser for annotations, but mostly some regexps Not (easily) possible to include new annotations
Extended Reflection API Provides access to PHPDoc comments Used to get information about the types of parameters or properties No real annotation support http://instantsvc.toolslave.net/wiki/ExtendedReflectionAPI
PHP_Unit class Calculator { /** *  @assert (0, 0) == 0 *  @assert (1, 0) == 1 *  @assert (1, 1) == 2 */ public function add($a, $b) { return $a + $b; } }
SCA/SDO class MyApplication { /** * The stock quote service to use. * *  @reference *  @binding.wsdl ../StockQuote/StockQuote.wsdl */ public $stock_quote; ... }
More specialized Frameworks Services_Webservice makes use of "pimped" PHPDoc comments to create WSDL EZPDO uses annotations to ease object-relational mapping
Next step: Generic frameworks Enable you to create your own annotations Provide generic annotation parsers Provide access to annotations at run-time No common standard for annotations
PEAR::PHP_Annotation Parser for generic DocBlocks and Java-style annotations Provides mechanism for dependency injection No public release, yet First and last commit 4 months ago
Addendum Supports Java-style annotations Annotations are classes that extend class  Annotation Annotations are accessible via reflection classes that extend built-in reflection http://code.google.com/p/addendum/
Stubbles OOP PHP 5.2 framework Package based Provides generic annotation functionality Eats its own dog food and uses annotations in various packages
Annotations in Stubbles Persistence Serializing objects to XML Persisting objects in RDMBS Security Marking methods as callable via JSON-RPC Marking methods callable from XSLT Misc Managing dependency injection
A Person POPO class Person { protected $id; protected $name; protected $age; protected $role; public function __construct($id, $name, $age, $role = 'user') { $this->id  = $id; $this->name = $name; $this->age  = $age; $this->role = $role; } public function getId() { return $this->id; } ... more getter methods for the other properties ... }
Serializing to XML // Create a serializer $serializer = new stubXMLSerializer(); // XML in Stubbles is created via a streaming API $writer = stubXMLStreamWriterFactory::createAsAvailable(); // Create and serialize the object $user = new Person (1, 'schst', 33, 'admin'); $serializer->serialize($user, $writer); echo writer->asXML();
The resulting XML <?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?> < Person > < getId >1</ getId > < getName >schst</ getName > < getAge >33</ getAge > < getRole >admin</ getRole > </ Person >
XMLSerializer behaviour All public methods without parameters are exported Class and method names are used as tag names But:  The behavior can be changed by annotating the class.
XMLSerializer annotations Changing the name of the root tag: /** * A person * *  @XMLTag(tagName=&quot;user&quot;) */ class Person { ... rest of the code ... }
XMLSerializer annotations Changing the name of other tags /** * Get the name * *  @XMLTag(tagName=&quot;realname&quot;) * @return string */ public function getName() { return $this->name; }
XMLSerializer annotations Using attributes instead of tags /** * Get the id * *  @XMLAttribute(attributeName=&quot;userId&quot;) * @return int */ public function getId() { return $this->id; }
XMLSerializer annotations Ignoring methods /** * Get the age * *  @XMLIgnore * @return int */ public function getAge() { return $this->age; }
The modified XML <?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?> < user   userId=&quot;1&quot; > < realname >schst</ realname > < role >admin</ role > </ user > tag names have been changed id property is serialized as attribute age is omitted
Features of XMLSerializer Serializes (nearly) every data structure Able to use ext/dom or ext/xmlwriter Able to serialize public methods and properties Provides annotations to &quot;batch-process&quot; methods and properties
Persistence: POPO revisited /** * @DBTable(name='persons') ‏ */ class Person  extends stubAbstractPersistable  { ... properties like in old version ... /** * @DBColumn(name='person_id', isPrimaryKey=true) ‏ */ public function getId() { return $this->id; } } /** * @DBColumn(name='name', defaultValue='') ‏ */ public function getName() { return $this->name; } /** * @DBColumn(name='age', defaultValue=0) ‏ */ public function getAge() { return $this->age; } ... more ge tte r and of course setter methods for the other properties ... }
Persistence: insert ... create the person with the data ... $person = new Person(); $person->setName('Frank Kleine'); $person->setAge(27); $person->setRole('admin'); ... get the connection ... $connection = stubDatabaseConnectionPool::getConnection(); ... get the serializer ... $serializer = stubDatabaseSerializer::getInstance($connection); ... and save to database ... $serializer->serialize($person); ... done: ... var_dump($person->getId()); ... displays int(1) ...
Persistence: select (find) ‏ ... create the person object ... $person = new Person(); $person->setId(1); ... get the connection ... $connection = stubDatabaseConnectionPool::getConnection(); ... get the finder ... $finder = stubDatabaseFinder::getInstance($connection); ... and retrieve data ... $finder->findByPrimaryKeys($person); ... done: ... var_dump($person->getAge()); ... displays int(27) ... or: $criterion = new stubEqualCriterion('age', 27); $persons = $finder->findByCriterion($criterion, 'Person'); ... $persons is now an array containing a list of Person objects all of age 27
Persistence: more features Delete similarly to finder Update works like insert Very simple support for joins (needs more research) ‏ Independent of database: connection handle knows database type, correct query builder is selected
Persistence: going crazy /** * @DBTable(name='persons', type='InnoDB') ‏ */ class Person  extends stubAbstractPersistable  { ... properties like in old version ... /** * @DBColumn(name='person_id', isPrimaryKey=true, type='int', size=10, isUnsigned=true) ‏ */ public function getId() { return $this->id; } } /** * @DBColumn(name='name', defaultValue='', type='varchar', size=255, isNullable=false) ‏ */ public function getName() { return $this->name; } } $connection = stubDatabaseConnectionPool::getConnection(); $creator = stubDatabaseCreator::getInstance($connection); $creator->createTable('Person');
Accessing annotations in PHP PHP's built-in reflection API: $class = new ReflectionClass('Person'); echo $class->getName() . &quot;\n&quot;; foreach ($class->getMethods() as $method) { echo &quot; -> &quot; . $method->getName()  . &quot;\n&quot;; } Person -> __construct -> getId -> getName -> ...
Accessing annotations in PHP Stubbles' reflection API: $class = new  stubReflectionClass ('Person'); if ($class-> hasAnnotation ('XMLTag')) { $xmlTag = $class-> getAnnotation ('XMLTag'); print_r($xmlTag); } stubXMLTagAnnotation Object ( [tagName:protected] => user [elementTagName:protected] => [annotationName:protected] => XMLTag )
Stubbles' reflection Provides drop-in replacements for all built-in reflection classes, that extend the built-in classes (for type safety) Provides two additional methods: hasAnnotation(string name) getAnnotation(string name) Annotations are objects
Creating annotations Annotation classes must implement  stubAnnotation  interface Annotations can extend abstract base class Annotations should comply to naming scheme Annotations may contain additional properties and methods
Example: CSV Export /** * A person * *  @CSV(file=&quot;users.csv&quot;, *  delimeter=&quot;;&quot;) */ class Person { ...properties and methods ... /** * Get the id * *  @CSVField * @return int */ public function getId() { return $this->id; } }
The  @CSV  Annotation class stubCSVAnnotation extends  stubAbstractAnnotation implements  stubAnnotation  { }
Annotation parameters Parameters can be set in three ways Providing a public property with the same name as the parameter Providing a public method with the same name as the parameter prefixed with  set Providing a magic  __set()  method
The  @CSV  Annotation class stubCSVAnnotation extends stubAbstractAnnotation implements stubAnnotation { public $file ; protected $delimeter; public function setDelimeter($delim) { $this->delimeter = $delim; } public function getDelimeter() { return $this->delimeter; } }
Annotation parameter types Strings (enclosed in &quot; or ') integers and doubles true ,  false  and  null PHP constants for configurable annotations instances of stubReflectionClass ( clazz=Person.class )
Annotation targets Annotations may be added to Classes Properties Methods Functions Each annotation may restrict the possible targets
The  @CSV  Annotation class stubCSVAnnotation extends stubAbstractAnnotation implements stubAnnotation { public function getAnnotationTarget() { return stubAnnotation::TARGET_CLASS; } } Should only be added to classes Parser will throw an exception on error
The  @CSVField  Annotation class stubCSVFieldAnnotation extends stubAbstractAnnotation implements stubAnnotation { public function getAnnotationTarget() { return stubAnnotation::TARGET_METHOD | stubAnnotation::TARGET_PROPERTY; } } Can be added to methods and properties
Implementing the CSV Writer Accept any object Check for  @CSV  annotation Extract parameters from annotation Traverse all methods and properties Check for  @CSVField  annotation Invoke the methods Write line to file
The  CSVWriter  class class CSVWriter { public static function write($obj) { $class = new stubReflectionClass(get_class($obj)); if (! $class->hasAnnotation('CSV') ) { throw new Exception('Not suported'); } $csv =  $class->getAnnotation('CSV'); $fp = fopen( $csv->file , 'a'); $fields = array(); foreach ($class->getMethods() as $method) {
The  CSVWriter  class if (! $method->hasAnnotation('CSVField') ) { continue; } $fields[] = $method->invoke($obj); } $line = implode( $csv->getDelimeter() , $fields); fwrite($fp, $line . &quot;\n&quot;); fclose($fp); } }
Using the  CSVWriter  class $user = new Person(1, 'schst', 33, 'admin'); CSVWriter::write($user); users.csv: 1;schst;33 Pass any annotated object to the  write()  method:
Advances Features Annotations are cached during and between the requests Annotations can be modified at run-tim
Advanced features Annotations may be interfaces that can be implemented in various ways: /** *  @XMLMethods [XMLMatcher] (pattern='/^get(.+)/') */ class Person { ... methods ... }
Annotation interfaces XMLSerializer only knows about the  @XMLMethods  annotation interface XMLMatcher  implements this interface and decides which methods to export Annotations do not only provide meta information, but also logic
The end Thank you for your attention. Want to know more? http://www.stubbles.net http://www.frankkleine.de http://www.schst.net
Commercial break

More Related Content

What's hot (20)

PPT
Overview of PHP and MYSQL
Deblina Chowdhury
 
PPT
Component Framework Primer for JSF Users
Andy Schwartz
 
PDF
Learning To Run - XPages for Lotus Notes Client Developers
Kathy Brown
 
PPT
JSF 2 and beyond: Keeping progress coming
Andy Schwartz
 
ODP
Ant User Guide
Muthuselvam RS
 
PPT
Apache Persistence Layers
Henning Schmiedehausen
 
PPTX
Beautiful REST and JSON APIs - Les Hazlewood
jaxconf
 
PPT
Starting with PHP and Web devepolment
Rajib Ahmed
 
KEY
A Conversation About REST
Jeremy Brown
 
PPTX
Dost.jar and fo.jar
Suite Solutions
 
PPT
PDF Localization
Suite Solutions
 
PPT
Unified Expression Language
BG Java EE Course
 
PPTX
Wt unit 5
team11vgnt
 
PPTX
working with PHP & DB's
Hi-Tech College
 
PDF
Dexterity in the Wild
David Glick
 
ZIP
Looking into HTML5
Christopher Schmitt
 
ODP
JavaScript and jQuery Fundamentals
BG Java EE Course
 
PDF
15 expression-language
snopteck
 
PDF
A Dexterity Intro for Recovering Archetypes Addicts
David Glick
 
KEY
Jumpstart Django
ryates
 
Overview of PHP and MYSQL
Deblina Chowdhury
 
Component Framework Primer for JSF Users
Andy Schwartz
 
Learning To Run - XPages for Lotus Notes Client Developers
Kathy Brown
 
JSF 2 and beyond: Keeping progress coming
Andy Schwartz
 
Ant User Guide
Muthuselvam RS
 
Apache Persistence Layers
Henning Schmiedehausen
 
Beautiful REST and JSON APIs - Les Hazlewood
jaxconf
 
Starting with PHP and Web devepolment
Rajib Ahmed
 
A Conversation About REST
Jeremy Brown
 
Dost.jar and fo.jar
Suite Solutions
 
PDF Localization
Suite Solutions
 
Unified Expression Language
BG Java EE Course
 
Wt unit 5
team11vgnt
 
working with PHP & DB's
Hi-Tech College
 
Dexterity in the Wild
David Glick
 
Looking into HTML5
Christopher Schmitt
 
JavaScript and jQuery Fundamentals
BG Java EE Course
 
15 expression-language
snopteck
 
A Dexterity Intro for Recovering Archetypes Addicts
David Glick
 
Jumpstart Django
ryates
 

Similar to Declarative Development Using Annotations In PHP (20)

PPT
Go OO! - Real-life Design Patterns in PHP 5
Stephan Schmidt
 
PDF
Annotations in PHP, They Exist.
Rafael Dohms
 
PPTX
FFW Gabrovo PMG - PHP OOP Part 3
Toni Kolev
 
PDF
PHP Annotations: They exist! - JetBrains Webinar
Rafael Dohms
 
KEY
Object Relational Mapping in PHP
Rob Knight
 
PPTX
Doctrine 2.0 Enterprise Persistence Layer for PHP
Guilherme Blanco
 
PPT
PHP 5 Boot Camp
Adam Trachtenberg
 
PDF
SPL: The Missing Link in Development
jsmith92
 
PDF
The state of your own hypertext preprocessor
Alessandro Nadalin
 
PDF
Object Oriented Programming with PHP 5 - More OOP
Wildan Maulana
 
PDF
PHP OOP
Oscar Merida
 
PPTX
Ch8(oop)
Chhom Karath
 
PDF
PHP 5
Rafael Corral
 
PPT
Advanced php
hamfu
 
PPT
OOP
thinkphp
 
PPT
Zend framework 03 - singleton factory data mapper caching logging
Tricode (part of Dept)
 
KEY
SPL, not a bridge too far
Michelangelo van Dam
 
PDF
PHP Language Trivia
Nikita Popov
 
PDF
php_final_sy_semIV_notes_vision.pdf
akankshasorate1
 
PDF
php_final_sy_semIV_notes_vision (3).pdf
bhagyashri686896
 
Go OO! - Real-life Design Patterns in PHP 5
Stephan Schmidt
 
Annotations in PHP, They Exist.
Rafael Dohms
 
FFW Gabrovo PMG - PHP OOP Part 3
Toni Kolev
 
PHP Annotations: They exist! - JetBrains Webinar
Rafael Dohms
 
Object Relational Mapping in PHP
Rob Knight
 
Doctrine 2.0 Enterprise Persistence Layer for PHP
Guilherme Blanco
 
PHP 5 Boot Camp
Adam Trachtenberg
 
SPL: The Missing Link in Development
jsmith92
 
The state of your own hypertext preprocessor
Alessandro Nadalin
 
Object Oriented Programming with PHP 5 - More OOP
Wildan Maulana
 
PHP OOP
Oscar Merida
 
Ch8(oop)
Chhom Karath
 
Advanced php
hamfu
 
Zend framework 03 - singleton factory data mapper caching logging
Tricode (part of Dept)
 
SPL, not a bridge too far
Michelangelo van Dam
 
PHP Language Trivia
Nikita Popov
 
php_final_sy_semIV_notes_vision.pdf
akankshasorate1
 
php_final_sy_semIV_notes_vision (3).pdf
bhagyashri686896
 
Ad

More from Stephan Schmidt (18)

PDF
Das Web Wird Mobil - Geolocation und Location Based Services
Stephan Schmidt
 
PDF
23 Dinge, die Sie über Software Entwicklung in Teams wissen sollten
Stephan Schmidt
 
PDF
23 Dinge, die Sie über Software-Entwicklung in Teams wissen sollten
Stephan Schmidt
 
PDF
Continuous Integration mit Jenkins
Stephan Schmidt
 
PDF
Die Kunst des Software Design - Java
Stephan Schmidt
 
PDF
PHP mit Paul Bocuse
Stephan Schmidt
 
PDF
Der Erfolgreiche Programmierer
Stephan Schmidt
 
PDF
23 Dinge, die Sie über Software-Entwicklung in Teams wissen sollten.
Stephan Schmidt
 
KEY
Die Kunst Des Software Design
Stephan Schmidt
 
PDF
Software-Entwicklung Im Team
Stephan Schmidt
 
PDF
JSON-RPC Proxy Generation with PHP 5
Stephan Schmidt
 
PPT
Session Server - Maintaing State between several Servers
Stephan Schmidt
 
PPT
PEAR For The Masses
Stephan Schmidt
 
PPT
XML-Socket-Server zur Kommunikation mit Flash
Stephan Schmidt
 
PPT
Interprozesskommunikation mit PHP
Stephan Schmidt
 
PPT
PHP im High End
Stephan Schmidt
 
PPT
Dynamische Websites mit XML
Stephan Schmidt
 
PPT
Web 2.0 Mit Der Yahoo User Interface Library
Stephan Schmidt
 
Das Web Wird Mobil - Geolocation und Location Based Services
Stephan Schmidt
 
23 Dinge, die Sie über Software Entwicklung in Teams wissen sollten
Stephan Schmidt
 
23 Dinge, die Sie über Software-Entwicklung in Teams wissen sollten
Stephan Schmidt
 
Continuous Integration mit Jenkins
Stephan Schmidt
 
Die Kunst des Software Design - Java
Stephan Schmidt
 
PHP mit Paul Bocuse
Stephan Schmidt
 
Der Erfolgreiche Programmierer
Stephan Schmidt
 
23 Dinge, die Sie über Software-Entwicklung in Teams wissen sollten.
Stephan Schmidt
 
Die Kunst Des Software Design
Stephan Schmidt
 
Software-Entwicklung Im Team
Stephan Schmidt
 
JSON-RPC Proxy Generation with PHP 5
Stephan Schmidt
 
Session Server - Maintaing State between several Servers
Stephan Schmidt
 
PEAR For The Masses
Stephan Schmidt
 
XML-Socket-Server zur Kommunikation mit Flash
Stephan Schmidt
 
Interprozesskommunikation mit PHP
Stephan Schmidt
 
PHP im High End
Stephan Schmidt
 
Dynamische Websites mit XML
Stephan Schmidt
 
Web 2.0 Mit Der Yahoo User Interface Library
Stephan Schmidt
 
Ad

Recently uploaded (20)

PDF
Building Resilience with Digital Twins : Lessons from Korea
SANGHEE SHIN
 
PDF
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
PDF
Persuasive AI: risks and opportunities in the age of digital debate
Speck&Tech
 
PDF
The Builder’s Playbook - 2025 State of AI Report.pdf
jeroen339954
 
PDF
Apache CloudStack 201: Let's Design & Build an IaaS Cloud
ShapeBlue
 
PDF
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
PDF
Impact of IEEE Computer Society in Advancing Emerging Technologies including ...
Hironori Washizaki
 
PDF
Why Orbit Edge Tech is a Top Next JS Development Company in 2025
mahendraalaska08
 
PPTX
Top Managed Service Providers in Los Angeles
Captain IT
 
PPTX
WooCommerce Workshop: Bring Your Laptop
Laura Hartwig
 
PDF
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
PDF
CloudStack GPU Integration - Rohit Yadav
ShapeBlue
 
PDF
Ampere Offers Energy-Efficient Future For AI And Cloud
ShapeBlue
 
PDF
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
PDF
Human-centred design in online workplace learning and relationship to engagem...
Tracy Tang
 
PPTX
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
PPT
Interview paper part 3, It is based on Interview Prep
SoumyadeepGhosh39
 
PDF
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PDF
NewMind AI Journal - Weekly Chronicles - July'25 Week II
NewMind AI
 
Building Resilience with Digital Twins : Lessons from Korea
SANGHEE SHIN
 
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
Persuasive AI: risks and opportunities in the age of digital debate
Speck&Tech
 
The Builder’s Playbook - 2025 State of AI Report.pdf
jeroen339954
 
Apache CloudStack 201: Let's Design & Build an IaaS Cloud
ShapeBlue
 
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
Impact of IEEE Computer Society in Advancing Emerging Technologies including ...
Hironori Washizaki
 
Why Orbit Edge Tech is a Top Next JS Development Company in 2025
mahendraalaska08
 
Top Managed Service Providers in Los Angeles
Captain IT
 
WooCommerce Workshop: Bring Your Laptop
Laura Hartwig
 
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
CloudStack GPU Integration - Rohit Yadav
ShapeBlue
 
Ampere Offers Energy-Efficient Future For AI And Cloud
ShapeBlue
 
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
Human-centred design in online workplace learning and relationship to engagem...
Tracy Tang
 
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
Interview paper part 3, It is based on Interview Prep
SoumyadeepGhosh39
 
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
NewMind AI Journal - Weekly Chronicles - July'25 Week II
NewMind AI
 

Declarative Development Using Annotations In PHP

  • 1. Declarative Development using Annotations in PHP Frank Kleine & Stephan Schmidt
  • 2. Agenda The Speakers Basic Concept of Annotations Annotations in Java Annotations in PHP Annotations in Stubbles Usage examples Defining your own annotations Q&A
  • 3. Frank Kleine Working at 1&1 Internet Inc. PHP since 2000 Stubbles Lead Developer Co-author of &quot;Exploring PHP&quot;
  • 4. Stephan Schmidt Team Leader at 1&1 Internet Inc. Contributor to the PHP Open Source Community since 2001 15 PEAR packages, 1 pecl extension Author of „PHP Design Patters“ and co-author of several other PHP-related books Speaker at various conferences since 2001
  • 5. The audience? Who is using PHP5? Who is using object-oriented development? Who is using PHP‘s reflection features?
  • 6. Basic concept of Annotations Add metadata to classes, methods, properties Do not (directly) affect program semantics Can be used by tools or libraries Can be parameterized or simple marker annotations
  • 7. Example scenarios Marking classes/methods as accessible via a web service Marking methods as unit test methods Defining how an object should be persisted or serialized Automating dependency injection
  • 8. Annotations in Java 4 Doclets, similar to PHPDoc Accessible via a Doclet API and a command line tool Not only used for documentation purposes Xdoclet for creation of EJBs and more
  • 9. Annotations in Java 5 Also accessible at runtime public @interface MyAnnotation { String myParam(); } @MyAnnotation(myParam=&quot;Foo&quot;) public class MyClass {} Annotations are part of the language
  • 10. Annotations in PHP Is this the end of the session? Annotations are not part of any PHP version.
  • 11. Annotations in PHP (revisited) Probably 90% of you used some kind of annotation /** * My class * * @author The Stubbles Team * @see http://www.stubbles.net */ class MyClass {}
  • 12. History of annotations in PHP There was PHPDoc There was PHPDoc PHP 5 was released Some frameworks accessed PHPDoc tags Some frameworks started using some &quot;specialized&quot; doc comments
  • 13. Specialized frameworks Annotations embedded in DocBlocks Allow you to use annotations supported by the framework. No generic parser for annotations, but mostly some regexps Not (easily) possible to include new annotations
  • 14. Extended Reflection API Provides access to PHPDoc comments Used to get information about the types of parameters or properties No real annotation support http://instantsvc.toolslave.net/wiki/ExtendedReflectionAPI
  • 15. PHP_Unit class Calculator { /** * @assert (0, 0) == 0 * @assert (1, 0) == 1 * @assert (1, 1) == 2 */ public function add($a, $b) { return $a + $b; } }
  • 16. SCA/SDO class MyApplication { /** * The stock quote service to use. * * @reference * @binding.wsdl ../StockQuote/StockQuote.wsdl */ public $stock_quote; ... }
  • 17. More specialized Frameworks Services_Webservice makes use of &quot;pimped&quot; PHPDoc comments to create WSDL EZPDO uses annotations to ease object-relational mapping
  • 18. Next step: Generic frameworks Enable you to create your own annotations Provide generic annotation parsers Provide access to annotations at run-time No common standard for annotations
  • 19. PEAR::PHP_Annotation Parser for generic DocBlocks and Java-style annotations Provides mechanism for dependency injection No public release, yet First and last commit 4 months ago
  • 20. Addendum Supports Java-style annotations Annotations are classes that extend class Annotation Annotations are accessible via reflection classes that extend built-in reflection http://code.google.com/p/addendum/
  • 21. Stubbles OOP PHP 5.2 framework Package based Provides generic annotation functionality Eats its own dog food and uses annotations in various packages
  • 22. Annotations in Stubbles Persistence Serializing objects to XML Persisting objects in RDMBS Security Marking methods as callable via JSON-RPC Marking methods callable from XSLT Misc Managing dependency injection
  • 23. A Person POPO class Person { protected $id; protected $name; protected $age; protected $role; public function __construct($id, $name, $age, $role = 'user') { $this->id = $id; $this->name = $name; $this->age = $age; $this->role = $role; } public function getId() { return $this->id; } ... more getter methods for the other properties ... }
  • 24. Serializing to XML // Create a serializer $serializer = new stubXMLSerializer(); // XML in Stubbles is created via a streaming API $writer = stubXMLStreamWriterFactory::createAsAvailable(); // Create and serialize the object $user = new Person (1, 'schst', 33, 'admin'); $serializer->serialize($user, $writer); echo writer->asXML();
  • 25. The resulting XML <?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?> < Person > < getId >1</ getId > < getName >schst</ getName > < getAge >33</ getAge > < getRole >admin</ getRole > </ Person >
  • 26. XMLSerializer behaviour All public methods without parameters are exported Class and method names are used as tag names But: The behavior can be changed by annotating the class.
  • 27. XMLSerializer annotations Changing the name of the root tag: /** * A person * * @XMLTag(tagName=&quot;user&quot;) */ class Person { ... rest of the code ... }
  • 28. XMLSerializer annotations Changing the name of other tags /** * Get the name * * @XMLTag(tagName=&quot;realname&quot;) * @return string */ public function getName() { return $this->name; }
  • 29. XMLSerializer annotations Using attributes instead of tags /** * Get the id * * @XMLAttribute(attributeName=&quot;userId&quot;) * @return int */ public function getId() { return $this->id; }
  • 30. XMLSerializer annotations Ignoring methods /** * Get the age * * @XMLIgnore * @return int */ public function getAge() { return $this->age; }
  • 31. The modified XML <?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?> < user userId=&quot;1&quot; > < realname >schst</ realname > < role >admin</ role > </ user > tag names have been changed id property is serialized as attribute age is omitted
  • 32. Features of XMLSerializer Serializes (nearly) every data structure Able to use ext/dom or ext/xmlwriter Able to serialize public methods and properties Provides annotations to &quot;batch-process&quot; methods and properties
  • 33. Persistence: POPO revisited /** * @DBTable(name='persons') ‏ */ class Person extends stubAbstractPersistable { ... properties like in old version ... /** * @DBColumn(name='person_id', isPrimaryKey=true) ‏ */ public function getId() { return $this->id; } } /** * @DBColumn(name='name', defaultValue='') ‏ */ public function getName() { return $this->name; } /** * @DBColumn(name='age', defaultValue=0) ‏ */ public function getAge() { return $this->age; } ... more ge tte r and of course setter methods for the other properties ... }
  • 34. Persistence: insert ... create the person with the data ... $person = new Person(); $person->setName('Frank Kleine'); $person->setAge(27); $person->setRole('admin'); ... get the connection ... $connection = stubDatabaseConnectionPool::getConnection(); ... get the serializer ... $serializer = stubDatabaseSerializer::getInstance($connection); ... and save to database ... $serializer->serialize($person); ... done: ... var_dump($person->getId()); ... displays int(1) ...
  • 35. Persistence: select (find) ‏ ... create the person object ... $person = new Person(); $person->setId(1); ... get the connection ... $connection = stubDatabaseConnectionPool::getConnection(); ... get the finder ... $finder = stubDatabaseFinder::getInstance($connection); ... and retrieve data ... $finder->findByPrimaryKeys($person); ... done: ... var_dump($person->getAge()); ... displays int(27) ... or: $criterion = new stubEqualCriterion('age', 27); $persons = $finder->findByCriterion($criterion, 'Person'); ... $persons is now an array containing a list of Person objects all of age 27
  • 36. Persistence: more features Delete similarly to finder Update works like insert Very simple support for joins (needs more research) ‏ Independent of database: connection handle knows database type, correct query builder is selected
  • 37. Persistence: going crazy /** * @DBTable(name='persons', type='InnoDB') ‏ */ class Person extends stubAbstractPersistable { ... properties like in old version ... /** * @DBColumn(name='person_id', isPrimaryKey=true, type='int', size=10, isUnsigned=true) ‏ */ public function getId() { return $this->id; } } /** * @DBColumn(name='name', defaultValue='', type='varchar', size=255, isNullable=false) ‏ */ public function getName() { return $this->name; } } $connection = stubDatabaseConnectionPool::getConnection(); $creator = stubDatabaseCreator::getInstance($connection); $creator->createTable('Person');
  • 38. Accessing annotations in PHP PHP's built-in reflection API: $class = new ReflectionClass('Person'); echo $class->getName() . &quot;\n&quot;; foreach ($class->getMethods() as $method) { echo &quot; -> &quot; . $method->getName() . &quot;\n&quot;; } Person -> __construct -> getId -> getName -> ...
  • 39. Accessing annotations in PHP Stubbles' reflection API: $class = new stubReflectionClass ('Person'); if ($class-> hasAnnotation ('XMLTag')) { $xmlTag = $class-> getAnnotation ('XMLTag'); print_r($xmlTag); } stubXMLTagAnnotation Object ( [tagName:protected] => user [elementTagName:protected] => [annotationName:protected] => XMLTag )
  • 40. Stubbles' reflection Provides drop-in replacements for all built-in reflection classes, that extend the built-in classes (for type safety) Provides two additional methods: hasAnnotation(string name) getAnnotation(string name) Annotations are objects
  • 41. Creating annotations Annotation classes must implement stubAnnotation interface Annotations can extend abstract base class Annotations should comply to naming scheme Annotations may contain additional properties and methods
  • 42. Example: CSV Export /** * A person * * @CSV(file=&quot;users.csv&quot;, * delimeter=&quot;;&quot;) */ class Person { ...properties and methods ... /** * Get the id * * @CSVField * @return int */ public function getId() { return $this->id; } }
  • 43. The @CSV Annotation class stubCSVAnnotation extends stubAbstractAnnotation implements stubAnnotation { }
  • 44. Annotation parameters Parameters can be set in three ways Providing a public property with the same name as the parameter Providing a public method with the same name as the parameter prefixed with set Providing a magic __set() method
  • 45. The @CSV Annotation class stubCSVAnnotation extends stubAbstractAnnotation implements stubAnnotation { public $file ; protected $delimeter; public function setDelimeter($delim) { $this->delimeter = $delim; } public function getDelimeter() { return $this->delimeter; } }
  • 46. Annotation parameter types Strings (enclosed in &quot; or ') integers and doubles true , false and null PHP constants for configurable annotations instances of stubReflectionClass ( clazz=Person.class )
  • 47. Annotation targets Annotations may be added to Classes Properties Methods Functions Each annotation may restrict the possible targets
  • 48. The @CSV Annotation class stubCSVAnnotation extends stubAbstractAnnotation implements stubAnnotation { public function getAnnotationTarget() { return stubAnnotation::TARGET_CLASS; } } Should only be added to classes Parser will throw an exception on error
  • 49. The @CSVField Annotation class stubCSVFieldAnnotation extends stubAbstractAnnotation implements stubAnnotation { public function getAnnotationTarget() { return stubAnnotation::TARGET_METHOD | stubAnnotation::TARGET_PROPERTY; } } Can be added to methods and properties
  • 50. Implementing the CSV Writer Accept any object Check for @CSV annotation Extract parameters from annotation Traverse all methods and properties Check for @CSVField annotation Invoke the methods Write line to file
  • 51. The CSVWriter class class CSVWriter { public static function write($obj) { $class = new stubReflectionClass(get_class($obj)); if (! $class->hasAnnotation('CSV') ) { throw new Exception('Not suported'); } $csv = $class->getAnnotation('CSV'); $fp = fopen( $csv->file , 'a'); $fields = array(); foreach ($class->getMethods() as $method) {
  • 52. The CSVWriter class if (! $method->hasAnnotation('CSVField') ) { continue; } $fields[] = $method->invoke($obj); } $line = implode( $csv->getDelimeter() , $fields); fwrite($fp, $line . &quot;\n&quot;); fclose($fp); } }
  • 53. Using the CSVWriter class $user = new Person(1, 'schst', 33, 'admin'); CSVWriter::write($user); users.csv: 1;schst;33 Pass any annotated object to the write() method:
  • 54. Advances Features Annotations are cached during and between the requests Annotations can be modified at run-tim
  • 55. Advanced features Annotations may be interfaces that can be implemented in various ways: /** * @XMLMethods [XMLMatcher] (pattern='/^get(.+)/') */ class Person { ... methods ... }
  • 56. Annotation interfaces XMLSerializer only knows about the @XMLMethods annotation interface XMLMatcher implements this interface and decides which methods to export Annotations do not only provide meta information, but also logic
  • 57. The end Thank you for your attention. Want to know more? http://www.stubbles.net http://www.frankkleine.de http://www.schst.net