Différences entre versions de « Php slim »
(13 versions intermédiaires par le même utilisateur non affichées) | |||
Ligne 5 : | Ligne 5 : | ||
Nous allons commencer par l'installation de PHP et du serveur web Apache ''httpd'': | Nous allons commencer par l'installation de PHP et du serveur web Apache ''httpd'': | ||
<pre> | <pre> | ||
− | # dnf -y install php php-cli mod_php httpd | + | # dnf -y install php php-cli mod_php httpd php-json |
</pre> | </pre> | ||
N'oubliez pas de [[SELinux#Changement_d.27.C3.A9tat|désactiver selinux]] et d'ouvrir le [[Iptables_on_systemd|pare-feu]] | N'oubliez pas de [[SELinux#Changement_d.27.C3.A9tat|désactiver selinux]] et d'ouvrir le [[Iptables_on_systemd|pare-feu]] | ||
+ | |||
= Préparation et installation = | = Préparation et installation = | ||
On doit créer le répertoire dans lequel va s'installer Slim ainsi que le code du site. Dans ce cas présent nous allons utiliser ''/opt/slim'': | On doit créer le répertoire dans lequel va s'installer Slim ainsi que le code du site. Dans ce cas présent nous allons utiliser ''/opt/slim'': | ||
Ligne 101 : | Ligne 102 : | ||
Generated autoload files | Generated autoload files | ||
</pre> | </pre> | ||
+ | = Quelques objets de Slim = | ||
+ | == Application == | ||
+ | L'objet application est disponible en utilisant l'interface suivante: | ||
+ | <source lang=php> | ||
+ | use Slim\Factory\AppFactory; | ||
+ | </source> | ||
+ | L'objet ''Application'' suit le [https://fr.wikipedia.org/wiki/Fabrique_(patron_de_conception) patron de conception fabrique] et s'obtient en utilisant la méthode ''create'': | ||
+ | <source lang=php> | ||
+ | $app = AppFactory::create(); | ||
+ | </source> | ||
+ | |||
+ | == Les méthodes == | ||
+ | ===get, post, put, delete, option head, patch et any=== | ||
+ | Permet le routage en fonction de la méthode et URL demandée | ||
+ | <source lang=php> | ||
+ | $app->get($pattern, $callback); | ||
+ | </source> | ||
+ | * pattern: correspond à la route et peut contenir des expressions ''moustache'': | ||
+ | ** /users | ||
+ | ** /users/{id} | ||
+ | * callback: correspond à la fonction de rappel avec la signature suivante: | ||
+ | <source lang=php> | ||
+ | function (Psr\Http\Message\ServerRequestInterface $request, Psr\Http\Message\ResponseInterface $response, array $args): Psr\Http\Message\ResponseInterface | ||
+ | </source> | ||
+ | Exemple: | ||
+ | <source lang=php> | ||
+ | $group->any('', function(Psr\Http\Message\ServerRequestInterface $request, Psr\Http\Message\ResponseInterface $response, array $args){ | ||
+ | return $response->getBody()->write('Hello Wolrd'); | ||
+ | }); | ||
+ | </source> | ||
+ | Enverra 'Hello World' sur la route par défaut ('') peu importe la méthode http. | ||
+ | |||
+ | ===group=== | ||
+ | La fonction ''group'' permet de définir plusieurs routes en une seule fois. | ||
+ | <source lang=php> | ||
+ | $app->group($pattern, $callback); | ||
+ | </source> | ||
+ | * pattern: correspond à la route et peut contenir des expressions ''moustache'': | ||
+ | ** /users | ||
+ | ** /users/{id} | ||
+ | * callback: correspond à la fonction de rappel avec la signature suivante: | ||
+ | <source lang=php> | ||
+ | function (Slim\Interfaces\RouteCollectorProxyInterface $group) | ||
+ | </source> | ||
+ | Exemple: | ||
+ | <source lang=php> | ||
+ | $app->group('/users', function (Slim\Interfaces\RouteCollectorProxyInterface $group) { | ||
+ | // Route par défaut qui liste tous les utilisateurs | ||
+ | $group->get('', function(Psr\Http\Message\ServerRequestInterface $request, Psr\Http\Message\ResponseInterface $response, array $args){ | ||
+ | return $response->getBody()->write('Hello Wolrd'); | ||
+ | }); | ||
+ | // Route qui permet de lister un utilisateur grâce à son identifiant | ||
+ | $group->get('/{name}', function(Psr\Http\Message\ServerRequestInterface $request, Psr\Http\Message\ResponseInterface $response, array $args){ | ||
+ | return $response->getBody()->write('Hello Wolrd '.$args['name']); | ||
+ | }); | ||
+ | }); | ||
+ | </source> | ||
+ | ===map=== | ||
+ | La fonction map permet de définir plusieurs méthode pour la même route en une seule fois: | ||
+ | <source lang=php> | ||
+ | $app->map($methodes, $pattern, $callback); | ||
+ | </source> | ||
+ | * methodes: est un tableau contenant le nom des méthodes en majuscule (eg. "GET",...) | ||
+ | * pattern: correspond à la route et peut contenir des expressions ''moustache'': | ||
+ | ** /users | ||
+ | ** /users/{id} | ||
+ | * callback: correspond à la fonction de rappel avec la signature suivante: | ||
+ | <source lang=php> | ||
+ | function (Slim\Interfaces\RouteCollectorProxyInterface $group) | ||
+ | </source> | ||
+ | Exemple: | ||
+ | <source lang=php> | ||
+ | $app->map(["GET", "POST"], '', function(Psr\Http\Message\ServerRequestInterface $request, Psr\Http\Message\ResponseInterface $response, array $args){ | ||
+ | return $response->getBody()->write('Hello Wolrd'); | ||
+ | }); | ||
+ | </source> | ||
+ | Enverra 'Hello World' sur la route par défaut ('') pour les méthodes GET et POST. | ||
+ | |||
+ | ===run=== | ||
+ | Cette méthode permet de démarrer l'application Slim pour effectuer le rendu | ||
+ | <source lang=php> | ||
+ | $app->run(); | ||
+ | </source> | ||
+ | C'est normalement la dernière ligne de votre script ''index''. | ||
+ | |||
+ | == Requête == | ||
+ | L'objet requête est disponible en utilisant l'interface suivante: | ||
+ | <source lang=php> | ||
+ | use Psr\Http\Message\ServerRequestInterface as Request; | ||
+ | </source> | ||
+ | |||
+ | == Reponse == | ||
+ | L'objet réponse est disponible en utilisant l'interface suivante: | ||
+ | <source lang=php> | ||
+ | use Psr\Http\Message\ResponseInterface as Response; | ||
+ | </source> | ||
+ | |||
== Création de classes == | == Création de classes == | ||
− | Dans le répertoire ''src'' nous allons créer les | + | Nous allons créer une petite api qui permet de lister des utilisateurs. |
+ | |||
+ | Dans le répertoire ''src'' nous allons créer les fichiers suivants: | ||
+ | * User.php | ||
+ | <source lang=php> | ||
+ | <?php | ||
+ | |||
+ | namespace Tala; | ||
+ | |||
+ | class User | ||
+ | { | ||
+ | |||
+ | public $name, $id; | ||
+ | |||
+ | /** | ||
+ | * User constructor. | ||
+ | * @param $name | ||
+ | * @param $id | ||
+ | */ | ||
+ | public function __construct($name, $id) | ||
+ | { | ||
+ | $this->name = $name; | ||
+ | $this->id = $id; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </source> | ||
+ | |||
+ | * UserDao.php | ||
+ | <source lang=php> | ||
+ | <?php | ||
+ | |||
+ | namespace Tala; | ||
+ | |||
+ | use Psr\Http\Message\ResponseInterface as Response; | ||
+ | use Psr\Http\Message\ServerRequestInterface as Request; | ||
+ | |||
+ | use Tala\User as User; | ||
+ | |||
+ | class UserDao | ||
+ | { | ||
+ | // tableau contenant les utilisateurs | ||
+ | private $users = array(); | ||
+ | |||
+ | public function __construct() | ||
+ | { | ||
+ | // Ajout d'utilisateurs pour faire les tests | ||
+ | $this->users[] = new User("tala", 1); | ||
+ | $this->users[] = new User("jcf", 2); | ||
+ | } | ||
+ | |||
+ | public function getUsers(Request $request, Response $response, array $args): Response | ||
+ | { | ||
+ | $response->getBody()->write(json_encode($this->users)); | ||
+ | return $response->withHeader('Content-Type', 'application/json')->withStatus(200); | ||
+ | } | ||
+ | |||
+ | public function getUserById(Request $request, Response $response, array $args): Response | ||
+ | { | ||
+ | $id = $args['id']; | ||
+ | foreach ($this->users as $user){ | ||
+ | if($user->id == $id){ | ||
+ | // Utilisateur trouvé, on retourne un 200 | ||
+ | $response->getBody()->write(json_encode($user)); | ||
+ | return $response->withHeader('Content-Type', 'application/json')->withStatus(200); | ||
+ | } | ||
+ | } | ||
+ | // Utilisateur non trouvé on retourne un 404 | ||
+ | return $response->withStatus(404); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </source> | ||
+ | |||
+ | == Ajout d'une route == | ||
+ | Dans le répertoire ''app'' nous allons créer un fichier ''routes.php'' qui va contenir le code suivant: | ||
+ | <source lang=php> | ||
+ | <?php | ||
+ | |||
+ | declare(strict_types=1); | ||
+ | |||
+ | use Psr\Http\Message\ResponseInterface as Response; | ||
+ | use Psr\Http\Message\ServerRequestInterface as Request; | ||
+ | use Slim\App; | ||
+ | use Slim\Interfaces\RouteCollectorProxyInterface as Group; | ||
+ | |||
+ | return function (App $app) { | ||
+ | $app->options('/{routes:.*}', function (Request $request, Response $response) { | ||
+ | // CORS Pre-Flight OPTIONS Request Handler | ||
+ | return $response; | ||
+ | }); | ||
+ | |||
+ | $app->group('/users', function (Group $group) { | ||
+ | // Route par défaut qui liste tous les utilisateurs | ||
+ | $group->get('', \Tala\UserDao::class . ':getUsers'); | ||
+ | // Route qui permet de lister un utilisateur grâce à son identifiant | ||
+ | $group->get('/{id}', \Tala\UserDao::class . ':getUserById'); | ||
+ | }); | ||
+ | }; | ||
+ | </source> | ||
+ | |||
+ | == Déclaration dans la page d'index == | ||
+ | Il ne reste plus qu'a définir tout ça dans le fichier ''index.php'' du répertoire ''public'': | ||
+ | <source lang=php> | ||
+ | <?php | ||
+ | |||
+ | use Slim\Factory\AppFactory; | ||
+ | |||
+ | require __DIR__ . '/../vendor/autoload.php'; | ||
+ | |||
+ | // Création de l'application Slim | ||
+ | $app = AppFactory::create(); | ||
+ | |||
+ | // Enregistrement des routes | ||
+ | $routes = require __DIR__ . '/../app/routes.php'; | ||
+ | $routes($app); | ||
+ | |||
+ | $app->run(); | ||
+ | </source> | ||
+ | |||
+ | == Utilisation == | ||
+ | Nous avons déclaré deux points de terminaisons ou ''endpoint'' dans notre api : | ||
+ | * /users : pour lister tous les utilisateurs | ||
+ | * /users/{id} : pour afficher un utilisateur en fonction de son identifiant |
Version actuelle datée du 10 mai 2021 à 08:48
Introduction
Pré-requis
Assurez-vous d'avoir installé PHP, Composer et le serveur web Apache httpd Nous allons commencer par l'installation de PHP et du serveur web Apache httpd:
# dnf -y install php php-cli mod_php httpd php-json
N'oubliez pas de désactiver selinux et d'ouvrir le pare-feu
Préparation et installation
On doit créer le répertoire dans lequel va s'installer Slim ainsi que le code du site. Dans ce cas présent nous allons utiliser /opt/slim:
# mkdir /opt/slim
Nous allons ensuite créer un hôte virtuel pour Apache avec une réécriture d'url. Nous allons créer le fichier /etc/httpd/conf.d/slim.conf:
<VirtualHost *:80> DocumentRoot /opt/slim/public <Directory /opt/slim/public> Require all granted RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?url=$1 [QSA,L] </Directory> </VirtualHost>
On poursuit avec l'installation de Slim:
# composer create-project slim/slim-skeleton:dev-master /opt/slim
A la question :
Do you want to remove the existing VCS (.git, .svn..) history? [Y,n]?
Vous pouvez répondre Y Il faut maintenant donner les droits à Apache:
# chown -R apache. /opt/slim
Une fois le serveur Apache (re)démarré, vous devriez avoir le message Hello World!
Première utilisation
Arborescence
L'installation de Slim a créé plusieurs répertoires dont la plupart servent pour l'application exemple "Hello World":
/opt/slim |_app \ |_dependencies.php |_middleware.php |_repositories.php |_routes.php |_settings.php |_logs \... |_public \ |_index.php |_... |_src \... |_tests \... |_var \... |_vendor \... |_README.md |_composer.json |_phpunit.xml |_composer.json
Vous pouvez avoir plus ou moins de répertoires, les plus importants sont les suivants:
- app : contient les fichiers descriptifs de l'application
- src : répertoire où nous allons stocker notre code source
- composer.json : fichier qui va nous servir pour l'autoloader
Pour partir sur une base simple, vous pouvez supprimer (sauvegarder si besoin) le contenu des répertoires app et src
Chargement automatique du code
Le chargement automatique ou autoloading se fait grâce à composer dans le fichier composer .json. Repérez la section commençant par autoload:
"autoload": { "psr-4": { "App\\": "src/" } },
Cette section indique à composer que toutes les classes faisant partie de l'espace de nom App se trouvent dans le répertoire src. Nous allons modifier cette espace de nom pour le remplacer par tala (généralement le nom du projet ou de l'entreprise):
"autoload": { "psr-4": { "Tala\\": "src/" } },
Pour que la modification soit effective, il faut demander à composer de regénérer les fichiers de classes:
# cd /opt/slim # composer du Generating autoload files Generated autoload files
Quelques objets de Slim
Application
L'objet application est disponible en utilisant l'interface suivante:
use Slim\Factory\AppFactory;
L'objet Application suit le patron de conception fabrique et s'obtient en utilisant la méthode create:
$app = AppFactory::create();
Les méthodes
get, post, put, delete, option head, patch et any
Permet le routage en fonction de la méthode et URL demandée
$app->get($pattern, $callback);
- pattern: correspond à la route et peut contenir des expressions moustache:
- /users
- /users/{id}
- callback: correspond à la fonction de rappel avec la signature suivante:
function (Psr\Http\Message\ServerRequestInterface $request, Psr\Http\Message\ResponseInterface $response, array $args): Psr\Http\Message\ResponseInterface
Exemple:
$group->any('', function(Psr\Http\Message\ServerRequestInterface $request, Psr\Http\Message\ResponseInterface $response, array $args){
return $response->getBody()->write('Hello Wolrd');
});
Enverra 'Hello World' sur la route par défaut () peu importe la méthode http.
group
La fonction group permet de définir plusieurs routes en une seule fois.
$app->group($pattern, $callback);
- pattern: correspond à la route et peut contenir des expressions moustache:
- /users
- /users/{id}
- callback: correspond à la fonction de rappel avec la signature suivante:
function (Slim\Interfaces\RouteCollectorProxyInterface $group)
Exemple:
$app->group('/users', function (Slim\Interfaces\RouteCollectorProxyInterface $group) {
// Route par défaut qui liste tous les utilisateurs
$group->get('', function(Psr\Http\Message\ServerRequestInterface $request, Psr\Http\Message\ResponseInterface $response, array $args){
return $response->getBody()->write('Hello Wolrd');
});
// Route qui permet de lister un utilisateur grâce à son identifiant
$group->get('/{name}', function(Psr\Http\Message\ServerRequestInterface $request, Psr\Http\Message\ResponseInterface $response, array $args){
return $response->getBody()->write('Hello Wolrd '.$args['name']);
});
});
map
La fonction map permet de définir plusieurs méthode pour la même route en une seule fois:
$app->map($methodes, $pattern, $callback);
- methodes: est un tableau contenant le nom des méthodes en majuscule (eg. "GET",...)
- pattern: correspond à la route et peut contenir des expressions moustache:
- /users
- /users/{id}
- callback: correspond à la fonction de rappel avec la signature suivante:
function (Slim\Interfaces\RouteCollectorProxyInterface $group)
Exemple:
$app->map(["GET", "POST"], '', function(Psr\Http\Message\ServerRequestInterface $request, Psr\Http\Message\ResponseInterface $response, array $args){
return $response->getBody()->write('Hello Wolrd');
});
Enverra 'Hello World' sur la route par défaut () pour les méthodes GET et POST.
run
Cette méthode permet de démarrer l'application Slim pour effectuer le rendu
$app->run();
C'est normalement la dernière ligne de votre script index.
Requête
L'objet requête est disponible en utilisant l'interface suivante:
use Psr\Http\Message\ServerRequestInterface as Request;
Reponse
L'objet réponse est disponible en utilisant l'interface suivante:
use Psr\Http\Message\ResponseInterface as Response;
Création de classes
Nous allons créer une petite api qui permet de lister des utilisateurs.
Dans le répertoire src nous allons créer les fichiers suivants:
- User.php
<?php
namespace Tala;
class User
{
public $name, $id;
/**
* User constructor.
* @param $name
* @param $id
*/
public function __construct($name, $id)
{
$this->name = $name;
$this->id = $id;
}
}
- UserDao.php
<?php
namespace Tala;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Tala\User as User;
class UserDao
{
// tableau contenant les utilisateurs
private $users = array();
public function __construct()
{
// Ajout d'utilisateurs pour faire les tests
$this->users[] = new User("tala", 1);
$this->users[] = new User("jcf", 2);
}
public function getUsers(Request $request, Response $response, array $args): Response
{
$response->getBody()->write(json_encode($this->users));
return $response->withHeader('Content-Type', 'application/json')->withStatus(200);
}
public function getUserById(Request $request, Response $response, array $args): Response
{
$id = $args['id'];
foreach ($this->users as $user){
if($user->id == $id){
// Utilisateur trouvé, on retourne un 200
$response->getBody()->write(json_encode($user));
return $response->withHeader('Content-Type', 'application/json')->withStatus(200);
}
}
// Utilisateur non trouvé on retourne un 404
return $response->withStatus(404);
}
}
Ajout d'une route
Dans le répertoire app nous allons créer un fichier routes.php qui va contenir le code suivant:
<?php
declare(strict_types=1);
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\App;
use Slim\Interfaces\RouteCollectorProxyInterface as Group;
return function (App $app) {
$app->options('/{routes:.*}', function (Request $request, Response $response) {
// CORS Pre-Flight OPTIONS Request Handler
return $response;
});
$app->group('/users', function (Group $group) {
// Route par défaut qui liste tous les utilisateurs
$group->get('', \Tala\UserDao::class . ':getUsers');
// Route qui permet de lister un utilisateur grâce à son identifiant
$group->get('/{id}', \Tala\UserDao::class . ':getUserById');
});
};
Déclaration dans la page d'index
Il ne reste plus qu'a définir tout ça dans le fichier index.php du répertoire public:
<?php
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
// Création de l'application Slim
$app = AppFactory::create();
// Enregistrement des routes
$routes = require __DIR__ . '/../app/routes.php';
$routes($app);
$app->run();
Utilisation
Nous avons déclaré deux points de terminaisons ou endpoint dans notre api :
- /users : pour lister tous les utilisateurs
- /users/{id} : pour afficher un utilisateur en fonction de son identifiant