Annotations in PHP - ConFoo 2013
-
Upload
rafael-dohms -
Category
Technology
-
view
6.404 -
download
1
description
Transcript of Annotations in PHP - ConFoo 2013
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