annotations in php - confoo 2013
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
*����������� ������������������ ConFoo����������� ������������������ -����������� ������������������ Montreal/2013
Annotations����������� ������������������ in����������� ������������������ PHP
@rdohmson����������� ������������������ twitter
They����������� ������������������ Exist!
phot
o cr
edit:
Eli W
hite
Evangelist, Speaker and Contributor.
Developer at WEBclusive.
Enabler at AmsterdamPHP.
Rafael Dohms@rdohms
we����������� ������������������ make����������� ������������������ awesome����������� ������������������ crowd-funding����������� ������������������ software!
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����������� ������������������ Commons
phpDocumentor����������� ������������������ 2
Notoj
Annotation Engines
php-annotations
https://github.com/doctrine/common
https://github.com/phpDocumentor/phpDocumentor2
https://github.com/mindplay-dk/php-annotations
https://github.com/crodas/Notoj
Doctrine����������� ������������������ Commons
phpDocumentor����������� ������������������ 2
Notoj
Annotation Engines
php-annotations
Doctrine����������� ������������������ Commons
phpDocumentor����������� ������������������ 2
Notoj
Annotation Engines
php-annotations
2.3
2.0
1.1
-
Doctrine����������� ������������������ Commons
phpDocumentor����������� ������������������ 2
Notoj
Annotation Engines
php-annotations
2.3
2.0
1.1
-
Doctrine����������� ������������������ Commons
phpDocumentor����������� ������������������ 2
Notoj
Annotation Engines
php-annotations
2.3
2.0
1.1
-
Doctrine����������� ������������������ Commons
phpDocumentor����������� ������������������ 2
Notoj
Annotation Engines
php-annotations
2.3
2.0
1.1
-
full����������� ������������������ support
only����������� ������������������ string����������� ������������������
full����������� ������������������ support
full����������� ������������������ support
Doctrine����������� ������������������ Commons
phpDocumentor����������� ������������������ 2
Notoj
Annotation Engines
php-annotations
2.3
2.0
1.1
-
full����������� ������������������ support
only����������� ������������������ string����������� ������������������
full����������� ������������������ support
full����������� ������������������ support
Doctrine����������� ������������������ Commons
phpDocumentor����������� ������������������ 2
Notoj
Annotation Engines
php-annotations
2.3
2.0
1.1
-
full����������� ������������������ support
only����������� ������������������ string����������� ������������������
full����������� ������������������ support
full����������� ������������������ support
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����������� ������������������ =>����������� ������������������ valueor
string:����������� ������������������ value
defaultProperty
/** * @My\Annotation(“name”, nullable=true) */
new My\Annotation($options);
array:����������� ������������������ key����������� ������������������ =>����������� ������������������ valueor
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����������� ������������������ =>����������� ������������������ valueor
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?
Questions?
https://joind.in/7912
on����������� ������������������ twitterthese����������� ������������������ slides����������� ������������������ will����������� ������������������ be����������� ������������������ here
Rate����������� ������������������ me,����������� ������������������ please!
http://slides.doh.ms
http://doh.ms
@rdohms