annotations in php, they exist

Post on 15-Jan-2015

2.734 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

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

TRANSCRIPT

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

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

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

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

I’m a Brazilian, living in Amsterdamwhich means I’m probably crazy,

and I speak with my hands

I’m a developer and speaker for… ever.ok its something like 14 years

I’m a serial User Group creatorI can’t help it

I have absolutely no solid Laravel experience

I have absolutely no solid Laravel experienceI’m sorry.

I have absolutely no solid Laravel experienceI’m sorry.

I have absolutely no solid Laravel experienceI’m sorry.

Don’t throw tomatoes

photo by araswami

I have absolutely no solid Laravel experienceI’m sorry.

Don’t throw tomatoes

I’m allergic.

photo by araswami

What? Why? Where?

How?

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

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

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

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

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

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

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

s?

http://ecdesignrebels.blogspot.com

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

reading any form of text."

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

reading any form of text."

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

“Annotations do not directly affect program semantics”

-- In Code Speak --

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

“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

“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

Annotations in the wild

C#

Annotations in the wild

annotations

C#attributes

Annotations in the wild

annotations

C#attributes

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

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; }

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; }

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; }

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

Questions?

Questions?

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

phpDoc

~2000

phpDoc

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

~2000 2005

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

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

phpDoc

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

~2000 2005

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

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

phpDoc

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

~2000 2005 2008

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

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

phpDoc

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

~2000 2005 2008

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

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

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

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

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

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

Current situation in php-internals

Current situation in php-internals

annotations

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;

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

On docblocks vs. comments

On docblocks vs. comments

T_COMMENT

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

On docblocks vs. comments

T_COMMENT

T_DOC_COMMENT

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

/** ! * this is a docblock! */

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

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

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;

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

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

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

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

otations?

http://ecdesignrebels.blogspot.com

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

I don’t know.

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

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

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

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

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

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

Let’s have an argumentphoto by Adam Arroyo

photo by Adam Arroyo

its code and its in my comment blocks

photo by Adam Arroyo

its code and its in my comment blocks

they are docblocks

photo by Adam Arroyo

its code and its in my comment blocks

docblocks are first-class citizens

they are docblocks

photo by Adam Arroyo

photo by Adam Arroyo

“Annotations and comments are like water and oil, just because they are in the same container, does

not mean they mix”!

—- @rosstuck

photo by Adam Arroyo

photo by Adam Arroyo

its impossible to test or debug

photo by Adam Arroyo

its impossible to test or debug

annotations are tags and config

photo by Adam Arroyo

its impossible to test or debug

don’t test the annotation, test the object that uses it

annotations are tags and config

photo by Adam Arroyo

photo by Adam Arroyo

all that parsing, it can’t perform!

photo by Adam Arroyo

all that parsing, it can’t perform!

caching!

photo by Adam Arroyo

I ❤️ Annotations

I ❤️ AnnotationsContextualizes����������� ������������������  behavior/config����������� ������������������  in����������� ������������������  the����������� ������������������  object

I ❤️ AnnotationsContextualizes����������� ������������������  behavior/config����������� ������������������  in����������� ������������������  the����������� ������������������  object

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

I ❤️ AnnotationsContextualizes����������� ������������������  behavior/config����������� ������������������  in����������� ������������������  the����������� ������������������  object

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

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

I ❤️ AnnotationsContextualizes����������� ������������������  behavior/config����������� ������������������  in����������� ������������������  the����������� ������������������  object

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

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

<?php

class User!{!!!!!!!!protected $name!!!...!!!!!!!

}

<?php

class User!{!!!!!!!!protected $name!!!...!!!!!!!

}

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

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

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

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

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

<?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

<?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()! */

<?php

class User!{!!!!!!!!protected $name!!!...!!!!!!!

}

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

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

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

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

http://ecdesignrebels.blogspot.com

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

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

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

http://ecdesignrebels.blogspot.com

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

/** ! * @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

/** ! * @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

/** ! * @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

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

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

annotations?

http://ecdesignrebels.blogspot.com

Annotations

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

Annotations

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

Engine

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

Code

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

Code

ReflectionClass->getDocComment()

DOCBlock

/**! * @tag(parameters)! */

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

Code

ReflectionClass->getDocComment()

DOCBlock

/**! * @tag(parameters)! */

Tag() + parameters

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

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

Code

ReflectionClass->getDocComment()

Doctrine����������� ������������������  Annotations

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

Notoj

Annotation Engines

php-annotations

https://github.com/doctrine/annotations

https://github.com/phpDocumentor/phpDocumentor2

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

https://github.com/crodas/Notoj

Doctrine����������� ������������������  Annotations

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

Notoj

Annotation Engines

php-annotations

Doctrine����������� ������������������  Annotations

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

Notoj

Annotation Engines

php-annotations

1.1.2

2.0.2

1.1

0.16.1

Doctrine����������� ������������������  Annotations

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

Notoj

Annotation Engines

php-annotations

1.1.2

2.0.2

1.1

0.16.1

Doctrine����������� ������������������  Annotations

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

Notoj

Annotation Engines

php-annotations

1.1.2

2.0.2

1.1

0.16.1

doctrine/annotations

phpdocumentor/reflection-docblock

mindplay/annotations

crodas/notoj

Doctrine����������� ������������������  Annotations

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

Notoj

Annotation Engines

php-annotations

1.1.2

2.0.2

1.1

0.16.1

doctrine/annotations

phpdocumentor/reflection-docblock

mindplay/annotations

crodas/notoj

Doctrine����������� ������������������  Annotations

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

Notoj

Annotation Engines

php-annotations

1.1.2

2.0.2

1.1

0.16.1

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

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

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

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

doctrine/annotations

phpdocumentor/reflection-docblock

mindplay/annotations

crodas/notoj

Doctrine����������� ������������������  Annotations

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

Notoj

Annotation Engines

php-annotations

1.1.2

2.0.2

1.1

0.16.1

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

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

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

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

doctrine/annotations

phpdocumentor/reflection-docblock

mindplay/annotations

crodas/notoj

Doctrine����������� ������������������  Annotations

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

Notoj

Annotation Engines

php-annotations

1.1.2

2.0.2

1.1

0.16.1

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

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

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

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

doctrine/annotations

phpdocumentor/reflection-docblock

mindplay/annotations

crodas/notoj

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

<?php

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

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

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

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

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

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

Input Filtering

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

Input Filtering

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

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

A short note on the word "filter"

Filters everywhere!

AnnotatedObject

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

Rules:Rules are objects that represent the annotationsnew Rules\StripTags(‘<b><i>’);

Filters:Filters are the executioners, they apply the effect of a rule$executioner = new Filter\StripTags();!$executioner->filter($metadata, $value);

Filter Service

Filter Service:Orchestrates the process of extracting values, filtering and replacing original values

Annotation Engine

Annotation Engine:Extracts string values into instances of rules for the Filter Service to parse

Filter Service

AnnotatedObject

Annotation Engine

Filter Service

AnnotatedObject

Annotation Engine

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

The “rule”

<?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>’)

<?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>’)

<?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)

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

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

defaultProperty

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

new My\Annotation($options);

defaultProperty

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

new My\Annotation($options);

array:����������� ������������������  key����������� ������������������  =>����������� ������������������  value����������� ������������������  or����������� ������������������  

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

defaultProperty

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

new My\Annotation($options);

array:����������� ������������������  key����������� ������������������  =>����������� ������������������  value����������� ������������������  or����������� ������������������  

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

defaultProperty

or

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

new My\Annotation($options);

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

array:����������� ������������������  key����������� ������������������  =>����������� ������������������  value����������� ������������������  or����������� ������������������  

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

defaultProperty

or

The “filter” or "executioner"

<?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); ! } !} !

<?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

<?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

The Filter Service

$service = new FilterService($reader);

Instantiate the service (DIC)

$service = new FilterService($reader);

$service->filter($object);

Instantiate the service (DIC)

Call for an object to be filtered

$service = new FilterService($reader);

$service->filter($object);

$reader->getPropertyAnnotations($object); //$a = array(Rule\StripTags(), Rule\Alpha());

Instantiate the service (DIC)

Call for an object to be filtered

The service uses the reader to read annotations and get the rule objects

$service = new FilterService($reader);

$service->filter($object);

$reader->getPropertyAnnotations($object); //$a = array(Rule\StripTags(), Rule\Alpha());

$object->prop = $filter->apply($rule, $object->prop);

Instantiate the service (DIC)

Call for an object to be filtered

The service uses the reader to read annotations and get the rule objects

Service resolves Rules into Filter objects, applies and overrides object

//new Filters\StripTags();

//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); ! !}

//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

//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

//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

Necessary Object Calisthenics Disclaimer

FilterService

MetadataFactory ObjectWalker

Loader Cache

Reader ReflectionPropertyCache

//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@mail.com"; ! ! //Filter you entity ! $filter->filter($user); ! ! echo $user->name; //"My name" ! echo $user->email; //"email@mail.com" !

//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@mail.com"; ! ! //Filter you entity ! $filter->filter($user); ! ! echo $user->name; //"My name" ! echo $user->email; //"email@mail.com" !

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

//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@mail.com"; ! ! //Filter you entity ! $filter->filter($user); ! ! echo $user->name; //"My name" ! echo $user->email; //"email@mail.com" !

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

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

What? Why? Where?

How?

Questions?

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

http://slides.doh.ms

http://doh.ms

@rdohms

https://joind.in/11694

top related