Transcript
Page 1: Annotations in PHP - ConFoo 2013

Rafael����������� ������������������  Dohms

*����������� ������������������  ConFoo����������� ������������������  -����������� ������������������  Montreal/2013

Annotations����������� ������������������  in����������� ������������������  PHP

@rdohmson����������� ������������������  twitter

They����������� ������������������  Exist!

Page 2: Annotations in PHP - ConFoo 2013

phot

o cr

edit:

Eli W

hite

Evangelist, Speaker and Contributor.

Developer at WEBclusive.

Enabler at AmsterdamPHP.

Rafael Dohms@rdohms

we����������� ������������������  make����������� ������������������  awesome����������� ������������������  crowd-funding����������� ������������������  software!

Page 3: Annotations in PHP - ConFoo 2013

What? Why? Where?

How?

a����������� ������������������  little����������� ������������������  history

show����������� ������������������  me����������� ������������������  the����������� ������������������  code!

existing����������� ������������������  uses

Implementing����������� ������������������  custom����������� ������������������  annotations

based����������� ������������������  on����������� ������������������  DMS\Filter

Page 4: Annotations in PHP - ConFoo 2013

what?What����������� ������������������  ar

e����������� ������������������  annotation

s?

http://ecdesignrebels.blogspot.com

Page 5: Annotations in PHP - ConFoo 2013

-- In English --"An annotation is a note that is made while

reading any form of text."

Page 6: Annotations in PHP - ConFoo 2013

-- In English --"An annotation is a note that is made while

reading any form of text."

something����������� ������������������  that����������� ������������������  describes����������� ������������������  an����������� ������������������  aspect����������� ������������������  of����������� ������������������  the����������� ������������������  subject

Page 7: Annotations in PHP - ConFoo 2013

“Annotations do not directly affect program semantics”

-- In Code Speak --

“An annotation is metadata attached to your code, that can be read at runtime.”

Page 8: Annotations in PHP - ConFoo 2013

“Annotations do not directly affect program semantics”

-- In Code Speak --

“An annotation is metadata attached to your code, that can be read at runtime.”

effects����������� ������������������  are����������� ������������������  only����������� ������������������  observed����������� ������������������  at

Page 9: Annotations in PHP - ConFoo 2013

“Annotations do not directly affect program semantics”

-- In Code Speak --

just����������� ������������������  like����������� ������������������  your����������� ������������������  notes

“An annotation is metadata attached to your code, that can be read at runtime.”

effects����������� ������������������  are����������� ������������������  only����������� ������������������  observed����������� ������������������  at

Page 10: Annotations in PHP - ConFoo 2013

Annotations in the wild

C#

Page 11: Annotations in PHP - ConFoo 2013

Annotations in the wild

annotations

C#attributes

Page 12: Annotations in PHP - ConFoo 2013

Annotations in the wild

annotations

C#attributes

@Entity @Table(name = "people") class Person implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id;

Page 13: Annotations in PHP - ConFoo 2013

Annotations in the wild

annotations

C#attributes

@Entity @Table(name = "people") class Person implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id;

public class Customer{ [Required] [StringLength(50)] public string Prename { get; set; } [Column(TypeName = "image")] public byte[] Image { get; set; }

Page 14: Annotations in PHP - ConFoo 2013

Annotations in the wild

annotations

C#attributes

after����������� ������������������  v1.5

@Entity @Table(name = "people") class Person implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id;

public class Customer{ [Required] [StringLength(50)] public string Prename { get; set; } [Column(TypeName = "image")] public byte[] Image { get; set; }

Page 15: Annotations in PHP - ConFoo 2013

Annotations in the wild

annotations

C#attributes

after����������� ������������������  v1.5

since����������� ������������������  first����������� ������������������  release

@Entity @Table(name = "people") class Person implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id;

public class Customer{ [Required] [StringLength(50)] public string Prename { get; set; } [Column(TypeName = "image")] public byte[] Image { get; set; }

Page 16: Annotations in PHP - ConFoo 2013
Page 17: Annotations in PHP - ConFoo 2013

No����������� ������������������  core����������� ������������������  annotation����������� ������������������  support

Page 18: Annotations in PHP - ConFoo 2013

Questions?

Page 19: Annotations in PHP - ConFoo 2013

Questions?

I’m����������� ������������������  kidding!

Page 20: Annotations in PHP - ConFoo 2013
Page 21: Annotations in PHP - ConFoo 2013
Page 22: Annotations in PHP - ConFoo 2013

phpDoc

~2000

Page 23: Annotations in PHP - ConFoo 2013

phpDoc

PHP����������� ������������������  5.1Reflection����������� ������������������  supports����������� ������������������  getDocComments()

~2000 2005

Page 24: Annotations in PHP - ConFoo 2013

First����������� ������������������  Annotation

����������� ������������������  Engines����������� ������������������  in����������� ������������������  PHP

phpDoc

PHP����������� ������������������  5.1Reflection����������� ������������������  supports����������� ������������������  getDocComments()

~2000 2005

Page 25: Annotations in PHP - ConFoo 2013

First����������� ������������������  Annotation

����������� ������������������  Engines����������� ������������������  in����������� ������������������  PHP

phpDoc

PHP����������� ������������������  5.1Reflection����������� ������������������  supports����������� ������������������  getDocComments()

~2000 2005 2008

Page 26: Annotations in PHP - ConFoo 2013

First����������� ������������������  Annotation

����������� ������������������  Engines����������� ������������������  in����������� ������������������  PHP

phpDoc

PHP����������� ������������������  5.1Reflection����������� ������������������  supports����������� ������������������  getDocComments()

~2000 2005 2008

Doctrine����������� ������������������  2����������� ������������������  Annotation����������� ������������������  Engine

Page 27: Annotations in PHP - ConFoo 2013

First����������� ������������������  Annotation

����������� ������������������  Engines����������� ������������������  in����������� ������������������  PHP

phpDoc

PHP����������� ������������������  5.1Reflection����������� ������������������  supports����������� ������������������  getDocComments()

~2000 2005 2008

Doctrine����������� ������������������  2����������� ������������������  Annotation����������� ������������������  Engine

2010

RFC:����������� ������������������  Annotations����������� ������������������  in����������� ������������������  core����������� ������������������  w/����������� ������������������  custom����������� ������������������  

syntax

Page 28: Annotations in PHP - ConFoo 2013

First����������� ������������������  Annotation

����������� ������������������  Engines����������� ������������������  in����������� ������������������  PHP

phpDoc

PHP����������� ������������������  5.1Reflection����������� ������������������  supports����������� ������������������  getDocComments()

~2000 2005 2008

Doctrine����������� ������������������  2����������� ������������������  Annotation����������� ������������������  Engine

2010

RFC:����������� ������������������  Annotations����������� ������������������  in����������� ������������������  core����������� ������������������  w/����������� ������������������  custom����������� ������������������  

syntaxREJECTED

Page 29: Annotations in PHP - ConFoo 2013

First����������� ������������������  Annotation

����������� ������������������  Engines����������� ������������������  in����������� ������������������  PHP

phpDoc

PHP����������� ������������������  5.1Reflection����������� ������������������  supports����������� ������������������  getDocComments()

~2000 2005 2008

Doctrine����������� ������������������  2����������� ������������������  Annotation����������� ������������������  Engine

2010

RFC:����������� ������������������  Annotations����������� ������������������  in����������� ������������������  core����������� ������������������  w/����������� ������������������  custom����������� ������������������  

syntax

2011

RFC:����������� ������������������  DocBlock����������� ������������������  Annotations

“in����������� ������������������  discussion”

REJECTED

Page 30: Annotations in PHP - ConFoo 2013

First����������� ������������������  Annotation

����������� ������������������  Engines����������� ������������������  in����������� ������������������  PHP

phpDoc

PHP����������� ������������������  5.1Reflection����������� ������������������  supports����������� ������������������  getDocComments()

~2000 2005 2008

Doctrine����������� ������������������  2����������� ������������������  Annotation����������� ������������������  Engine

2010

RFC:����������� ������������������  Annotations����������� ������������������  in����������� ������������������  core����������� ������������������  w/����������� ������������������  custom����������� ������������������  

syntax

2011

RFC:����������� ������������������  DocBlock����������� ������������������  Annotations

“in����������� ������������������  discussion”

REJECTED

2013

discussion����������� ������������������  sparks����������� ������������������  up����������� ������������������  again

Page 31: Annotations in PHP - ConFoo 2013

First����������� ������������������  Annotation

����������� ������������������  Engines����������� ������������������  in����������� ������������������  PHP

phpDoc

PHP����������� ������������������  5.1Reflection����������� ������������������  supports����������� ������������������  getDocComments()

~2000 2005 2008

Doctrine����������� ������������������  2����������� ������������������  Annotation����������� ������������������  Engine

2010

RFC:����������� ������������������  Annotations����������� ������������������  in����������� ������������������  core����������� ������������������  w/����������� ������������������  custom����������� ������������������  

syntax

2011

RFC:����������� ������������������  DocBlock����������� ������������������  Annotations

“in����������� ������������������  discussion”

REJECTED

?2013

discussion����������� ������������������  sparks����������� ������������������  up����������� ������������������  again

Page 32: Annotations in PHP - ConFoo 2013

Current situation in php-internals

Page 33: Annotations in PHP - ConFoo 2013

Current situation in php-internals

Page 34: Annotations in PHP - ConFoo 2013
Page 35: Annotations in PHP - ConFoo 2013

annotations

Page 36: Annotations in PHP - ConFoo 2013

annotations

/** * Entity\Reward * * @ORM\Table("reward") * @ORM\Entity(repositoryClass="RewardRepository") */ class Reward { /** * @var integer $id * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @var string $title * * @ORM\Column(name="title", type="string", length=150, nullable=true) * * @Assert\MaxLength(150) */ protected $title;

Page 37: Annotations in PHP - ConFoo 2013

annotations

/** * Entity\Reward * * @ORM\Table("reward") * @ORM\Entity(repositoryClass="RewardRepository") */ class Reward { /** * @var integer $id * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @var string $title * * @ORM\Column(name="title", type="string", length=150, nullable=true) * * @Assert\MaxLength(150) */ protected $title;

re-use����������� ������������������  of����������� ������������������  docblocks

Page 38: Annotations in PHP - ConFoo 2013

On docblocks vs. comments

Page 39: Annotations in PHP - ConFoo 2013

On docblocks vs. comments

T_COMMENT

// this is a comment/* This is a multiline comment */

Page 40: Annotations in PHP - ConFoo 2013

On docblocks vs. comments

T_COMMENT

T_DOC_COMMENT

// this is a comment/* This is a multiline comment */

/** * this is a docblock */

Page 41: Annotations in PHP - ConFoo 2013

On docblocks vs. comments

T_COMMENT

T_DOC_COMMENT

// this is a comment/* This is a multiline comment */

/** * this is a docblock */

ignored����������� ������������������  by����������� ������������������  opcode����������� ������������������  cache

Page 42: Annotations in PHP - ConFoo 2013

On docblocks vs. comments

T_COMMENT

T_DOC_COMMENT

// this is a comment/* This is a multiline comment */

/** * this is a docblock */

ignored����������� ������������������  by����������� ������������������  opcode����������� ������������������  cache

cached����������� ������������������  by����������� ������������������  opcode����������� ������������������  cache

Page 43: Annotations in PHP - ConFoo 2013
Page 44: Annotations in PHP - ConFoo 2013

public class Customer{ [Required] [StringLength(50)] public string Prename { get; set; } [Column(TypeName = "image")] public byte[] Image { get; set; }

@Entity @Table(name = "people") class Person implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id;

class Reward { /** * @var integer $id * @deprecated * @ORM\Column(name="id", type="integer") * @ORM\Id */ protected $id;

Page 45: Annotations in PHP - ConFoo 2013

public class Customer{ [Required] [StringLength(50)] public string Prename { get; set; } [Column(TypeName = "image")] public byte[] Image { get; set; }

@Entity @Table(name = "people") class Person implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id;

class Reward { /** * @var integer $id * @deprecated * @ORM\Column(name="id", type="integer") * @ORM\Id */ protected $id;

marker

Page 46: Annotations in PHP - ConFoo 2013

public class Customer{ [Required] [StringLength(50)] public string Prename { get; set; } [Column(TypeName = "image")] public byte[] Image { get; set; }

@Entity @Table(name = "people") class Person implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id;

class Reward { /** * @var integer $id * @deprecated * @ORM\Column(name="id", type="integer") * @ORM\Id */ protected $id;

marker

parameterized

Page 47: Annotations in PHP - ConFoo 2013

Why?Why����������� ������������������  sho

uld����������� ������������������  I����������� ������������������  use����������� ������������������  ann

otations?

http://ecdesignrebels.blogspot.com

Are����������� ������������������  annotations����������� ������������������  for����������� ������������������  you?

Page 48: Annotations in PHP - ConFoo 2013

I don’t know.

Page 49: Annotations in PHP - ConFoo 2013
Page 50: Annotations in PHP - ConFoo 2013

hate����������� ������������������  annotations

Page 51: Annotations in PHP - ConFoo 2013

hate����������� ������������������  annotations

love����������� ������������������  annotations

Page 52: Annotations in PHP - ConFoo 2013

hate����������� ������������������  annotations

love����������� ������������������  annotations

never����������� ������������������  used����������� ������������������  annotations

Page 53: Annotations in PHP - ConFoo 2013

but����������� ������������������  its����������� ������������������  code,����������� ������������������  in����������� ������������������  comments!docblocks

harder

The downside or why not

Page 54: Annotations in PHP - ConFoo 2013

but����������� ������������������  its����������� ������������������  code,����������� ������������������  in����������� ������������������  comments!docblocks

harder

The downside or why not

docblocks����������� ������������������  are����������� ������������������  first����������� ������������������  class����������� ������������������  citizens.

Page 55: Annotations in PHP - ConFoo 2013

Its����������� ������������������  impossible����������� ������������������  to����������� ������������������  debug/test!

harder

The downside or why not

Page 56: Annotations in PHP - ConFoo 2013

Its����������� ������������������  impossible����������� ������������������  to����������� ������������������  debug/test!

harder

The downside or why not

Test/debug����������� ������������������  annotation����������� ������������������  “executor”

Page 57: Annotations in PHP - ConFoo 2013

The downside or why not

It����������� ������������������  does����������� ������������������  not����������� ������������������  perform!

Page 58: Annotations in PHP - ConFoo 2013

The downside or why not

It����������� ������������������  does����������� ������������������  not����������� ������������������  perform!

Caching����������� ������������������  FTW!

Page 59: Annotations in PHP - ConFoo 2013

Why I love Annotations

Page 60: Annotations in PHP - ConFoo 2013

Easier����������� ������������������  to����������� ������������������  inject����������� ������������������  behavior����������� ������������������  without����������� ������������������  extending

Why I love Annotations

Page 61: Annotations in PHP - ConFoo 2013

Easier����������� ������������������  to����������� ������������������  inject����������� ������������������  behavior����������� ������������������  without����������� ������������������  extendingDoctrine����������� ������������������  1����������� ������������������  vs����������� ������������������  Doctrine����������� ������������������  2

Why I love Annotations

Page 62: Annotations in PHP - ConFoo 2013

Easier����������� ������������������  to����������� ������������������  inject����������� ������������������  behavior����������� ������������������  without����������� ������������������  extending

Contextualizes����������� ������������������  behavior/config����������� ������������������  in����������� ������������������  the����������� ������������������  object

Doctrine����������� ������������������  1����������� ������������������  vs����������� ������������������  Doctrine����������� ������������������  2

Why I love Annotations

Page 63: Annotations in PHP - ConFoo 2013

Easier����������� ������������������  to����������� ������������������  inject����������� ������������������  behavior����������� ������������������  without����������� ������������������  extending

Contextualizes����������� ������������������  behavior/config����������� ������������������  in����������� ������������������  the����������� ������������������  object

Doctrine����������� ������������������  1����������� ������������������  vs����������� ������������������  Doctrine����������� ������������������  2

In����������� ������������������  object����������� ������������������  vs.����������� ������������������  external����������� ������������������  configuration����������� ������������������  file

Why I love Annotations

Page 64: Annotations in PHP - ConFoo 2013

Easier����������� ������������������  to����������� ������������������  inject����������� ������������������  behavior����������� ������������������  without����������� ������������������  extending

Contextualizes����������� ������������������  behavior/config����������� ������������������  in����������� ������������������  the����������� ������������������  object

Doctrine����������� ������������������  1����������� ������������������  vs����������� ������������������  Doctrine����������� ������������������  2

In����������� ������������������  object����������� ������������������  vs.����������� ������������������  external����������� ������������������  configuration����������� ������������������  file

Its����������� ������������������  documented/stored����������� ������������������  by����������� ������������������  phpDocumentor

Why I love Annotations

Page 65: Annotations in PHP - ConFoo 2013

Easier����������� ������������������  to����������� ������������������  inject����������� ������������������  behavior����������� ������������������  without����������� ������������������  extending

Contextualizes����������� ������������������  behavior/config����������� ������������������  in����������� ������������������  the����������� ������������������  object

Doctrine����������� ������������������  1����������� ������������������  vs����������� ������������������  Doctrine����������� ������������������  2

In����������� ������������������  object����������� ������������������  vs.����������� ������������������  external����������� ������������������  configuration����������� ������������������  file

Its����������� ������������������  documented/stored����������� ������������������  by����������� ������������������  phpDocumentorIts����������� ������������������  in����������� ������������������  docblocks,����������� ������������������  so����������� ������������������  its����������� ������������������  parsed

Why I love Annotations

Page 66: Annotations in PHP - ConFoo 2013
Page 67: Annotations in PHP - ConFoo 2013
Page 68: Annotations in PHP - ConFoo 2013

<?php

class User{

protected $name

...

}

Page 69: Annotations in PHP - ConFoo 2013

<?php

class User{

protected $name

...

}

-����������� ������������������  persist����������� ������������������  as����������� ������������������  varchar

-����������� ������������������  length����������� ������������������  should����������� ������������������  not����������� ������������������  be����������� ������������������  

more����������� ������������������  then����������� ������������������  255

-����������� ������������������  should����������� ������������������  not����������� ������������������  be����������� ������������������  blank

-����������� ������������������  only����������� ������������������  letters

Page 70: Annotations in PHP - ConFoo 2013

<?php

class User{

protected $name

...

}

-����������� ������������������  persist����������� ������������������  as����������� ������������������  varchar

-����������� ������������������  length����������� ������������������  should����������� ������������������  not����������� ������������������  be����������� ������������������  

more����������� ������������������  then����������� ������������������  255

-����������� ������������������  should����������� ������������������  not����������� ������������������  be����������� ������������������  blank

-����������� ������������������  only����������� ������������������  letters

MyProject\User: properties: name: - NotBlank: ~ - MaxLength: 255

Validation

MyProject\User: filters: name: - alpha

filter

MyProject\User: type: entity table: users fields: name: type: string length: 255

persistence

Page 71: Annotations in PHP - ConFoo 2013

<?php

class User{

protected $name

...

}

MyProject\User: properties: name: - NotBlank: ~ - MaxLength: 255

Validation

MyProject\User: filters: name: - alpha

filter

MyProject\User: type: entity table: users fields: name: type: string length: 255

persistence

/** * @ORM\Column(‘string’, length=255) * @Assert\NotBlank() * @Assert\MaxLength(255) * @Filter\Alpha() */

Page 72: Annotations in PHP - ConFoo 2013

<?php

class User{

protected $name

...

}

/** * @ORM\Column(‘string’, length=255) * @Assert\NotBlank() * @Assert\MaxLength(255) * @Filter\Alpha() */

Page 73: Annotations in PHP - ConFoo 2013

Where?Where����������� ������������������  a

re����������� ������������������  annotatio

ns����������� ������������������  used?

http://ecdesignrebels.blogspot.com

Page 74: Annotations in PHP - ConFoo 2013

Where?Where����������� ������������������  a

re����������� ������������������  annotatio

ns����������� ������������������  used?

http://ecdesignrebels.blogspot.com

Page 75: Annotations in PHP - ConFoo 2013

class DataTest extends PHPUnit_Framework_TestCase { /** * @dataProvider provider * * @expectedException InvalidArgumentException * @expectedExceptionMessage Right Message */ public function testAdd($a, $b, $c) { /* Test code */ } public function provider() { return array( array(0, 0, 0), ); } }

expectations

repetition

Page 76: Annotations in PHP - ConFoo 2013

/** * @ORM\Table("myentity") * @ORM\Entity(repositoryClass="MyEntityRepository") */ class MyEntity { /** * @var integer $id * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @var string $title * * @ORM\Column(name="title", type="string", length=255) * @Assert\MaxLength(255) * @Assert\NotBlank() */ protected $title; /** * @var \Doctrine\Common\Collections\ArrayCollection $users * * @ORM\OneToMany(targetEntity="OtherEntity", mappedBy="myEntity", cascade={"persist","remove"}) */ protected $otherEntities; }

persistance

association

Page 77: Annotations in PHP - ConFoo 2013

/** * @Route("/myaction/{id}", name="myaction") * @Method("POST") * * @Template("MyBundle:MyController:my.html.twig") * * @param int $id * @return array */ public function myAction($id) { /* Controller Logic */ return array('data' => $data); }

class MyEntity { /** * @var string $title * * @ORM\Column(name="title", type="string", length=255) * @Assert\MaxLength(255) * @Assert\NotBlank() */ protected $title; }

routing

Validation

templating

Page 78: Annotations in PHP - ConFoo 2013

/** * @FLOW3\Aspect */ class LoggingAspect { /** * @FLOW3\Inject * @var \Examples\Forum\Logger\ApplicationLoggerInterface */ protected $applicationLogger; /** * Log a message if a post is deleted * * @param \TYPO3\FLOW3\AOP\JoinPointInterface $joinPoint * @FLOW3\Before("method(Examples\Forum\Domain\Model\Forum->deletePost())") * @return void */ public function logDeletePost(\TYPO3\FLOW3\AOP\JoinPointInterface $joinPoint) { $post = $joinPoint->getMethodArgument('post'); $this->applicationLogger->log('Removing post ' . $post->getTitle(), LOG_INFO); } }

Dependency����������� ������������������  Injection

AOP

Page 79: Annotations in PHP - ConFoo 2013

How?How����������� ������������������  can����������� ������������������  i����������� ������������������  

write����������� ������������������  my����������� ������������������  own����������� ������������������  

annotations?

http://ecdesignrebels.blogspot.com

Page 80: Annotations in PHP - ConFoo 2013

Annotations

My����������� ������������������  Project

Page 81: Annotations in PHP - ConFoo 2013

Annotations

My����������� ������������������  ProjectAnnotation����������� ������������������  

Engine

Page 82: Annotations in PHP - ConFoo 2013
Page 83: Annotations in PHP - ConFoo 2013

/** * @tag(parameters) */public function method()

Code

Page 84: Annotations in PHP - ConFoo 2013

/** * @tag(parameters) */public function method()

Code

ReflectionClass->getDocComment()

Page 85: Annotations in PHP - ConFoo 2013

DOCBlock

/** * @tag(parameters) */

/** * @tag(parameters) */public function method()

Code

ReflectionClass->getDocComment()

Page 86: Annotations in PHP - ConFoo 2013

DOCBlock

/** * @tag(parameters) */

Tag() + parameters

Annotation����������� ������������������  Instances

/** * @tag(parameters) */public function method()

Code

ReflectionClass->getDocComment()

Page 87: Annotations in PHP - ConFoo 2013

Doctrine����������� ������������������  Commons

phpDocumentor����������� ������������������  2

Notoj

Annotation Engines

php-annotations

https://github.com/doctrine/common

https://github.com/phpDocumentor/phpDocumentor2

https://github.com/mindplay-dk/php-annotations

https://github.com/crodas/Notoj

Page 88: Annotations in PHP - ConFoo 2013

Doctrine����������� ������������������  Commons

phpDocumentor����������� ������������������  2

Notoj

Annotation Engines

php-annotations

Page 89: Annotations in PHP - ConFoo 2013

Doctrine����������� ������������������  Commons

phpDocumentor����������� ������������������  2

Notoj

Annotation Engines

php-annotations

2.3

2.0

1.1

-

Page 90: Annotations in PHP - ConFoo 2013

Doctrine����������� ������������������  Commons

phpDocumentor����������� ������������������  2

Notoj

Annotation Engines

php-annotations

2.3

2.0

1.1

-

Page 91: Annotations in PHP - ConFoo 2013

Doctrine����������� ������������������  Commons

phpDocumentor����������� ������������������  2

Notoj

Annotation Engines

php-annotations

2.3

2.0

1.1

-

Page 92: Annotations in PHP - ConFoo 2013

Doctrine����������� ������������������  Commons

phpDocumentor����������� ������������������  2

Notoj

Annotation Engines

php-annotations

2.3

2.0

1.1

-

full����������� ������������������  support

only����������� ������������������  string����������� ������������������  

full����������� ������������������  support

full����������� ������������������  support

Page 93: Annotations in PHP - ConFoo 2013

Doctrine����������� ������������������  Commons

phpDocumentor����������� ������������������  2

Notoj

Annotation Engines

php-annotations

2.3

2.0

1.1

-

full����������� ������������������  support

only����������� ������������������  string����������� ������������������  

full����������� ������������������  support

full����������� ������������������  support

Page 94: Annotations in PHP - ConFoo 2013

Doctrine����������� ������������������  Commons

phpDocumentor����������� ������������������  2

Notoj

Annotation Engines

php-annotations

2.3

2.0

1.1

-

full����������� ������������������  support

only����������� ������������������  string����������� ������������������  

full����������� ������������������  support

full����������� ������������������  support

Page 95: Annotations in PHP - ConFoo 2013

How����������� ������������������  it����������� ������������������  Works

<?php

/** * @ORM\Column(‘string’) * @Assert\NotBlank() */

use Doctrine\ORM\Mapping as ORM;use Symfony\Component\Validator\ Constraints as Assert;

Page 96: Annotations in PHP - ConFoo 2013

How����������� ������������������  it����������� ������������������  Works

<?php

/** * @ORM\Column(‘string’) * @Assert\NotBlank() */

use Doctrine\ORM\Mapping as ORM;use Symfony\Component\Validator\ Constraints as Assert;

Declare����������� ������������������  which����������� ������������������  Annotations����������� ������������������  you����������� ������������������  will����������� ������������������  use

Page 97: Annotations in PHP - ConFoo 2013

How����������� ������������������  it����������� ������������������  Works

AnnotationReader<?php

/** * @ORM\Column(‘string’) * @Assert\NotBlank() */

use Doctrine\ORM\Mapping as ORM;use Symfony\Component\Validator\ Constraints as Assert;

Declare����������� ������������������  which����������� ������������������  Annotations����������� ������������������  you����������� ������������������  will����������� ������������������  use

Page 98: Annotations in PHP - ConFoo 2013

How����������� ������������������  it����������� ������������������  Works

AnnotationReader<?php

/** * @ORM\Column(‘string’) * @Assert\NotBlank() */

new ORM\Column(‘string’)new Assert\NotBlank()

“metadata”

use Doctrine\ORM\Mapping as ORM;use Symfony\Component\Validator\ Constraints as Assert;

Declare����������� ������������������  which����������� ������������������  Annotations����������� ������������������  you����������� ������������������  will����������� ������������������  use

Page 99: Annotations in PHP - ConFoo 2013

How����������� ������������������  it����������� ������������������  Works

AnnotationReader<?php

/** * @ORM\Column(‘string’) * @Assert\NotBlank() */

new ORM\Column(‘string’)new Assert\NotBlank()

Cache

“metadata”

Walker����������� ������������������  /����������� ������������������  code

use Doctrine\ORM\Mapping as ORM;use Symfony\Component\Validator\ Constraints as Assert;

Declare����������� ������������������  which����������� ������������������  Annotations����������� ������������������  you����������� ������������������  will����������� ������������������  use

Page 100: Annotations in PHP - ConFoo 2013

Input Filtering

DMS\Filter: https://github.com/rdohms/DMS

Page 101: Annotations in PHP - ConFoo 2013

Input Filtering

DMS\Filter: https://github.com/rdohms/DMS

With����������� ������������������  Annotation����������� ������������������  Support!

Page 102: Annotations in PHP - ConFoo 2013

Ingredients:

-����������� ������������������  Filter����������� ������������������  Rules-����������� ������������������  Filter����������� ������������������  Executioners-����������� ������������������  Filter����������� ������������������  Service-����������� ������������������  Annotation����������� ������������������  Engine-����������� ������������������  Annotated����������� ������������������  Objects

the����������� ������������������  annotation����������� ������������������  /����������� ������������������  metadata,����������� ������������������  configuration

applies����������� ������������������  the����������� ������������������  rules

the����������� ������������������  middle-man

gets����������� ������������������  the����������� ������������������  rules����������� ������������������  out����������� ������������������  of����������� ������������������  the����������� ������������������  docblocks

defines����������� ������������������  the����������� ������������������  rules

Page 103: Annotations in PHP - ConFoo 2013

Filter����������� ������������������  Service

Filter����������� ������������������  EnforcerFiltered����������� ������������������  values

annotated����������� ������������������  object@Filter\StripTags(‘<b><i>’)

$executioner = new Filter\StripTags();$executioner->filter($metadata, $value);

<p>Hello����������� ������������������  <b>World</b></p>

Hello����������� ������������������  <b>World</b>

“Configured”����������� ������������������  Rulesnew Rules\StripTags(‘<b><i>’);

Annotation����������� ������������������  Engine

Page 104: Annotations in PHP - ConFoo 2013

The “rule”

Page 105: Annotations in PHP - ConFoo 2013

<?php namespace DMS\Filter\Rules; /** * StripTags Rule * * @Annotation */ class StripTags extends Rule { /** * String of allowed tags. Ex: <b><i><a> * * @var string */ public $allowed = null; /** * {@inheritDoc} */ public function getDefaultOption() { return 'allowed'; } }

Usage:����������� ������������������  use DMS\Filter\Rules as Filter;

@Filter\StripTags(‘<b><i>’)

Page 106: Annotations in PHP - ConFoo 2013

<?php namespace DMS\Filter\Rules; /** * StripTags Rule * * @Annotation */ class StripTags extends Rule { /** * String of allowed tags. Ex: <b><i><a> * * @var string */ public $allowed = null; /** * {@inheritDoc} */ public function getDefaultOption() { return 'allowed'; } }

tell����������� ������������������  doctrine����������� ������������������  this����������� ������������������  is����������� ������������������  an����������� ������������������  annotation

Usage:����������� ������������������  use DMS\Filter\Rules as Filter;

@Filter\StripTags(‘<b><i>’)

Page 107: Annotations in PHP - ConFoo 2013

<?php namespace DMS\Filter\Rules; /** * StripTags Rule * * @Annotation */ class StripTags extends Rule { /** * String of allowed tags. Ex: <b><i><a> * * @var string */ public $allowed = null; /** * {@inheritDoc} */ public function getDefaultOption() { return 'allowed'; } }

tell����������� ������������������  doctrine����������� ������������������  this����������� ������������������  is����������� ������������������  an����������� ������������������  annotation

Usage:����������� ������������������  use DMS\Filter\Rules as Filter;

@Filter\StripTags(‘<b><i>’)

DMS\Filter\Rules\Rule:

public function __construct($options = null)

Page 108: Annotations in PHP - ConFoo 2013

/** * @My\Annotation(“name”, nullable=true) */

Page 109: Annotations in PHP - ConFoo 2013

/** * @My\Annotation(“name”, nullable=true) */

defaultProperty

Page 110: Annotations in PHP - ConFoo 2013

/** * @My\Annotation(“name”, nullable=true) */

new My\Annotation($options);

defaultProperty

Page 111: Annotations in PHP - ConFoo 2013

/** * @My\Annotation(“name”, nullable=true) */

new My\Annotation($options);

array:����������� ������������������  key����������� ������������������  =>����������� ������������������  valueor

string:����������� ������������������  value

defaultProperty

Page 112: Annotations in PHP - ConFoo 2013

/** * @My\Annotation(“name”, nullable=true) */

new My\Annotation($options);

array:����������� ������������������  key����������� ������������������  =>����������� ������������������  valueor

string:����������� ������������������  value

defaultProperty

or

Page 113: Annotations in PHP - ConFoo 2013

/** * @My\Annotation(“name”, nullable=true) */

new My\Annotation($options);

$a = new My\Annotation();$a->nullable = true;$a->{$a->getDefaultProperty()} = “name”;

array:����������� ������������������  key����������� ������������������  =>����������� ������������������  valueor

string:����������� ������������������  value

defaultProperty

or

Page 114: Annotations in PHP - ConFoo 2013

The “enforcer”

Page 115: Annotations in PHP - ConFoo 2013

<?php namespace DMS\Filter\Filters; use DMS\Filter\Rules\Rule; /** * StripTags Rule * * @package DMS * @subpackage Filter * * @Annotation */ class StripTags extends BaseFilter { /** * {@inheritDoc} * * @param \DMS\Filter\Rules\StripTags $filter * @param mixed $filter */ public function apply( Rule $filter, $value) { return strip_tags($value, $filter->allowed); } }

Page 116: Annotations in PHP - ConFoo 2013

<?php namespace DMS\Filter\Filters; use DMS\Filter\Rules\Rule; /** * StripTags Rule * * @package DMS * @subpackage Filter * * @Annotation */ class StripTags extends BaseFilter { /** * {@inheritDoc} * * @param \DMS\Filter\Rules\StripTags $filter * @param mixed $filter */ public function apply( Rule $filter, $value) { return strip_tags($value, $filter->allowed); } }

Does����������� ������������������  the����������� ������������������  filtering

Page 117: Annotations in PHP - ConFoo 2013

<?php namespace DMS\Filter\Filters; use DMS\Filter\Rules\Rule; /** * StripTags Rule * * @package DMS * @subpackage Filter * * @Annotation */ class StripTags extends BaseFilter { /** * {@inheritDoc} * * @param \DMS\Filter\Rules\StripTags $filter * @param mixed $filter */ public function apply( Rule $filter, $value) { return strip_tags($value, $filter->allowed); } }

Does����������� ������������������  the����������� ������������������  filtering

Rule����������� ������������������  has����������� ������������������  the����������� ������������������  configuration.Ex:����������� ������������������  allowed����������� ������������������  tags

Page 118: Annotations in PHP - ConFoo 2013

The Filter Service

Page 119: Annotations in PHP - ConFoo 2013

The����������� ������������������  Life����������� ������������������  of����������� ������������������  a����������� ������������������  Filter����������� ������������������  Service

Page 120: Annotations in PHP - ConFoo 2013

The����������� ������������������  Life����������� ������������������  of����������� ������������������  a����������� ������������������  Filter����������� ������������������  Service

09:00����������� ������������������  -����������� ������������������  DIC����������� ������������������  wake-up����������� ������������������  call new FilterService($reader);

Page 121: Annotations in PHP - ConFoo 2013

The����������� ������������������  Life����������� ������������������  of����������� ������������������  a����������� ������������������  Filter����������� ������������������  Service

09:00����������� ������������������  -����������� ������������������  DIC����������� ������������������  wake-up����������� ������������������  call

09:05����������� ������������������  -����������� ������������������  Reply����������� ������������������  to����������� ������������������  emergency����������� ������������������  filter����������� ������������������  call

new FilterService($reader);

$service->filter($object);

Page 122: Annotations in PHP - ConFoo 2013

The����������� ������������������  Life����������� ������������������  of����������� ������������������  a����������� ������������������  Filter����������� ������������������  Service

09:00����������� ������������������  -����������� ������������������  DIC����������� ������������������  wake-up����������� ������������������  call

09:05����������� ������������������  -����������� ������������������  Reply����������� ������������������  to����������� ������������������  emergency����������� ������������������  filter����������� ������������������  call

09:06����������� ������������������  -����������� ������������������  Get����������� ������������������  Annotations����������� ������������������  for����������� ������������������  properties

new FilterService($reader);

$service->filter($object);

$reader->getPropertyAnnotations($p);

$a = array(StripTags(), Alpha());

Page 123: Annotations in PHP - ConFoo 2013

The����������� ������������������  Life����������� ������������������  of����������� ������������������  a����������� ������������������  Filter����������� ������������������  Service

09:00����������� ������������������  -����������� ������������������  DIC����������� ������������������  wake-up����������� ������������������  call

09:05����������� ������������������  -����������� ������������������  Reply����������� ������������������  to����������� ������������������  emergency����������� ������������������  filter����������� ������������������  call

09:06����������� ������������������  -����������� ������������������  Get����������� ������������������  Annotations����������� ������������������  for����������� ������������������  properties

09:07����������� ������������������  -����������� ������������������  Track����������� ������������������  down����������� ������������������  the����������� ������������������  Filters

new FilterService($reader);

$service->filter($object);

$reader->getPropertyAnnotations($p);

$a = array(StripTags(), Alpha());

new Filters\StripTags();

Page 124: Annotations in PHP - ConFoo 2013

The����������� ������������������  Life����������� ������������������  of����������� ������������������  a����������� ������������������  Filter����������� ������������������  Service

09:00����������� ������������������  -����������� ������������������  DIC����������� ������������������  wake-up����������� ������������������  call

09:05����������� ������������������  -����������� ������������������  Reply����������� ������������������  to����������� ������������������  emergency����������� ������������������  filter����������� ������������������  call

09:06����������� ������������������  -����������� ������������������  Get����������� ������������������  Annotations����������� ������������������  for����������� ������������������  properties

09:07����������� ������������������  -����������� ������������������  Track����������� ������������������  down����������� ������������������  the����������� ������������������  Filters

09:08����������� ������������������  -����������� ������������������  Get����������� ������������������  values����������� ������������������  filtered

new FilterService($reader);

$service->filter($object);

$reader->getPropertyAnnotations($p);

$a = array(StripTags(), Alpha());

new Filters\StripTags();

$filter->apply($rule, $value);

Page 125: Annotations in PHP - ConFoo 2013

The����������� ������������������  Life����������� ������������������  of����������� ������������������  a����������� ������������������  Filter����������� ������������������  Service

09:00����������� ������������������  -����������� ������������������  DIC����������� ������������������  wake-up����������� ������������������  call

09:05����������� ������������������  -����������� ������������������  Reply����������� ������������������  to����������� ������������������  emergency����������� ������������������  filter����������� ������������������  call

09:06����������� ������������������  -����������� ������������������  Get����������� ������������������  Annotations����������� ������������������  for����������� ������������������  properties

09:07����������� ������������������  -����������� ������������������  Track����������� ������������������  down����������� ������������������  the����������� ������������������  Filters

09:08����������� ������������������  -����������� ������������������  Get����������� ������������������  values����������� ������������������  filtered

09:10����������� ������������������  -����������� ������������������  Update����������� ������������������  the����������� ������������������  object����������� ������������������  with����������� ������������������  new����������� ������������������  data

new FilterService($reader);

$service->filter($object);

$reader->getPropertyAnnotations($p);

$a = array(StripTags(), Alpha());

new Filters\StripTags();

$filter->apply($rule, $value);

$object->prop = $newValue;

Page 126: Annotations in PHP - ConFoo 2013

The����������� ������������������  Life����������� ������������������  of����������� ������������������  a����������� ������������������  Filter����������� ������������������  Service

09:00����������� ������������������  -����������� ������������������  DIC����������� ������������������  wake-up����������� ������������������  call

09:05����������� ������������������  -����������� ������������������  Reply����������� ������������������  to����������� ������������������  emergency����������� ������������������  filter����������� ������������������  call

09:06����������� ������������������  -����������� ������������������  Get����������� ������������������  Annotations����������� ������������������  for����������� ������������������  properties

09:07����������� ������������������  -����������� ������������������  Track����������� ������������������  down����������� ������������������  the����������� ������������������  Filters

09:08����������� ������������������  -����������� ������������������  Get����������� ������������������  values����������� ������������������  filtered

09:10����������� ������������������  -����������� ������������������  Update����������� ������������������  the����������� ������������������  object����������� ������������������  with����������� ������������������  new����������� ������������������  data

09:11����������� ������������������  -����������� ������������������  send����������� ������������������  the����������� ������������������  object����������� ������������������  on����������� ������������������  its����������� ������������������  way

new FilterService($reader);

$service->filter($object);

$reader->getPropertyAnnotations($p);

$a = array(StripTags(), Alpha());

new Filters\StripTags();

$filter->apply($rule, $value);

$object->prop = $newValue;

return $object;

Page 127: Annotations in PHP - ConFoo 2013

The����������� ������������������  Life����������� ������������������  of����������� ������������������  a����������� ������������������  Filter����������� ������������������  Service

09:00����������� ������������������  -����������� ������������������  DIC����������� ������������������  wake-up����������� ������������������  call

09:05����������� ������������������  -����������� ������������������  Reply����������� ������������������  to����������� ������������������  emergency����������� ������������������  filter����������� ������������������  call

09:06����������� ������������������  -����������� ������������������  Get����������� ������������������  Annotations����������� ������������������  for����������� ������������������  properties

09:07����������� ������������������  -����������� ������������������  Track����������� ������������������  down����������� ������������������  the����������� ������������������  Filters

09:08����������� ������������������  -����������� ������������������  Get����������� ������������������  values����������� ������������������  filtered

09:10����������� ������������������  -����������� ������������������  Update����������� ������������������  the����������� ������������������  object����������� ������������������  with����������� ������������������  new����������� ������������������  data

09:11����������� ������������������  -����������� ������������������  send����������� ������������������  the����������� ������������������  object����������� ������������������  on����������� ������������������  its����������� ������������������  way

new FilterService($reader);

$service->filter($object);

$reader->getPropertyAnnotations($p);

$a = array(StripTags(), Alpha());

new Filters\StripTags();

$filter->apply($rule, $value);

$object->prop = $newValue;

return $object;

09:12����������� ������������������  -����������� ������������������  DO����������� ������������������  IT����������� ������������������  ALL����������� ������������������  AGAIN!

Page 128: Annotations in PHP - ConFoo 2013

The����������� ������������������  Life����������� ������������������  of����������� ������������������  a����������� ������������������  Filter����������� ������������������  Service

09:00����������� ������������������  -����������� ������������������  DIC����������� ������������������  wake-up����������� ������������������  call

09:05����������� ������������������  -����������� ������������������  Reply����������� ������������������  to����������� ������������������  emergency����������� ������������������  filter����������� ������������������  call

09:06����������� ������������������  -����������� ������������������  Get����������� ������������������  Annotations����������� ������������������  for����������� ������������������  properties

09:07����������� ������������������  -����������� ������������������  Track����������� ������������������  down����������� ������������������  the����������� ������������������  Filters

09:08����������� ������������������  -����������� ������������������  Get����������� ������������������  values����������� ������������������  filtered

09:10����������� ������������������  -����������� ������������������  Update����������� ������������������  the����������� ������������������  object����������� ������������������  with����������� ������������������  new����������� ������������������  data

09:11����������� ������������������  -����������� ������������������  send����������� ������������������  the����������� ������������������  object����������� ������������������  on����������� ������������������  its����������� ������������������  way

new FilterService($reader);

$service->filter($object);

$reader->getPropertyAnnotations($p);

$a = array(StripTags(), Alpha());

new Filters\StripTags();

$filter->apply($rule, $value);

$object->prop = $newValue;

return $object;

09:12����������� ������������������  -����������� ������������������  DO����������� ������������������  IT����������� ������������������  ALL����������� ������������������  AGAIN!

Page 129: Annotations in PHP - ConFoo 2013

//Iterate over all annotations foreach($this->reader->getPropertyAnnotations($property) as $rule) { //Skip is its not a rule if ( ! $rule instanceof Rules\Rule ) continue; //Add Rule $metadata->addPropertyRule($property->getName(), $rule); }

Page 130: Annotations in PHP - ConFoo 2013

//Iterate over all annotations foreach($this->reader->getPropertyAnnotations($property) as $rule) { //Skip is its not a rule if ( ! $rule instanceof Rules\Rule ) continue; //Add Rule $metadata->addPropertyRule($property->getName(), $rule); }

get����������� ������������������  all����������� ������������������  annotation����������� ������������������  objects

Page 131: Annotations in PHP - ConFoo 2013

//Iterate over all annotations foreach($this->reader->getPropertyAnnotations($property) as $rule) { //Skip is its not a rule if ( ! $rule instanceof Rules\Rule ) continue; //Add Rule $metadata->addPropertyRule($property->getName(), $rule); }

get����������� ������������������  all����������� ������������������  annotation����������� ������������������  objects

filter����������� ������������������  out����������� ������������������  “our”����������� ������������������  annotations

Page 132: Annotations in PHP - ConFoo 2013

//Iterate over all annotations foreach($this->reader->getPropertyAnnotations($property) as $rule) { //Skip is its not a rule if ( ! $rule instanceof Rules\Rule ) continue; //Add Rule $metadata->addPropertyRule($property->getName(), $rule); }

glorified����������� ������������������  array

get����������� ������������������  all����������� ������������������  annotation����������� ������������������  objects

filter����������� ������������������  out����������� ������������������  “our”����������� ������������������  annotations

Page 133: Annotations in PHP - ConFoo 2013

Necessary Object Calisthenics Disclaimer

FilterService

MetadataFactory ObjectWalker

Loader Cache

Reader ReflectionPropertyCache

Page 134: Annotations in PHP - ConFoo 2013

//Get Doctrine Reader $reader = new Annotations\AnnotationReader(); $reader->setEnableParsePhpImports(true); //Load AnnotationLoader $loader = new Mapping\Loader\AnnotationLoader($reader); $this->loader = $loader; //Get a MetadataFactory $metadataFactory = new Mapping\ClassMetadataFactory($loader); //Get a Filter $filter = new DMS\Filter\Filter($metadataFactory); //Get your Entity $user = new App\Entity\User(); $user->name = "My <b>name</b>"; $user->email = " [email protected]"; //Filter you entity $filter->filter($user); echo $user->name; //"My name" echo $user->email; //"[email protected]"

Page 135: Annotations in PHP - ConFoo 2013

//Get Doctrine Reader $reader = new Annotations\AnnotationReader(); $reader->setEnableParsePhpImports(true); //Load AnnotationLoader $loader = new Mapping\Loader\AnnotationLoader($reader); $this->loader = $loader; //Get a MetadataFactory $metadataFactory = new Mapping\ClassMetadataFactory($loader); //Get a Filter $filter = new DMS\Filter\Filter($metadataFactory); //Get your Entity $user = new App\Entity\User(); $user->name = "My <b>name</b>"; $user->email = " [email protected]"; //Filter you entity $filter->filter($user); echo $user->name; //"My name" echo $user->email; //"[email protected]"

put����������� ������������������  this����������� ������������������  in����������� ������������������  your����������� ������������������  DIC

Page 136: Annotations in PHP - ConFoo 2013

//Get Doctrine Reader $reader = new Annotations\AnnotationReader(); $reader->setEnableParsePhpImports(true); //Load AnnotationLoader $loader = new Mapping\Loader\AnnotationLoader($reader); $this->loader = $loader; //Get a MetadataFactory $metadataFactory = new Mapping\ClassMetadataFactory($loader); //Get a Filter $filter = new DMS\Filter\Filter($metadataFactory); //Get your Entity $user = new App\Entity\User(); $user->name = "My <b>name</b>"; $user->email = " [email protected]"; //Filter you entity $filter->filter($user); echo $user->name; //"My name" echo $user->email; //"[email protected]"

Calling����������� ������������������  the����������� ������������������  Service

put����������� ������������������  this����������� ������������������  in����������� ������������������  your����������� ������������������  DIC

Page 137: Annotations in PHP - ConFoo 2013

What? Why? Where?

How?

Page 138: Annotations in PHP - ConFoo 2013

Questions?

https://joind.in/7912

on����������� ������������������  twitterthese����������� ������������������  slides����������� ������������������  will����������� ������������������  be����������� ������������������  here

Rate����������� ������������������  me,����������� ������������������  please!

http://slides.doh.ms

http://doh.ms

@rdohms