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

Documentação e Best Practices: Um caso de uso

Documentação e Best Practices: Um caso de uso

  • January 4, 2007

Documentação, a palavra mais assustadora e antipática criada dentro do ambiente de desenvolvimento.

Read More
Meetup API Client v1.0.0

Meetup API Client v1.0.0

  • March 29, 2013

I love APIs, but I honestly hate having to deal with signing, auth, and curl inside my controllers or services, which means I end up wrapping all of that into something that provides easy access in my controllers. I also love Meetup.com since it really makes managing User Groups pretty cool, even with some bad UI choices, which is exactly where their API comes in, it allows me to provide a decent interface to their features from my own UG page and do all the communication via API.

Read More
Escrevendo testes com PHPT e contribuindo com o PHP

Escrevendo testes com PHPT e contribuindo com o PHP

  • August 19, 2009

Este ano esteve em destaque a PHPTestFest09, sendo realizada em vários cantos do mundo e destacando-se a participação do PHPSP que contribuiu com o maior número de testes. Ficou de fora? Então já comece a se preparar para ano que vem.

O PHPT é um framework extremamente simples de testes criado e usado internamente pelos desenvolvedores do core. Ele é extremamente atômico e centrado em testes como os que esperamos do PHP, como testar funções e bugs específicos.

O que preciso saber?

A grande vantagem do PHPT é que para poder escrever um teste, tudo que você precisa saber é: como escrever código PHP. Claro que um pouco de conhecimento interno do funcionamento do PHP vai te ajudar a procurar detalhes para testar, mas sabendo escrever PHP você já pode contribuir com uma grande percentagem dos testes que precisamos.

Vamos então atacar por partes:

  1. Preparando o ambiente
  2. Escolhendo um teste
  3. Escrevendo um teste
  4. Rodando um teste
  5. Enviando seu teste para o PHP

Read More