Création de la classe du service
Maintenant que nous savons utiliser un service, apprenons à le créer. Comme un service n'est qu'une classe, il suffit de créer un fichier n'importe où et de créer une classe dedans.
La seule convention à respecter, de façon générale dans Symfony, c'est de mettre notre classe dans un namespace correspondant au dossier où est le fichier. Par exemple, la classe
Sdz\BlogBundle\Service\SdzAntispam doit se trouver dans le répertoire
src/Sdz/BlogBundle/Service/SdzAntispam.php. C'est ce que nous faisons depuis le début du tutoriel

.
Je vous propose, pour suivre notre fil rouge du blog, de créer un système anti-spam. Notre besoin : détecter les spams à partir d'un simple texte. Comme c'est une fonction à part entière, et qu'on aura besoin d'elle à plusieurs endroits (pour les articles et pour les commentaires), faisons-en un service. Ce service devra être réutilisable simplement dans d'autre projets Symfony : il ne devra pas être dépendant d'un élément de notre blog. Je nommerais ce service
SdzAntispam, mais vous pouvez le nommer comme vous le souhaitez. Il n'y a pas de règle précise à ce niveau, mise à part que l'utilisation des underscores (_) est fortement déconseillée.
Si votre service est relativement indépendant (il n'y a pas d'autres services autour du même thème), il est bon de mettre ce service dans un dossier
Service de votre bundle, mais à vrai dire vous pouvez faire comme vous le souhaitez.
Créons donc le fichier
src/Sdz/BlogBundle/Service/SdzAntispam.php, avec ce code pour l'instant :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14 | <?php
// src/Sdz/BlogBundle/Service/SdzAntispam.php
namespace Sdz\BlogBundle\Service;
/**
* Un anti-spam simple pour Symfony2.
*
* @author Leglopin
*/
class SdzAntispam
{
}
|
C'est tout ce qu'il faut pour avoir un service. Il n'y a vraiment rien d'obligatoire, vous y mettez ce que vous voulez. Pour l'exemple, faisons un rapide anti-spam : considérons qu'un message est un spam s'il contient au moins 3 liens ou adresse e-mail. Voici ce que j'obtiens :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 | <?php
// src/Sdz/BlogBundle/Service/SdzAntispam.php
namespace Sdz\BlogBundle\Service;
/**
* Un anti-spam simple pour Symfony2.
*
* @author Leglopin
*/
class SdzAntispam
{
/**
* Vérifie si le texte est un spam ou non.
* Un texte est considéré comme spam à partir de 3 liens
* ou adresses e-mails dans son contenu.
*
* @param string $text
*/
public function isSpam($text)
{
if( ($this->countLinks($text) + $this->countMails($text)) >= 3 )
{
return true;
}
else
{
return false;
}
}
/**
* Compte les URL de $text.
*
* @param string $text
*/
private function countLinks($text)
{
preg_match_all(
'#(http|https|ftp)://([A-Z0-9][A-Z0-9_-]*(?:.[A-Z0-9][A-Z0-9_-]*)+):?(d+)?/?#i',
$text,
$matches);
return count($matches[0]);
}
/**
* Compte les e-mails de $text.
*
* @param string $text
*/
private function countMails($text)
{
preg_match_all(
'#[a-z0-9._-]+@[a-z0-9._-]{2,}\.[a-z]{2,4}#i',
$text,
$matches);
return count($matches[0]);
}
}
|
Création de la configuration du service
Maintenant que nous avons créé notre service, il faut le signaler à Symfony. Un service se définit par sa classe ainsi que sa configuration. Pour cela, nous pouvons utiliser le fichier
src/Sdz/BlogBundle/Ressources/config/services.yml.
Si vous avez généré votre bundle avec le generator en répondant "oui" pour créer toute la structure du bundle, alors ce fichier est chargé automatiquement. Vérifiez-le en confirmant que le répertoire DependencyInjection de votre bundle existe, il devrait contenir le fichier SdzBlogExtension.php.
Si ce n'est pas le cas, vous devez créer le fichier DependencyInjection/SdzBlogExtension.php (adaptez à votre bundle évidemment) avec le contenu suivant :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | <?php
namespace Sdz\BlogBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
class SdzBlogExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
}
|
Ouvrez ou créez le fichier Ressources/config/services.yml de votre bundle, et ajoutez-y la configuration pour notre service :
Code : Autre1
2
3
| services:
sdz_blog.antispam:
class: Sdz\BlogBundle\Service\SdzAntispam |
Dans cette configuration :
- "sdz_blog.antispam" est le nom de notre service fraîchement créé. De cette manière, le service sera accessible via <?php $container->get('sdz_blog.antispam');. Essayez de respecter cette convention de préfixer le nom de vos services par "nomApplication_nomBundle". Pour notre bundle Sdz\BlogBundle, on a donc préfixé notre service de "sdz_blog.".
- "class" est un attribut obligatoire de notre service, il définit simplement le namespace complet de la classe du service.
Il existe bien sûr d'autres attributs pour affiner la définition de notre service, nous les verrons dans le prochain chapitre.
Utilisation du service
Maintenant que notre classe est définie, et notre configuration déclarée, nous pouvons nous servir du service. Voici un exemple simple de l'utilisation que l'on pourrait en faire :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | <?php
// src/Sdz/BlogBundle/Controller/BlogController.php
namespace Sdz\BlogBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class BlogController extends Controller
{
public function indexAction()
{
$antispam = $this->container->get('sdz_blog.antispam');
if( $antispam->isSpam($text) )
{
exit('Votre message a été détecté comme spam !');
}
return $this->render('SdzBlogBundle:Blog:index.html.twig');
}
}
|
Et voilà, vous avez créé et utilisé votre premier service !