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:
 

Route
Méthode
Type
Description
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.
Télécharger le code source en cliquant ici.
Outil gratuit pour tester votre API REST https://tools.waytolearnx.com/rest-api-tester.

 

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.
Récupérer les données Json envoyé par la méthode PUT en PHP

<?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);
	}
?>
Tutoriel cURL

28 réflexions sur “Créer et utiliser une API REST en PHP

  • janvier 6, 2020 à 9:40 am
    Permalien

    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 :

        {
            "id": "1",
            "name": "PEN",
            "description": "Pen Blue",
            "price": "1",
            "category_id": "1",
            "created": "2020-07-04 00:00:00",
            "modified": "2020-09-03 00:00:00"
        },
    

    à la place de:

        {
            "0": "1",
            "id": "1",
            "1": "PEN",
            "name": "PEN",
            "2": "Pen Blue",
            "description": "Pen Blue",
            "3": "1",
            "price": "1",
            "4": "1",
            "category_id": "1",
            "5": "2020-07-04 00:00:00",
            "created": "2020-07-04 00:00:00",
            "6": "2020-09-03 00:00:00",
            "modified": "2020-09-03 00:00:00"
        },
    
  • janvier 24, 2020 à 7:57 pm
    Permalien

    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…

  • janvier 24, 2020 à 11:00 pm
    Permalien

    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…

  • janvier 24, 2020 à 11:03 pm
    Permalien

    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.

    • janvier 25, 2020 à 3:49 am
      Permalien

      L’article à été mis a jour 🙂

  • janvier 30, 2020 à 5:03 pm
    Permalien

    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

  • février 11, 2020 à 11:13 am
    Permalien

    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.

    • février 11, 2020 à 11:37 am
      Permalien

      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é 🙂

  • février 19, 2020 à 3:33 pm
    Permalien

    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.

    • février 19, 2020 à 4:08 pm
      Permalien

      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:

      ini_set('display_errors', 1);
      ini_set('display_startup_errors', 1);
      error_reporting(E_ALL);

      Bon courage 🙂

  • février 20, 2020 à 10:48 am
    Permalien

    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.

    • février 20, 2020 à 11:29 am
      Permalien

      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

      $result = mysqli_query($conn, $query) or die(mysqli_error($conn));
  • février 20, 2020 à 11:16 am
    Permalien

    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 ?

  • février 20, 2020 à 11:18 am
    Permalien

    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 ?

    • février 20, 2020 à 11:36 am
      Permalien

      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.

  • février 20, 2020 à 11:44 am
    Permalien

    Bon j’ai finalement trouvé la solution !
    Dans le fichier db_connect.php, sous la ligne :

    $conn = mysqli_connect($server, $username, $password, $db);

    ajouter ces 2 lignes :

    mysqli_query($conn,"SET CHARACTER SET 'utf8'");
    mysqli_query($conn,"SET SESSION collation_connection ='utf8_unicode_ci'");
  • février 27, 2020 à 9:17 pm
    Permalien

    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

    • février 28, 2020 à 6:12 pm
      Permalien

      Salut Paul 🙂
      je vous recommandes de suivre ce tuto.

      Bon courage.

      • février 29, 2020 à 5:00 pm
        Permalien

        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

        • mars 1, 2020 à 1:25 am
          Permalien

          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.

  • mars 1, 2020 à 2:53 pm
    Permalien

    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

    • avril 5, 2020 à 12:57 pm
      Permalien

      Avec plaisir 🙂
      Restez connecter, peut-être que nous allons ajouter un tuto sur la sécurité des API.

  • avril 4, 2020 à 6:22 pm
    Permalien

    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.

    • avril 5, 2020 à 1:04 pm
      Permalien

      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:

      $res = mysqli_query($conn,"SELECT * FROM my_table");
      
      while($row = mysqli_fetch_array($res)){
      
      	echo '<img src="data:image/jpeg;base64,'.base64_encode($row['image']).'">';
      
      }
  • avril 6, 2020 à 3:02 pm
    Permalien

    Merci pour ta réponse;
    mais malheureusement j’ai pas pu l’insérer !

    • avril 6, 2020 à 5:07 pm
      Permalien

      Je vous recommande de suivre ce tuto.

Commentaires fermés.