annotations in php, they exist
Post on 15-Jan-2015
2.736 Views
Preview:
DESCRIPTION
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