Filtering objects using annotations

  • PHP
  • August 11, 2011

Filtering with Annotations

PHP does not have native Annotations support, however many projects have been using doc blocks to add value and semantics to code, like PHPUnit, Doctrine and Symfony. The Doctrine did a really good job in making available a Annotation parser kit, which allows you to bring the power of annotations into you own project. This opens up a few possibilities.

Input Validation and Filtering

Rule #1 of the developer is “Filter input, escape output”. To me treating input has two distinct steps which are very important: Filtering and Validation. Symfony 2 has come out with a very cool Validation library which makes validation possible using annotations. It relies on a set of constraints which can be attached to properties of your object, allowing you to simply pass your objects to a validation service and it will do the rest for you. Like this:

 <?php // src/Acme/BlogBundle/Entity/Author.php use Symfony\\Component\\Validator\\Constraints as Assert;

class Author { /\*\* \* @Assert\\NotBlank() \*/ public $name; } ?> 
``` ```php
 <?php $author = new Author();

$validator = $this->get('validator'); $errorList = $validator->validate($author); ?> 

This is a very nice and clean way of handling validation, it allows all rules to be centered on the entities, making maintenance easy. A nice complement is that constraints can be added to the class so they use more then one variable, as well as allowing you to create your own contraints.

However the library lacks one thing, which Zend_Filter_Input does very well, Filtering. Most data needs to be filtered before going in for validation, and even of Symfony2 offers a Data Transformer, that is not quite what is needed here, so I came out with the only other solution, build one myself.

DMS\Filter

I wanted a library with all the power of the filters out there and the advantage of using annotations to provide its interface. So i set about studying the annotations implementation in doctrine and the Symfony2 Validator and came up with my own Filter library. It was designed to be simple and to be used alongside doctrine and symfony validator, so it depends on Doctrine Common.

Its composed of a filter service which is capable of reading “filter rules” from object properties and iterate over them, even private and protected ones, filtering the values. It works based on the object instance which is not cloned, so the object is altered and does not need to be returned nd re-assigned.

To add rules to you properties, just declare the namespace use and go for it, like this:

 <?php

namespace App\\Entity;

//Import Annotations use DMS\\Filter\\Rules as Filter;

class User {

/\*\* \* @Filter\\StripTags() \* @Filter\\Trim() \* @Filter\\StripNewlines() \* \* @var string \*/ public $name;

/\*\* \* @Filter\\StripTags() \* @Filter\\Trim() \* @Filter\\StripNewlines() \* \* @var string \*/ public $email;

} ?> 

To filter your instance, just do it like this:

 <?php //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]" ?> 

You can also recycle an AnnotationReader already in use by Symfony Validator for example. The AnnotationReader is currently changing in Doctrine Common, but DMS\Filter tries to auto-configure its namespace, I will be keeping an eye on this in the future.

The project is available in two forms, inside the DMS library on github , or as a standalone component, also on github (sub tree split FTW!). It has a limited number of filters, but you can develop your own filters to use or just open up an issue and i’ll create them.

Hope the library is useful and you enjoy it.

comments powered by Disqus

Related Posts

News Update

News Update

  • August 15, 2006

O tempo pra variar não espera ninguem, no meu caso já fiquei para trás a muito tempo.

Read More
Installing Composer Packages

Installing Composer Packages

  • October 13, 2014

I have been putting together a new talk about Composer, and that means looking around the community, doing loads of research and trying to identify the items that need to be covered in a talk.

Read More
Um estudo em RSS - Parte 1: XML DOM

Um estudo em RSS - Parte 1: XML DOM

  • July 13, 2006

RSS, hoje me perguntaram “o que é isso?” Eu sei o que é, porém na hora me faltaram palavras para explicar, especialmente palavras que um não-programador consiga absorver de forma a compreender o conceito e seus melhores usos. Portanto com essa série de posts, não sei quantos nem se vou escrever na ordem, mas garanto que vou tentar cobrir tudo.

Read More