php annotations: they exist! - jetbrains webinar
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 protected]"; ! ! //Filter you entity ! $filter->filter($user); ! ! echo $user->name; //"My name" ! echo $user->email; //"[email protected]" !
//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
//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
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