php annotations: they exist! - jetbrains webinar

Post on 08-Sep-2014

36.129 Views

Category:

Technology

0 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!

phot

o cr

edit:

Eli W

hite

Evangelist, Speaker and Contributor.

!Enabler at AmsterdamPHP.

Rafael Dohms@rdohms

drop����������� ������������������  by����������� ������������������  if����������� ������������������  you����������� ������������������  are����������� ������������������  in����������� ������������������  Amsterdam!

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

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

harder

The downside or why not

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

harder

The downside or why not

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

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

harder

The downside or why not

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

harder

The downside or why not

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

The downside or why not

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

The downside or why not

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

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

Why I love Annotations

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

Why I love Annotations

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

Why I love Annotations

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

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

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

Why I love Annotations

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

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

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

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

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

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

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 “enforcer”

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

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

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

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

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

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());

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();

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

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;

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;

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!

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!

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

http://plugins.jetbrains.com/plugin/7320?pr=phpStorm

PHP Annotations Pluginby Daniel Espendiller

Questions?

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

http://slides.doh.ms

http://doh.ms

@rdohms

top related