Slideshare.net (beta)

 
Post to TwitterPost to Twitter
Post: 
Myspace Hi5 Friendster Xanga LiveJournal Facebook Blogger Tagged Typepad Freewebs BlackPlanet gigya icons

All comments

Add a comment on Slide 1

If you have a SlideShare account, login to comment; else you can comment as a guest


Showing 1-50 of 2 (more)

Declarative Development Using Annotations In PHP

From stubbles, 2 years ago

Presentation from the International PHP Conference 2007 - Spring E more

2977 views  |  0 comments  |  2 favorites  |  6 embeds (Stats)
Download not available ?
 

Categories

Add Category
 
 

Groups / Events

 

 
Embed
options

More Info

This slideshow is Public
Total Views: 2977
on Slideshare: 2681
from embeds: 296

Slideshow transcript

Slide 1: Declarative Development using Annotations in PHP Frank Kleine & Stephan Schmidt

Slide 2: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations Agenda • The Speakers • Basic Concept of Annotations • Annotations in Java • Annotations in PHP • Annotations in Stubbles • Usage examples • Defining your own annotations • Q&A 2

Slide 3: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations Frank Kleine • Working at 1&1 Internet Inc. • PHP since 2000 • Stubbles Lead Developer • Co-author of \"Exploring PHP\" 3

Slide 4: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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 4

Slide 5: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations The audience? • Who is using PHP5? • Who is using object-oriented development? • Who is using PHP‘s reflection features? 5

Slide 6: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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 6

Slide 7: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using 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 7

Slide 8: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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 8

Slide 9: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations Annotations in Java 5 • Annotations are part of the language public @interface MyAnnotation { String myParam(); } @MyAnnotation(myParam=\"Foo\") public class MyClass {} • Also accessible at runtime 9

Slide 10: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations Annotations in PHP Annotations are not part of any PHP version. Is this the end of the session? 10

Slide 11: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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 {} 11

Slide 12: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations History of annotations in PHP 1. There was PHPDoc 2. There was PHPDoc 3. PHP 5 was released 4. Some frameworks accessed PHPDoc tags 5. Some frameworks started using some \"specialized\" doc comments 12

Slide 13: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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 13

Slide 14: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using 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/Extende dReflectionAPI 14

Slide 15: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations PHP_Unit class Calculator { /** * @assert (0, 0) == 0 * @assert (1, 0) == 1 * @assert (1, 1) == 2 */ public function add($a, $b) { return $a + $b; } } 15

Slide 16: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations SCA/SDO class MyApplication { /** * The stock quote service to use. * * @reference * @binding.wsdl ../StockQuote/StockQuote.wsdl */ public $stock_quote; ... } 16

Slide 17: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations More specialized Frameworks • Services_Webservice makes use of \"pimped\" PHPDoc comments to create WSDL • EZPDO uses annotations to ease object- relational mapping 17

Slide 18: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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 18

Slide 19: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using 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 19

Slide 20: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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/ 20

Slide 21: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations Stubbles • OOP PHP 5.2 framework • Package based • Provides generic annotation functionality • Eats its own dog food and uses annotations in various packages 21

Slide 22: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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 22

Slide 23: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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 ... } 23

Slide 24: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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(); 24

Slide 25: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations The resulting XML <?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> <Person> <getId>1</getId> <getName>schst</getName> <getAge>33</getAge> <getRole>admin</getRole> </Person> 25

Slide 26: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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. 26

Slide 27: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations XMLSerializer annotations Changing the name of the root tag: /** * A person * * @XMLTag(tagName=\"user\") */ class Person { ... rest of the code ... } 27

Slide 28: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations XMLSerializer annotations Changing the name of other tags /** * Get the name * * @XMLTag(tagName=\"realname\") * @return string */ public function getName() { return $this->name; } 28

Slide 29: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations XMLSerializer annotations Using attributes instead of tags /** * Get the id * * @XMLAttribute(attributeName=\"userId\") * @return int */ public function getId() { return $this->id; } 29

Slide 30: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations XMLSerializer annotations Ignoring methods /** * Get the age * * @XMLIgnore * @return int */ public function getAge() { return $this->age; } 30

Slide 31: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations The modified XML <?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> <user userId=\"1\"> <realname>schst</realname> <role>admin</role> </user> • tag names have been changed • id property is serialized as attribute • age is omitted 31

Slide 32: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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 \"batch-process\" methods and properties 32

Slide 33: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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 getter and of course setter methods for the other properties ... } 33

Slide 34: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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) ... 34

Slide 35: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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 35

Slide 36: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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 36

Slide 37: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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'); 37

Slide 38: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations Accessing annotations in PHP PHP's built-in reflection API: $class = new ReflectionClass('Person'); echo $class->getName() . \"\\n\"; foreach ($class->getMethods() as $method) { echo \" -> \" . $method->getName() . \"\\n\"; } Person -> __construct -> getId -> getName -> ... 38

Slide 39: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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 ) 39

Slide 40: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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 40

Slide 41: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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 41

Slide 42: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations Example: CSV Export /** * A person * * @CSV(file=\"users.csv\", * delimeter=\";\") */ class Person { ...properties and methods ... /** * Get the id * * @CSVField * @return int */ public function getId() { return $this->id; } } 42

Slide 43: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations The @CSV Annotation class stubCSVAnnotation extends stubAbstractAnnotation implements stubAnnotation { } 43

Slide 44: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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 44

Slide 45: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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; } } 45

Slide 46: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations Annotation parameter types • Strings (enclosed in \" or ') • integers and doubles • true, false and null • PHP constants for configurable annotations • instances of stubReflectionClass (clazz=Person.class) 46

Slide 47: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations Annotation targets • Annotations may be added to • Classes • Properties • Methods • Functions • Each annotation may restrict the possible targets 47

Slide 48: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations The @CSV Annotation • Should only be added to classes class stubCSVAnnotation extends stubAbstractAnnotation implements stubAnnotation { public function getAnnotationTarget() { return stubAnnotation::TARGET_CLASS; } } • Parser will throw an exception on error 48

Slide 49: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations The @CSVField Annotation • Can be added to methods and properties class stubCSVFieldAnnotation extends stubAbstractAnnotation implements stubAnnotation { public function getAnnotationTarget() { return stubAnnotation::TARGET_METHOD | stubAnnotation::TARGET_PROPERTY; } } 49

Slide 50: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations Implementing the CSV Writer 1. Accept any object 2. Check for @CSV annotation 3. Extract parameters from annotation 4. Traverse all methods and properties 5. Check for @CSVField annotation 6. Invoke the methods 7. Write line to file 50

Slide 51: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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) { 51

Slide 52: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations The CSVWriter class if (!$method->hasAnnotation('CSVField')) { continue; } $fields[] = $method->invoke($obj); } $line = implode($csv->getDelimeter(), $fields); fwrite($fp, $line . \"\\n\"); fclose($fp); } } 52

Slide 53: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations Using the CSVWriter class • Pass any annotated object to the write() method: $user = new Person(1, 'schst', 33, 'admin'); CSVWriter::write($user); users.csv: 1;schst;33 53

Slide 54: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations Advances Features • Annotations are cached during and between the requests • Annotations can be modified at run-tim 54

Slide 55: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations Advanced features Annotations may be interfaces that can be implemented in various ways: /** * @XMLMethods[XMLMatcher](pattern='/^get(.+)/') */ class Person { ... methods ... } 55

Slide 56: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations 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 56

Slide 57: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations The end Thank you for your attention. Want to know more? http://www.stubbles.net http://www.frankkleine.de http://www.schst.net 57

Slide 58: Frank Kleine & Stephan Schmidt, 1&1 Internet AG Declarative Development using Annotations Commercial break 58