Silex est un framework PHP issu d'un autre framework PHP, Symfony 2.
Il est généralement considéré comme étant un mini framework PHP. Je vais tenter de vous montrer qu'il est largement suffisant et puissant pour bon nombre de projets, même si le projet est conséquent.

Commentez

- Titre : Silex mini framework.....pourquoi mini ?

- Auteur : Ernaelsten Gérard

- Parution : 31 octobre 2012

- Mise à jour : 20 novembre 2012

- Licence : Copyright © 2012 Ernaelsten Gérard. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 € de dommages et intérêts. Cette page est déposée à la SACD.

Sommaire

- Avant propos

- Présentation

- Notre façon de travailler.

- Arborescence

- Composer

- Autoloader

- vendor/composer/autoload_namespaces.php

- index.php

- bootstrap.php

- App/Controller/IndexController.php

- Conclusion

- Installation

- bootstrap.php

- layout.twig

- IndexController.php

- index.twig

- Mise en page

- Routes

- bootstrap.php

- layout.twig

- La suite....

Avant propos

Il n'est pas possible à mon sens de parler de Silex sans faire allusion à Symfony 2.
Alors de mon point de vue, je n'aime pas (encore) Symfony 2, pour des raisons totalement subjectives et absolument pas pour des raisons constructives.
Une des raisons étant liée à Hugo Hamon et sa façon assez hautaine (ma perception hein !) dont il est intervenu au PHP tour de Lille lors de la présentation de Enrico Zimuel sur le Zend Framework 2.
Une autre raison est que je trouve que la prise en main de Symfony 2 (SF2) est malaisé de prime abord.
Et c'est là qu'intervient Silex, ce (mini) framework, va être pour nous une porte d'entrée pour appréhender SF2.

Présentation

Silex est un framework PHP pour PHP 5.3, inspiré du framework développé par Sensio Labs Symfony 2 .
Celui-ci à été créé par Fabien Potencier , créateur du framework Symfony, et Igor Wiedler, ingénieur logiciel. Il est publié sous license MIT.
Silex est composé de Silex-Core, Twig qui est le template et certains composant de Symfony.
Silex utilise Composer : Composer est un outil moderne qui permet de gérer les dépendances de ses projets de manière simple et puissante.
Comme Silex est compilant 'psr-0', cela nous permet d'intégrer des librairies externe très facilement.

Notre façon de travailler.

Il existe plusieurs façons de traiter et travailler avec Silex. Notamment Grégoire Pineau qui propose sa façon de faire, ou encore Mparaiso qui nous proposent le fameux blog, c'est sur ce dernier que je me suis largement inspiré pour cet article.
Dans le projet que je dois mettre en place, il faut que cela soit maintenable, clair et précis.
Je mettrais donc en place une structure MVC (Model- vue - Controlleur), et je vais distinguer deux parties. La première sera la mise en place de la structure et architecture de façon à disposer d'un outil prêt à l'emploi.
Cet outil se présentera en une arborescence définie, la mise en place de Silex, Twig et le bootstrap Twitter

Arborescence

Notre structure du nouveau projet SilexSkeleton va ressembler à ceci :

Composer

A partir d'ici nous allons utiliser Composer pour gérer les dépendances de notre application, nous devons donc rapatrier cet outil.
Il existe plusieurs façon de faire et il existe plusieurs façon de l'utiliser, je vous laisse le soin de choisir selon votre préférence .
Une fois "Composer" installé, nous allons à la racine créer notre fichier de configuration Json, qui va nous permettre de gérer nos dépendances.
Editons un fichier nommer composer.json et plaçon le à la racine de notre projet.

{
"minimum-stability":"dev",
"require":{
"silex/silex":"1.0.*"
}

}

Dans ce fichier nous demandons d'installer Silex version 1.0.* , l'étoile représentant les sous branches, mais avec un minimum de stabilité.
Lançon l'installation

php composer.phar install

Ce qui chez moi donne ceci

This dev build of composer is outdated, please run "composer.phar self-update" to get the latest version.
Installing dependencies
- Installing pimple/pimple (dev-master)
Cloning b9f27b8dc18c08f00627dec02359b46a24791dc3

- Installing symfony/routing (2.1.x-dev)
Cloning v2.1.2

- Installing symfony/http-foundation (2.1.x-dev)
Cloning 17af0b966d268aa62e3487e3c48f0742e919edd1

- Installing symfony/event-dispatcher (2.1.x-dev)
Cloning v2.1.2

- Installing symfony/http-kernel (2.1.x-dev)
Cloning 9d00c6069a5e194826091d72baa5402f623ebf31

- Installing silex/silex (dev-master)
Cloning fc82b4255ef081dd7d464c5320ca93a902f9190f

symfony/routing suggests installing doctrine/common (=2.2,2.4-dev)
symfony/routing suggests installing symfony/config (2.1.*)
symfony/routing suggests installing symfony/yaml (2.1.*)
symfony/event-dispatcher suggests installing symfony/dependency-injection (2.1.*)
symfony/http-kernel suggests installing symfony/browser-kit (2.1.*)
symfony/http-kernel suggests installing symfony/class-loader (2.1.*)
symfony/http-kernel suggests installing symfony/config (2.1.*)
symfony/http-kernel suggests installing symfony/console (2.1.*)
symfony/http-kernel suggests installing symfony/dependency-injection (2.1.*)
symfony/http-kernel suggests installing symfony/finder (2.1.*)
silex/silex suggests installing symfony/browser-kit (2.1.*)
silex/silex suggests installing symfony/css-selector (2.1.*)
silex/silex suggests installing symfony/dom-crawler (2.1.*)
Writing lock file
Generating autoload files

Et où l'on retrouve un nouveau répertoire vendor/

Autoloader

Ce qui est intéressant à regarder dans tout ces nouveaux fichiers et répertoires, c'est l'autoloader qui est pris en charge intégralement par "Composer"

vendor/composer/autoload_namespaces.php

<?php

// autoload_namespaces.php generated by Composer

$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);

return array(
'Symfony\\Component\\Routing' => $vendorDir . '/symfony/routing/',
'Symfony\\Component\\HttpKernel' => $vendorDir . '/symfony/http-kernel/',
'Symfony\\Component\\HttpFoundation' => $vendorDir . '/symfony/http-foundation/',
'Symfony\\Component\\EventDispatcher' => $vendorDir . '/symfony/event-dispatcher/',
'Silex' => $vendorDir . '/silex/silex/src/',
'SessionHandlerInterface' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Resources/stubs',
'Pimple' => $vendorDir . '/pimple/pimple/lib/',
);

Nous allons maintenant pouvoir commencer notre projet, en continuant sa mise en place.

index.php

Dans le répertoire public, créons notre fichier d'entrée le "index.php" et faisons le pointer sur le fichier structure de notre application.

<?php
require_once __DIR__ . '/../App/bootstrap.php';

Et tant que nous y sommes, créons le fichier .htaccess (pour Apache) qui va bien

&lt;IfModule mod_rewrite.c&gt;
Options -MultiViews
RewriteEngine On
#RewriteBase /path/to/app
RewriteCond %{REQUEST_FILENAME} !-f
#RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
&lt;/IfModule&gt;

bootstrap.php

Nous avons vu dans le index.php, qui nous faisions appelle à un fichier de configuration nommé bootsrap.php dans notre répertoire, c'est dans ce fichier que nous alons mettre en place la mécanique pour faire fonctionner le framework.
Construisons le pas à pas.

<?php

//On initialise le timeZone
ini_set('date.timezone', 'Europe/Brussels');

//On ajoute l'autoloader
$loader = require_once __DIR__ . '/../vendor/autoload.php';

//dans l'autoloader nous ajoutons notre répertoire applicatif
$loader->add("App",dirname(__DIR__));

//Nous instancions un objet Silex\Application
$app = new Silex\Application();

//en dev, nous voulons voir les erreurs
$app['debug'] = true;

Il ne nous reste plus qu'a lancer notre appli sur http://loclahost/SilexApplication/public/
Nous tombons sur une belle erreur.

Cette erreur prouve que notre application est bien configuré.
Silex nous réclame une route, normal, il dit "je vais où moi" et dans ce que vous pourrez trouver sur le net, a partir d'ici les façons de faire diverge.
Dans notre cas, on va dire au boostrap où allez voir, dans quelle controlleur nous allons.
C'est dans le(s) controlleur(s) que nous allons définir nos routes.
Dans le bootsrap.php ajoutons la ligne suivante :

....
//On indique ou allez pour le chemin http://localhost/SilexSkeleton/public/
$app->mount("/", new App\Controller\IndexController());

//On lance l'application
$app->run();

App/Controller/IndexController.php

Dans notre IndexController.php, nous allons définir trois méthodes (juste pour l'exemple) :

- index

- info

- connect

c'est dans la méthode connect que nous définirons nos routes.
Soit dans le fichier IndexController.php, définissons notre namespace.

<?php
namespace App\Controller {

}

Ajoutons les namespaces dont nous avons besoins pour faire prendre le tout.

<?php
namespace App\Controller {

use Silex\Application;
use Silex\ControllerProviderInterface;
}

Créons notre classe étendue de ControllerProviderInterface

<?php
namespace App\Controller {

use Silex\Application;
use Silex\ControllerProviderInterface;

class IndexController implements ControllerProviderInterfacepublic
{
}
}

Nous allons écrire notre première méthode, qui va définir nos routes.
Il est bon de savoir que dans chaque controlleurs c'est la méthode connect() qui définiras vos routes, donc soit vous la définissez une fois dans IndexController, soit vous la définissez dans chaque controlleur, ce qui est l'option que j'ai pris.

public function connect(Application $app)
{
// créer un nouveau controller basé sur la route par défaut
$index = $app['controllers_factory'];
$index->match("/", 'App\Controller\IndexController::index');
$index->match("/info", 'App\Controller\IndexController::info');
return $index;
}

Dans cette méthode qui prend en parametre l'application Silex, nous recupérons la factory des controlleurs et lui ajoutons deux routes :

- http://loclahost/SilexSkeleton/public/

- http://loclahost/SilexSkeleton/public/info

Ces deux routes, font appel à deux méthodes de notre IndexController.
Définissons ces deux méthodes.

public function index()
{
echo 'Bonjour';
}

public function info()
{
phpinfo();
}

Ce qui nous donne le controlleur complet suivant :

<?php
namespace App\Controller {

use Silex\Application;
use Silex\ControllerProviderInterface;

class IndexController implements ControllerProviderInterface
{

public function index()
{  echo 'Bonjour';
}

public function info()
{
phpinfo();
}

public function connect(Application $app)
{
// créer un nouveau controller basé sur la route par défaut
$index = $app['controllers_factory'];
$index->match("/", 'App\Controller\IndexController::index');
$index->match("/index", 'App\Controller\IndexController::index');
$index->match("/info", 'App\Controller\IndexController::info');

return $index;
}

}

}

maintenant si nous allons sur le lien suivante http://localhost/SilexSkeleton/public , cela affichera bonjour.
Tandis que le lien http://localhost/SilexSkeleton/public/info , vous affichera le phpinfo().

Conclusion

Potentiellement l'application est fonctionnelle en l'état et vous n'avez besoin de rien d'autres pour développer votre application.
Mais nous allons encore faire un petit pas plus loin.

Twig est un moteur de templates PHP permettant de séparer la couche de présentation de vos applications web, tout en gardant flexibilité, rapidité et facilités au développement.
L'objectif principal de Twig est de proposer aux développeurs de séparer la couche de présentation (Vue du MVC) dans des templates dédiés, afin de favoriser la maintenabilité du code. Idéal aussi pour les graphistes qui ne connaissent pas forcément le langage PHP et qui s'accommoderont parfaitement des instructions natives du moteur, relativement simples à maîtriser.
Vous trouverez toutes la doc et des exemples sur leur sites .

Installation

Pour installer Twig, nous allons utiliser "Composer", mais vous devez savoir que Sensio Labs à également compiler en C cette librairie et que donc on peut l'intégrer nativement à PHP ( voir ici ), cette compilation permettras aux très gros projets de gagner de la vélocité.
Installation de Twig, d'abord modifier le fichier composer.json, pour ajouter Twig

{
"minimum-stability":"dev",
"require":{
"silex/silex":"1.0.*",
"symfony/twig-bridge":"2.1.*",
"twig/twig":">=1.8,<2.0-dev"

}

}

Suivi de la commande :

php composer.phar update

bootstrap.php

Dans le boostrap, nous allons initialiser Twig, en donnant comme paramètre le répertoire par defaut et le cache.

/* twig */
$app->register(new Silex\Provider\TwigServiceProvider(), array(
"twig.path" => dirname(__DIR__) . "/App/Views",
'twig.options' => array('cache' => dirname(__DIR__).'/cache', 'strict_variables' => true)
));

On voit bien ici, on dit à Twig d'aller chercher les vues dans /App/Views

layout.twig

Dans App/Views, créer un fichier layout.php qui sera la vue de base de notre application et dedans nous aurons ceci :

{# layout principal #}
<!doctype html>

<html lang="fr-FR">
<head>
<meta charset="UTF-8">
<title>SilexSkeleton</title>

</head>
<body>
<header>

<div id="content">

{% block content %}
{% endblock %}

</div>
</header>

<footer>

</footer>

</body>
</html>

Bon actuellement cela ne change rien, mais revenons dans notre IndexController et modififions quelque peu notre méthode index.

IndexController.php

public function index(Application $app)
{
return $app["twig"]->render("index/index.twig");
}

Ici nous avons modifier deux choses, nous avons d'abord mis l'application en paramètre afin de pouvoir rechercher Twig.
Ensuite nous avons données le chemin d'une vue dans la méthode render, ce chemin est App/Views/index/index.twig

index.twig

Il suffit dans ce fichier de mettre le code suivant :

{% extends "layout.twig" %}

{% block content %}

Bonjour ! de ma vue Twig

{% endblock %}

Concretement si vous allez sur le lien http://localhost/SiteSilex/public , cela ne change pas grand chose, mais si vous regardez le code source :

<!doctype html>

<html lang="fr-FR">
<head>
<meta charset="UTF-8">
<title>SilexSkeleton</title>

</head>
<body>
<header>

<div id="content">

Bonjour ! de ma vue Twig

</div>
</header>

<footer>

</footer>

</body>
</html>

Nous avons bien une page html complète, je vous renvoie sur la doc de Twig pour comprendre la gestion des 'extends' et 'block' de Twig

Mise en page

Ici nous allons mettre en place le Bootstrap de Twitter, pourquoi ? Juste pour pouvoir avoir un peu de mise en page et puis c'est une bonne excuse pour parler de la génération de route.

Routes

Dans notre controller nous avons générer les routes dans la méthode connect(), mais nous allons "binder" ces routes et les récuperer dans d'autres contexte

bootstrap.php

Il faut ajouter la ligne suivante dans le bootstrap.php

# url generator
$app->register(new Silex\Provider\UrlGeneratorServiceProvider());

Grâce à ce provider, nous allons pourvoir utiliser deux méthodes :

- url()

- path()

Mais avant nous devons "binder" les routes dans notre controller

public function connect(Application $app)
{
// créer un nouveau controller basé sur la route par défaut
$index = $app['controllers_factory'];
$index->match("/", 'App\Controller\IndexController::index')->bind("index.index");
$index->match("/info", 'App\Controller\IndexController::info')->bind("index.info");

return $index;
}

Il ne reste plus qu'a télécharger le bootstrap Twitter et l'installer dans /public, je vous met également une petite css perso pour finaliser

body
{
margin-top: 70px;
}
html
{
position: relative;
}

body
{
font: 11px Verdana, Arial, Helvetica, sans-serif;
background-color: #efefef;
/* margin:1px;
padding:0px;*/

}

footer
{
background-color: #F5F5F5;
border-top: 1px solid #E5E5E5;
margin-top: 70px;
padding: 70px 0;
}

.pull-center
{
text-align: center;
}

#content
{
width: 75%;
margin-left: auto;
margin-right: auto;
padding: 5px;
border: 1px solid #cccccc;
margin-top: 20px;
background-color: white;
position: relative;
z-index: 3;
}

#content form label
{
display: block;
width: 300px;
background-color: #B9ED5D;
float: left;
text-align: right;
line-height: 2.1em;
padding: 0 0.8em 0 0;
margin-right: 3px;
}

#content form input
{
border: 1px solid #cccccc;
width: 250px;
-webkit-border-radius:3px;
-moz-border-radius:3px;
border-radius:3px;
}

#content form input[type=checkbox]
{
display: inline;
width: 15px;
}

layout.twig

Je vous met ici le code avec l'intégration du bootstrap Twitter, regarder de plus près les méthodes path() et url()

{# layout principal #}
<!doctype html>

<html lang="fr-FR">
<head>
<meta charset="UTF-8">
<title>SilexSkeleton</title>
<link rel="stylesheet" href="{{ url('index.index') }}bootstrap/css/bootstrap.css">
<link rel="stylesheet" href="{{ url('index.index') }}bootstrap/css/bootstrap-responsive.css">
<link rel="stylesheet" href="{{ url('index.index') }}bootstrap/css/bootstrap-notify.css">
<link rel="stylesheet" href="{{ url('index.index') }}css/default.css">

<script type="text/javascript" src="{{ url('index.index') }}bootstrap/js/bootstrap.js"></script>
<script type="text/javascript" src="{{ url('index.index') }}bootstrap/js/bootstrap-dropdown.js"></script>
<script type="text/javascript" src="{{ url('index.index') }}bootstrap/js/bootstrap-transition.js"></script>
<script type="text/javascript" src="{{ url('index.index') }}bootstrap/js/bootstrap-scrollspy.js"></script>
<script type="text/javascript" src="{{ url('index.index') }}bootstrap/js/bootstrap-modal.js"></script>
<script type="text/javascript" src="{{ url('index.index') }}bootstrap/js/bootstrap-tab.js"></script>

</head>
<body>
<header>
<body data-spy="scroll" data-target=".navbar">

<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner"><section id="I-F" noNumber="1">
<title>La suite....</title>
<paragraph>C'est ici que ce termine cet article sur Silex.<br />
J'espère que je vous ai montré avec facilité il est possible de monter un projet en Silex, prochainement je développerais cet article avec les notions de Session,Base de données, Formulaires et validation.<br />
Ce qui est bien avec Silex, est qu'il est une bonne porte d'entrèe vers Symfony 2, parce que inévitablement, plus le projet Silex est gros, plus on lorgne vers Symfony.

</paragraph>
</section>
<div class="container">
<a class="brand" href="#">SilexSkeleton</a>

<div class="nav-collapse collapse">
<p class="navbar-text pull-right">

<b>Nous sommes le {{ "now"|date("d/m/Y") }} </b>
</p>
<ul class="nav" role="navigation">
<li><a href="{{ path("index.index") }}">Accueil</a></li>
<li><a href="{{ path("index.info") }}">Info</a></li>

</ul>
</div>
</div>
</div>
</div>

</header>
<div id="content">

{% block content %}
{% endblock %}

</div>

<footer>

</footer>

</body>
</html>

La suite....

C'est ici que ce termine cet article sur Silex.
J'espère que je vous ai montré avec quel facilité il est possible de monter un projet en Silex, prochainement je développerais cet article avec les notions de Session,Base de données, Formulaires et validation.
Ce qui est bien avec Silex, est qu'il est une bonne porte d'entrèe vers Symfony 2, parce que inévitablement, plus le projet Silex est gros, plus on lorgne vers Symfony.

Silex mini framework.....pourquoi mini ?

Auteur

Ernaelsten Gérard