Créer et utiliser une API REST en PHP
REST (Representational State Transfer) est l’un des moyens pour accéder aux Web services. L’API REST est utilisée pour effectuer une requête HTTP GET, POST, PUT ou DELETE côté client vers le serveur pour récupérer ou pour modifier certaines informations sur le serveur.
Les services Web basés sur REST peuvent produire une sortie dans n’importe quel format, tel que CSV, JSON, RSS, etc. Cela dépend donc du format que vous souhaitez analyser facilement avec votre langage. Dans ce tutoriel, nous allons créer une API REST simple à l’aide du langage PHP.
Commençons par créer un exemple d’API rest, nous allons créer un répertoire ‘api/’. Ce répertoire contient tous les fichiers nécessaires pour ce tutoriel. Nous créerons un api rest pour le module produit qui aura la requête HTTP Get, Post, Put et Delete pour récupérer, ajouter, mettre à jour et supprimer les enregistrements de mysql. Les détails de l’API rest sont les suivants:
http://127.0.0.1/api/produits | GET | JSON | Récupérer toutes les produits. |
http://127.0.0.1/api/produits/{id} | GET | JSON | Récupérer les données d’un seul produit |
http://127.0.0.1/api/produits | POST | JSON | Insérer un nouveau produit dans la base de données. |
http://127.0.0.1/api/produits/{id} | PUT | JSON | Mettre à jour un produit dans la base de données. |
http://127.0.0.1/api/produits/{id} | DELETE | JSON | Supprimer un produit de la base de données. |
Nous allons utiliser les fichiers suivants pour ce tutoriel:
- index.php: Ce fichier est un fichier d’entrée. Ce fichier empêche la navigation dans les fichiers de répertoire.
- db_connect.php: Ce fichier utilisera la chaîne de connexion mysql.
- produits.php: Ce fichier contient tous les méthode d’API REST.
- post.php: Ce fichier permet d’envoyer une requête POST à notre API REST pour tester l’ajout d’un nouveau produit.
- put.php: Ce fichier permet d’envoyer une requête PUT à notre API REST pour tester la mise à jour d’un nouveau produit.
- delete.php: Ce fichier permet d’envoyer une requête DELETE à notre API REST pour tester la suppression d’un nouveau produit.
- .htaccess: Ce fichier est utilisé pour le routage.
Schéma de la table des produits:
Créez une base de données MySQL nommée ‘stock’ par exemple. Si vous avez déjà une base de données de test, exécutez le code ci-dessous dans la fenêtre de requête SQL de la base de données. Comme illustré dans l’image ci-dessous :
CREATE TABLE IF NOT EXISTS `produit` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(256) NOT NULL, `description` text NOT NULL, `price` int(255) NOT NULL, `category_id` int(11) NOT NULL, `created` datetime, `modified` timestamp DEFAULT CURRENT_TIMESTAMP, primary key (id) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Pour le moment, ajouter ces enregistrements manuellement, parce que nous allons voir comment les ajoutés en utilisant l’api Rest.
INSERT INTO produit VALUES (1, 'PEN', 'Pen Blue', 1.23, 1, '2020-7-04', '2020-9-03'); INSERT INTO produit VALUES (2, 'PC', 'Apple products', 300.99, 2, '2019-1-01', '2019-5-14'); INSERT INTO produit VALUES (3, 'Car', 'Mercedes benz', 985470.47, 3, '2019-2-06', '2019-6-23');
Ajouter le fichier .Htaccess
Nous allons créer le fichier .htaccess et écrire une règle pour accéder à l’API Rest avec des URLs propres. Pour cela, nous ajouterons les règles suivantes,
RewriteEngine On # Activer le module Rewrite RewriteRule ^produits/?$ produits.php [NC,L] RewriteRule ^[^/]+/(\d+)$ produits.php?id=$1
Pour activer le module Rewrite sur WampServer, voir l’image ci-dessous :
Connexion à la base de données MySQL avec PHP
Après avoir créé la table « produit », nous allons créer le fichier db_connect.php pour établir une connexion avec la base de données MySQL.
<?php $server = "localhost"; $username = "root"; $password = ""; $db = "stock"; $conn = mysqli_connect($server, $username, $password, $db); ?>
API REST pour récupérer tous les enregistrements de MySQL
Nous allons créer une requête HTTP de type GET pour accéder à tous les enregistrements de produits à partir de MySQL. Nous allons utiliser une requête MySQL pour récupérer les données de la table « produit » et envoyer les données JSON au client en tant qu’objet.
Nous allons maintenant créer le fichier produits.php et inclure le fichier de connexion MySQL pour accéder aux données de la base de données.
<?php // Se connecter à la base de données include("db_connect.php"); $request_method = $_SERVER["REQUEST_METHOD"]; ... ?>
Nous avons également utilisé la méthode $_SERVER pour accéder aux informations sur l’action, comme l’ajout, la modification ou la suppression.
Dans le même fichier, Nous allons « switcher » entre les méthodes de requête( comme GET, POST, DELETE et PUT) à l’aide de l’instruction « switch » en PHP :
<?php switch($request_method) { case 'GET': if(!empty($_GET["id"])) { // Récupérer un seul produit $id = intval($_GET["id"]); getProducts($id); } else { // Récupérer tous les produits getProducts(); } break; default: // Requête invalide header("HTTP/1.0 405 Method Not Allowed"); break; } ?>
Nous avons créé une requête GET pour extraire toutes les données relatives aux produits de la base de données mysql. Pour les données relatives à un seul produit, nous transmettons l’id du produit. Nous avons défini la méthode getProducts() afin que nous puissions créer une méthode comme ci-dessous:
<?php function getProducts() { global $conn; $query = "SELECT * FROM produit"; $response = array(); $result = mysqli_query($conn, $query); while($row = mysqli_fetch_array($result)) { $response[] = $row; } header('Content-Type: application/json'); echo json_encode($response, JSON_PRETTY_PRINT); } ?>
La méthode mysqli_query() récupère les données de la table « produit » de MySQL et les stocke comme abject dans la variable ‘result’. La méthode json_encode() convertit un tableau en json.
Maintenant, accédez à l’url « http://127.0.0.1/api/produits » et vous obtiendrez un enregistrement de tous les produits de la table « produit ». Comme illustré dans l’image ci-dessous :
Api REST pour récupérer un seul produit
Nous allons créer une requête de type HTTP GET pour accéder à un seul enregistrement de produit à partir de la base de données MySQL via php.
function getProduct($id=0) { global $conn; $query = "SELECT * FROM produit"; if($id != 0) { $query .= " WHERE id=".$id." LIMIT 1"; } $response = array(); $result = mysqli_query($conn, $query); while($row = mysqli_fetch_array($result)) { $response[] = $row; } header('Content-Type: application/json'); echo json_encode($response, JSON_PRETTY_PRINT); }
Maintenant, accédez à l’url « http://127.0.0.1/api/produits/1 », et vous obtiendrez un seul enregistrement de produit à partir de la table des produits.
Api Reste pour créer un nouvel enregistrement dans la base de donnée MySQL
Nous allons créer une nouvelle Api Reste pour insérer un nouveau produit dans MySQL en utilisant php. Nous allons créer une requête de type POST car nous publierons des données JSON sur le serveur.
Nous allons ajouter un nouveau cas dans le bloc « Switch » comme indiqué ci-dessous :
<?php ... case 'POST': // Ajouter un produit AddProduct(); break; ... ?>
Nous allons maintenant créer la méthode AddProduct() dans le fichier « produits.php ».
<?php function AddProduct() { global $conn; $name = $_POST["name"]; $description = $_POST["description"]; $price = $_POST["price"]; $category = $_POST["category"]; $created = date('Y-m-d H:i:s'); $modified = date('Y-m-d H:i:s'); echo $query="INSERT INTO produit(name, description, price, category_id, created, modified) VALUES('".$name."', '".$description."', '".$price."', '".$category."', '".$created."', '".$modified."')"; if(mysqli_query($conn, $query)) { $response=array( 'status' => 1, 'status_message' =>'Produit ajoute avec succes.' ); } else { $response=array( 'status' => 0, 'status_message' =>'ERREUR!.'. mysqli_error($conn) ); } header('Content-Type: application/json'); echo json_encode($response); } ?>
Nous allons maintenant tester notre API Rest pour ajouter un nouveau produit en envoyant une requête POST, pour cela nous allons créer le fichier « post.php » et en ajoutant le code suivant.
<?php $url = 'http://127.0.0.1/api/produits'; $data = array('name' => 'PEC', 'description' => 'Pencil 2H', 'price' => '2.25', 'category' => '9'); // utilisez 'http' même si vous envoyez la requête sur https:// ... $options = array( 'http' => array( 'header' => "Content-type: application/x-www-form-urlencoded\r\n", 'method' => 'POST', 'content' => http_build_query($data) ) ); $context = stream_context_create($options); $result = file_get_contents($url, false, $context); if ($result === FALSE) { /* Handle error */ } var_dump($result); ?>
Maintenant, accédez à l’url « http://127.0.0.1/api/post.php », et vous voyez un nouvel enregistrement de produit est inséré dans la table des produits, et sur le navigateur vous aurez le résultat suivant :
Api Reste pour modifier un enregistrement dans la base de donnée MySQL
Nous allons créer une nouvelle requête HTTP PUT pour mettre à jour les données dans la base de données MySQL.
Nous allons ajouter un nouveau cas dans le bloc « Switch » comme indiqué ci-dessous :
<?php ... case 'PUT': // Modifier un produit $id = intval($_GET["id"]); updateProduct($id); break; ... ?>
Maintenant, nous allons créer la méthode updateProduct() dans le fichier « produits.php ». Nous allons utiliser l’id du produit que nous voulons mettre à jour et deuxièmement, les données mises à jour au format JSON.
Puisque PHP n’a pas de variable $_PUT similaire à $_GET et $_POST pour récupérer les valeurs transmises, nous utilisons les flux d’entrée (input stream 'php://input'
) pour obtenir ces valeurs pour mettre à jour un produit.
<?php function updateProduct($id) { global $conn; $_PUT = array(); //tableau qui va contenir les données reçues parse_str(file_get_contents('php://input'), $_PUT); $name = $_PUT["name"]; $description = $_PUT["description"]; $price = $_PUT["price"]; $category = $_PUT["category"]; $modified = date('Y-m-d H:i:s'); //construire la requête SQL $query="UPDATE produit SET name='".$name."', description='".$description."', price='".$price."', category_id='".$category."', modified='".$modified."' WHERE id=".$id; if(mysqli_query($conn, $query)) { $response=array( 'status' => 1, 'status_message' =>'Produit mis a jour avec succes.' ); } else { $response=array( 'status' => 0, 'status_message' =>'Echec de la mise a jour de produit. '. mysqli_error($conn) ); } header('Content-Type: application/json'); echo json_encode($response); } ?>Nous allons maintenant tester notre API Rest pour mettre à jour le produit en envoyant une requête PUT via cURL, pour cela nous allons créer le fichier « put.php » et en ajoutant le code suivant.
<?php $url = "http://127.0.0.1/api/produits/1"; // modifier le produit 1 $data = array('name' => 'MAC', 'description' => 'Ordinateur portable', 'price' => '9658', 'category' => '2'); $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT"); curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($data)); $response = curl_exec($ch); var_dump($response); if (!$response) { return false; } ?>
Maintenant, accédez à l’url « http://127.0.0.1/api/put.php », et vous voyez que le produit en question a été mis à jour dans la table des produits, et sur le navigateur vous aurez le résultat suivant :
Api Reste pour supprimer un enregistrement dans la base de donnée MySQL
Nous allons créer une nouvelle requête d’API REST de type DELETE utilisant PHP pour supprimer un produit de la base de données MySQL. Nous transmettons l’id du produit que vous souhaitez supprimer en tant que paramètres.
Nous allons ajouter un nouveau cas dans le bloc « Switch » comme indiqué ci-dessous :
<?php ... case 'DELETE': // Supprimer un produit $id = intval($_GET["id"]); deleteProduct($id); break; ... ?>
Nous allons maintenant créer la méthode deleteProduct() dans le fichier « produits.php ». Nous utiliserons l’id pour supprimer l’enregistrement de la table « produit ».
<?php function deleteProduct($id) { global $conn; $query = "DELETE FROM produit WHERE id=".$id; if(mysqli_query($conn, $query)) { $response=array( 'status' => 1, 'status_message' =>'Produit supprime avec succes.' ); } else { $response=array( 'status' => 0, 'status_message' =>'La suppression du produit a echoue. '. mysqli_error($conn) ); } header('Content-Type: application/json'); echo json_encode($response); } ?>
Nous allons maintenant tester notre API Rest pour supprimer le produit en envoyant une requête DELETE via cURL, pour cela nous allons créer le fichier « delete.php » et en ajoutant le code suivant.
<?php $url = "http://127.0.0.1/api/produits/1"; // supprimer le produit 1 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); var_dump($response); curl_close($ch); ?>
Maintenant, accédez à l’url « http://127.0.0.1/api/delete.php », et vous voyez que le produit en question a été supprimer dans la table des produits, et sur le navigateur vous aurez le résultat suivant :
Conclusion
Il y’a une autre solution, pour tester les méthodes GET/POST/PUT/DELETE que nous avons vu dans ce tutoriel en utilisant Postman, qui est un outil open-source pour tester les API RESTful que vous avez créées vous-même. Il offre une interface utilisateur avec laquelle faire des requêtes HTML, sans avoir à écrire un tas de code juste pour tester les fonctionnalités d’une API.
Pour ceux qui ne souhaitent pas voir retournés les lignes indexés par le numéro de champs, il suffit d’utiliser le paramètre MYSQLI_ASSOC :
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
Ainsi, vous obtenez :
à la place de:
la mise a jour de la base de donnée ne fonctionne pas. en effet j’ai fait un écho de la requete et les valeur ne sont pas remis dedans…
N’oubliez pas d’appeler la méthode updateProduct(); dans le fichier produits.php. si toujours ne fonction pas téléchargez le code source en cliquant sur ce lien(https://waytolearnx.com/wp-content/uploads/2020/01/api-waytolearnx.com_.rar). chez moi le code source fonctionne bien.
J’ai ainsi pris le code source j’ai ainsi le même problème même plus (juste les retour du type produit bien ajouté).
pour la mise à jour toujours le même problème.
Incompréhensible peut-être la version de wampserver mais peux probable…
La mise a jour remet tout les chaînes de caractère dans la base de donnée vide. il y a juste heure et la date de modification qui se met à jours.
L’article à été mis a jour 🙂
pourriez-vous donnez le code permettant de récupérer les données et les afficher sur une page web.
je vous remercie par avance.
PS: je suis débutant de se genre de développement
Je vous recommande ce tutoriel.
Merci pour ce tuto bien complet !
Petit pinaillement : Tout est fait pour être en ASCII dans le code source, SAUF dans produits.php la ligne « ‘status_message’ =>’Produit ajouté avec succès.' » qui contient des accents 😉
Je le mentionne car tous le reste est sans accents, donc je suppose que la volonté initiale était de ne mettre aucun accents.
Oui, c’est pour quoi j’ai supprimé les accents, c’est pour éviter les erreurs de codage. Merci pour cette remarque, c’est corrigé 🙂
Bonjour, j’ai testé votre tuto avec la base de données fournie en exemple et cela fonctionne parfaitement.
J’ai essayé de reproduire la même chose avec une autre base de données contenant des membres et là rien ne s’affiche. J’ai une page blanche.
Je n’arrive pas à trouver l’erreur.
Il ne s’agit pas de la connexion à la base de données, j’ai testé les nouveaux identifiants avec la page produits et ça s’affiche.
Auriez-vous une idée ?
Je précise que je débute dans la création d’API.
Bonjour kmellia 🙂
Pour afficher les données des membres sur le navigateur, d’abord vous devez insérer des données dans la base de donnée soit via l’api(méthode POST) soit manuellement en utilisant l’instruction insert:
INSERT INTO membres VALUES (1, 'Thomas', 20, ....);
exécutez-le sur le shell MySQL, ou via PHPmyAdmin, comme montré sur le tutoriel.Et n’oubliez pas de modifier le code pour qu’il correspond à la structure de votre base de données.
Si vous pensez que vous avez des erreurs dans votre code, essayez d’ajouter ces lignes au début de votre fichier PHP, pour afficher tous les erreurs de votre script:
Bon courage 🙂
Merci pour la réponse rapide.
Ma base de données n’est pas vide, elle contient des données.
Le problème de vient pas de là.
Par contre j’ai des accents dans ma base de données.
ça peut jouer ?
J’ai ajouté les lignes plus haut dans le fichier php juste après la balise ouvrante mais ça n’affiche pas d’erreurs.
Je me retrouve toujours encore avec une page blanche.
Non, essayez d’éviter les accents dans votre base de données,
Là, c’est bizarre, essayez d’ajouter cette ligne
var_dump($result);die();
après la ligne 7 ($result = mysqli_query($conn, $query);
) dans la méthode getProducts() et voir qu’est ce qu’il renvoie.Si’il ne renvoie rien, remplacer la ligne 7 par la ligne suivante, pour voir si il y a des erreurs au niveau de la requête
Bon ben j’ai trouvé le problème.
C’est bien les accents.
Que dois-je faire, ajouter pour que les accents soient pris en compte ?
Bon ben j’ai trouvé le problème.
C’est bien les accents.
J’ai testé une petite table avec et sans accents.
Sans accent, les données s’affichent très bien et avec accent j’ai une page blanche.
Que dois-je faire/ajouter pour que les accents soient pris en compte ?
Ok, super 🙂
Pour que les accents soient pris en compte essayez d’ajouter
$mysqli->query('SET NAMES utf8');
après la connexion à la base de données dans votre fichier PHP.Bon j’ai finalement trouvé la solution !
Dans le fichier db_connect.php, sous la ligne :
ajouter ces 2 lignes :
Bonjour,
j’ai ainsi effectué votre tuto maintenant je voudrais mettre en place un système d’identification pour un administrateur. En effet, je voudrais que lorsque l’administrateur se connecte il pourrait modifier les ressources (UPDATE, DELETE, ADD). Alors que les personnes pas identifier pourront que les consulter.
Auriez vous un tuto pour faire cela, j’ai fais quelque recherche mais sans trop réellement de succès
En vous remerciant par avance.
Cordialement
Salut Paul 🙂
je vous recommandes de suivre ce tuto.
Bon courage.
Bonjour,
suite a ma demande pour faire un espace d’administrateur. j’ai une question car en effet si j’effectue ce tuto. l’API REST ne sera pas sécuriser car si on utilise postman un pirate pourra toujours supprimer ou ajouter une ressource via l’url. De plus une api doit rester sans état donc pas possible de crée une une session sur le serveur..
Comment je peux sécuriser l’api de cela?
En vous remerciant par avance
Cordialement
Vous pouvez utiliser le token (par exemple: JWT) pour authentifier l’utilisateur, Dans Postman il y a un champ où l’utilisateur doit spécifier le token pour qu’il puisse exécuter la requête.
Dans la réponse JSON renvoyée par le serveur, vous pouvez renvoyer le message « 405 Method Not Allowed » si l’utilisateur tente de violer le contrat d’API, par exemple, en essayant de supprimer une ressource à l’aide de la méthode DELETE.
Sachez que la plupart des serveurs n’autorisent pas par défaut POST/PUT/DELETE.
Je vous remercie pour votre réponse je vais me pencher sur cela.
Vous auriez pas par hasard des exemples, Tuto la dessus?
J’ai un peux chercher sur internet mais rien de vraiment concluant pour moi je vous remercie
Avec plaisir 🙂
Restez connecter, peut-être que nous allons ajouter un tuto sur la sécurité des API.
Bonjour;
Très bonne tuto, je l’ai effectué et testé. Maintenant, pouvons nous ajouter un champs Image dans la table et l’afficher correctement, sachant que json n’accepte pas les données BLOB.
Sachant que je travaille sur Windev Mobine, je voudrai apprendre plus sur ce genre d’API.
Encore merci pour ce traivail. cordialement.
Si j’ai bien compris, vous souhaitez transférer des images vers une application mobile via JSON. Vous pouvez encoder l’image en Base64. En fait les données binaires en JSON sont généralement mieux représentées sous une forme encodée en Base64. Essayer le code suivant pour afficher une image stocké dans votre table:
Merci pour ta réponse;
mais malheureusement j’ai pas pu l’insérer !
Je vous recommande de suivre ce tuto.