đȘ¶ Flight PHP#
Indication
Cette page à pour but de découvrir le langage PHP au travers de micro framework et le design pattern MVC.
Composer#

Note
Composer est un gestionnaire de dépendances écrit en PHP pour PHP.
Il permet Ă ses utilisateurs de dĂ©clarer et dâinstaller les bibliothĂšques dont le projet principal a besoin.
Composer utilise un fichier composer.json
qui contient plusieurs informations sur le projet dont la liste des librairies utilisées. Il est ensuite capable de télécharger automatiquement ces librairies (et les dépendances associées) et de générer un autoloader pour les utiliser simplement dans vos projets PHP.
Installation de composer#
Lâinstallation de composer est trĂšs simple (dans les 2 cas il faut avoir la commande php disponible dans le terminal) :
Sous Windows, il vous suivre les instructions suivantes
Sous unix utiliser votre gestionnaire de package
apt-get install composer
,dnf install composer
, âŠ
Utilisation de composer#
Composer est un logiciel qui fonctionne en ligne de commande, ainsi il vous suffit dâinvoquer composer
pour accĂšder Ă la commande composer.
CrĂ©ation dâun rĂ©pertoire pour le projet#
$ mkdir test_composer
$ cd test_composer
Installation dâune librairie via composer#
$ composer require rmccue/requests
Cette commande lance la rĂ©cupĂ©ration et lâinstallation de la librairie requests. Si câest la premiĂšre fois que la commande est lancĂ©e, celle-ci va créée plusieurs rĂ©pertoires et fichiers :
|
pour spécifier les différentes dépendances, |
|
instannée des dépendances à un instant \(t\), |
|
le répertoire qui contient les fichies des dépendances. |
Note
Lâavantage câest que composer est capable de gĂ©rer les dĂ©pendances, donc si votre librairie Ă besoin dâune autre librairie pour fonctionner elle sera automatiquement tĂ©lĂ©chargĂ©e.
Avertissement
Il est intéressant de versionner le fichier composer.json
toutefois le composer.lock
ainsi que le dossier vendor
viendrait en revanche polluer notre dépÎt Git.
Utilisation de notre librairie#
Câest bien beau de tĂ©lĂ©charger des librairie mais encore faut-il ĂȘtre en mesure de les inclure.
Note
Lors dâune install ou dâun update composer va automatiquement gĂ©nĂ©rĂ© un autoloader autoload.php
disponible à la racine du répertoire vendor.
Cet autoloader permet de ne pas avoir Ă inclure les fichier des diffĂ©rentes librairies mais utilise un systĂšme dâautoloader, vous nâavez quâĂ vous soucier des namespace.
<?php
require "vendor/autoload.php"; // Inclusion de l'autoloader
Découverte de requests en PHP#
Objectif
Nous allons voir dans cette partie comment dĂ©velopper une application en PHP appelant une API qui va rĂ©cupĂ©rer le rĂ©sultat de la requĂȘte en JSON (JavaScript Object Notation) pour lâafficher sur votre site web.
Les API sur Internet
Les API sont un moyen dâaccĂ©der aux donnĂ©es dâun site sans avoir lâautorisation dâaccĂ©der directement Ă la base de donnĂ©es. Il y a beaucoup de portails sĂ©curisĂ©s permettant Ă vos applications web de manipuler les donnĂ©es renvoyĂ©es par ces sites.
Lâexemple parfait est Twitter. Elle permet de lire la timeline dâune personne en particulier, de rechercher des statuts Ă partir dâun mot clĂ©, de modifier les paramĂštres de votre compte, etc.
Pourquoi le format JSON ?
Vous pouvez utiliser les API avec de nombreux langages et retourner les donnĂ©es de plusieurs façons. Lâune dâelles est le JSON (JavaScript Object Notation). Câest un format de donnĂ©es lĂ©ger, facile Ă lire et Ă Ă©crire et compatible avec pas mal de langages de dĂ©veloppement.
Sa structure est composĂ©e dâobjets et de tableaux. Sa flexibilitĂ© fait de JSON le parfait candidat pour retourner des donnĂ©es.
Requests et PHP#
Faire une requĂȘte est trĂšs simple :
<?php
$response = Requests::get('https://ingen.ugaritic.fr/api/books/');
Et si on affiche le contenu de $response
:
<?php
var_dump($response->body);
Pour obtenir le statut de la réponse:
<?php
var_dump($response->status_code);
Pour obtenir un tableau à partir du corp de la réponse:
<?php
$books = json_decode($response->body);
On peut maintenant itérer sur ce tableau pour afficher chaque titre de livre:
<?php
foreach($books as $book){
echo $book->title;
}
Ă faire
Modifiez votre fichier pour afficher sous une belle forme HTML chaque Ă©lĂ©ment retournĂ© par lâAPI,
Essayez de rĂ©cupĂ©rer lâĂ©lĂ©ment JSON Ă lâurl suivante: /api/books/a-game-of-thrones comme prĂ©cĂ©demment,
Comment corriger ce problĂšme ?
Indication
Vous venez de découvrir un gestionnaire de dépendances en PHP qui sera bien utile pour la suite de nos aventures ! Vous avez également découvert les API REST et le format de données JSON ! Félicitations !
PHP & la POO#
La dĂ©finition dâune classe commence par le mot-clĂ© class
suivi du nom de la classe.
<?php
class Warrior{
//Attributs
public $name = 'Conan'; //default value
public function my_name(){
echo $this->var;
}
}
Pour crĂ©er lâinstance dâune classe on utilise le mot-clĂ© new
.
<?php
include('warrior.php');
$warrior1 = new Warrior();
$warrior1->my_name();
Note
Les attributs sont dĂ©finies au sein dâune classe en utilisant un des mots-clĂ©s public
, protected
ou private
suivie dâune dĂ©claration classique de variable.
Important
Les variables au sein dâune classe sont appellĂ©es attributs (membres, propriĂ©tĂ©s ou encore champs).
Au sein des mĂ©thodes de classes, les attributs peuvent ĂȘtre appelĂ©es en utilisant la syntaxe ->
(opĂ©rateur de lâobjet):
$this->my_attr.
La pseudo-variable $this
est disponible au sein de nâimporte quelle mĂ©thode quand celle-ci est appelĂ©e depuis un objet. $this
est une rĂ©fĂ©rence Ă lâobjet appellant.
Ă faire
Dans notre classe warrior, ajouter les attributs (publiques) suivants avec une valeur par défault:
point de vie (hp)
point dâattaque (att)
point de défence (def)
Note
Les attributs sont définies comme publiques, protégées ou privées.
Ă faire
<?php
class Warrior{
//Attributs
public $name = 'Conan'; //default value
private $hp = 10;
private $att = 6;
private $def = 3;
public function my_name(){
echo $this->var;
}
}
<?php
include('warrior.php');
$warrior1 = new Warrior();
$warrior1->my_name();
echo $warrior->name;
echo $warrior->att;
echo $warrior->def;
echo $warrior->hp;
Que se passe tâil lors de lâaccĂšs au attributs hp, att et def ?
Astuce
Pour remĂ©dier aux soucis dâaccessibilitĂ©s, nous allons mettre en oeuvre la notion de getter et de setter
Ă faire
<?php
class Warrior{
//Attributs
public $name = 'Conan'; //default value
private $hp = 10;
private $att = 6;
private $def = 3;
public function get_hp(){
return $this->hp;
}
public function set_hp($hp){
$this->hp = $hp;
}
public function my_name(){
echo $this->var;
}
}
Tester ces deux nouvelles mĂ©thodes, quels est leur intĂ©rĂȘt ? Ajouter les getters et setters pour les autres attributs de notre classe.
Note
La dĂ©claration de constructeur permet dâajouter un comportement qui sera appelĂ© Ă chaque crĂ©ation dâune nouvelle instance de la classe.
<?php
class Warrior{
//Attributs
public $name = 'Conan'; //default value
private $hp = 10;
private $att = 6;
private $def = 3;
function __construct($name, $hp, $att, $def){
//TODO: complete behavior
}
}
Ce constructeur permet dâinitialiser les attributs de notre instance lors de sa crĂ©ation.
Ă faire
Complétez le constructeur de notre classe puis instanciez plusieurs objets de type Warrior et enfin manipulez les.
Ajouter une méthode
slap
qui permet à un guerrier de gifler un autre guerrier ..Ajouter une méthode
take_damage
qui permet à un guerrier de subir des dégùts ..Simuler une « bagarre » entre deux guerriers ..
Flight PHP#
Flight est un framework performant, simple et extensible pour PHP.
Flight vous permet de créer rapidement et facilement des applications Web (RESTful).
Flight est un micro framework PHP intĂ©grant notamment la gestion du routing , les views et bien dâautres choses..
Installation de Flight PHP#
$ composer require mikecao/flight
Note
Pour rappel, composer ne fait que tĂ©lĂ©charger les sources des librairies PHP (les fichiers php donc) et crĂ©er automatiquement un autoloader que nous utiliserons dans notre projet. Il faut donc retenir que ces librairies ne sont pas installĂ©es dans le systĂšme mais uniquement tĂ©lĂ©charger dans le rĂ©pertoire vendor. Il sâagit dâailleurs dâune bonne pratique dâavoir un dossier vendor par projet.
Pour commencer#
<?php
require "vendor/autoload.php";
Découverte du routing#
Dans le fichier index.php
rajouter le code suivant:
<?php
Flight::route('/', function(){
echo 'hello world!';
});
Flight::start();
Rendez-vous sur votre site web local
Normalement vous devriez voir une page blanche avec les mots hello world!
,
Félicitations!
Quelques précisions:
La méthode statique: start
permet de charger le framework et de mettre en place le routing.
La méthode statique route
permet dâassocier Ă un pattern de route, une fonction. En lâoccurrence /
signifie lâindex du site web et ensuite nous avons dĂ©clarĂ© une fonction directement dans le passage de variable.
Ainsi, ceci:
<?php
Flight::route('/', function(){
echo 'hello world!';
});
est identique Ă cela:
<?php
function hello(){
echo 'hello world!';
}
Flight::route('/', 'hello');
Routing & paramĂštre#
<?php
Flight::route('/hello/@name', function($name){
echo "hello, $name!";
});
Ă faire
Quâelle est lâutilitĂ© de ce code ?
Indication
Nous venons de dĂ©couvrir la base de routing et le principe dâun framework, voyez vous lâutilitĂ© du routing Ă prĂ©sent ?
Composer et autoloading#
Vous aurez remarqué que depuis le début nous utilisons le fichier autoload.php
pour charger les librairies installées via composer.
Et si je souhaite charger automatiquement mes propres fichiers ?
Nous lâavons dĂ©jĂ vue, le fichier composer.json
permet de lister les dépendances dont notre projet à besoin mais nous pouvons également y ajouter nos propres fichiers.
Nous adoptons la structure de projet suivante:
-- src/
-- vendor/
-- composer.json
-- composer.lock
-- index.php
Astuce
Si nous ajoutons un fichier functions.php
dans notre dossier src
, il suffit de modifier le fichier composer.json
comme ceci pour ajouter notre fichier de fonctions Ă lâautoloader:
{
"require": {
"mikecao/flight": "^1.3",
},
"autoload": {
"files": [
"src/functions.php",
"src/utils.php"
]
}
}
Via lâobjet autoload
et sa propriété files
nous indiquons Ă composer de charger les fichiers lister.
Ainsi functions.php
et utils.php
seront chargés automatiquement.
Attention
Il convient dâappeller la commande composer dump-autoload
aprĂšs chaque modification du fichier composer.json
.
Vous savez désormais charger automatiquement vos fichiers via composer, ainsi seul le require
de lâautoloader de composer sera requis. En clair vous nâaurez plus besoin de charger un Ă un vos fichiers PHP !
Test unitaire & dâintĂ©gration avec PHP#
PlutĂŽt que de tout tester Ă la main de maniĂšre rĂ©pĂ©titif et fastidieuse, nous allons apprendre Ă automatiser les tests unitaires et dâintĂ©grations.
Pré-requis en PHP
Pour rĂ©aliser les tests unitaires et dâintĂ©grations nous aurons besoin des librairies php suivantes:
phpunit/phpunit
guzzlehttp/guzzle
symfony/process
Un petit composer require
pour lâinstallation ?
Nous allons donc créer un répertoire tests
Ă la racine de notre projet qui contiendra nos fichier de tests.
Premier test unitaire en PHP#
Lâexemple le plus simple pour comprendre le principe des tests unitaires est la fonction de multiplication.
Note
Pour rappel une multiplication est lâopĂ©ration mathĂ©matique permettant dâobtenir le produit de deux facteur (nommĂ©s facteur gauche et facteur droite).
Ă faire
Créer un fichier (vide)
functions.php
dans le répertoiresrc/
Créer dans le répertoire
tests/
un fichierUnitariesTest.php
Pensez Ă modifier votre
composer.json
pour charger automatiquement le fichier de fonctions qui se trouve dans le répertoiresrc/
PHPUnit#

Note
PHPUnit est un framework open source de tests unitaires dédié au langage de programmation PHP.
Il permet lâimplĂ©mentation des tests de non-rĂ©gression en vĂ©rifiant que les exĂ©cutions correspondent aux assertions prĂ©dĂ©finies.
Premier test#
Modifier le fichier UnitariesTest.php
pour que son contenu soit:
1<?php
2
3require_once 'vendor/autoload.php';
4
5use PHPUnit\Framework\TestCase;
6
7class UnitariesTest extends TestCase {
8
9 public function test_multiply(){
10 $this->assertEquals(4, multiply(2, 2));
11 }
12}
Quelques précisions
Nous venons de définir une classe de tests qui posséde un fonction permettant de tester notre fonction de multiplication (notez la présence du require
pour charger lâautoloader de composer).
La ligne 10 permet de vérifier que la fonction retourne bien le produit de 2 par 2 (à savoir 4).
Nous avons définit notre premier test, il serait donc temps de le lancer via la commmande suivante:
$ vendor/bin/phpunit tests/UnitariesTest.php
Normalement vous devriez avoir lâerreur suivante :
PHPUnit 7.5.2 by Sebastian Bergmann and contributors.
E 1 / 1 (100%)
Time: 15 ms, Memory: 4.00MB
There was 1 error:
1) MultiplyTest::test_multiply
Error: Call to undefined function multiply()
/home/sam/php/tests/UnitariesTest.php:8
ERRORS!
Tests: 1, Assertions: 0, Errors: 1.
Câest normal ! Nous respectons la philosophie TDD Ă savoir Ă©crire nos tests dâabord puis vĂ©rifier que ceux-ci Ă©chouent !
Ă faire
Il convient de créer maintenant notre fonction de multiplication, copier-coller dans votre fichier functions.php
le code (sans corriger erreur) suivant:
<?php
function multiply($facteur_gauche, $facteur_droite)
{
return $facteur_gauche + $facteur_droite;
}
Relancez votre test via la commmande suivante:
$ vendor/bin/phpunit tests/UnitariesTest.php
Attention
Notre test passe ! Mais notre jeu de donnĂ©es nâest pas complet ! Il convient donc dâajouter une assertion supplĂ©mentaire Ă notre test.
Ă faire
Ajoutez lâassertion que le produit de 3 par 7 est 21
Relancez votre test que constatez vous ?
Corrigez le code de votre fonction pour régler ce souci.
Bravo vous venez de faire votre premiĂšre suite de test unitaire.
Astuce
Le répertoire tests
ainsi que le fait de suffixer nos fichier par Test.php
est une convention qui permet Ă php unit de charger de maniĂšre automatique lâensemble des tests du rĂ©pertoire.
Il suffit de lancer la commande suivante pour lancer lâensemble des tests du rĂ©pertoire tests/
:
$ vendor/bin/phpunit tests/
Test dâintĂ©gration avec FlightPHP#
Tester nos fonctions câest bien, utile et indispensable. Toutefois il est tout aussi indispensable de tester le retour de nos pages, nous allons donc voir comment mettre en place des tests dâintĂ©grations.
CrĂ©ation dâun client de test en PHP#
Pour pouvoir tester notre site en intégration il convient de créer un client de tests. Votre professeur étant fort sympatique en voici un à placer dans le fichier src/utils.php
<?php
use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\Process;
use GuzzleHttp\Client;
abstract class IntegrationTestCase extends TestCase {
private static $process;
public static function setUpBeforeClass(): void
{
self::$process = new Process(["php", "-S", "localhost:8080", "-t", "."]);
self::$process->start();
usleep(100000); //wait for server to get going
}
public static function tearDownAfterClass(): void
{
self::$process->stop();
}
public function get_client()
{
return new Client(['http_errors' => false]);
}
public function build_url($url)
{
return "localhost:8080" . $url;
}
public function make_request($method, $url)
{
$client = $this->get_client();
return $client->request($method, $this->build_url($url));
}
}
Ce client lance en processus votre site web et permet de tester le retour de requĂȘte HTTP sur celui-ci.
Notre premier test dâintĂ©gration avec FlightPHP#
Créer un fichier IntegrationsTest.php
dans le répertoire tests/
avec le contenu suivant:
<?php
require_once 'vendor/autoload.php';
class PagesIntegrationTest extends IntegrationTestCase{
public function test_index()
{
$response = $this->make_request("GET", "/");
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals("Hello World!", $response->getBody()->getContents());
$this->assertContains("text/html", $response->getHeader('Content-Type')[0]);
}
}
Le test dâintĂ©gration test_index
permet de:
Tester si le retour de la requĂȘte sur
/
en méthode GET retourne le code de statut 200,Et que le contenu de la réponse est bien
Hello World!
.Et que le type de contenu est bien du
text/html
.
Ă faire
Lancez la suite de tests,
Que constatez vous ?
Comment corriger le problĂšme ?
Comment mettre en place un test dâintĂ©gration pour la route
hello
de votre site ? Pensez Ă lâesprit TDD et comment tester cela.Et si notre route
hello
retourner une string sous la forme<h2>Hello $name </h2>
?Et si on utiliser lâassertion
assertContains
?
Twig#
Maintenant que nous savons router nos fonctions PHP vers un pattern dâurl (routing + Controller), il convient de sâintĂ©resser au V de MVC Ă savoir les vues !
Des vues ?#
Note
Les vues (parfois nommés templates) permettent de séparer la présentation (le code HTML) de notre logique métier (le controller). Flight intégre un mécanisme de gestion des vues mais celui-ci est plutÎt limité. Nous allons donc utiliser le moteur de templates du secteur PHP à savoir Twig.
Twig, un moteur de template#

Important
Twig est un moteur de templates pour le langage de programmation PHP, utilisé par défaut par le framework Symfony. Celui-ci est une traduction de jinja, moteur de templates écrit en python.
Twig dispose des fonctionnalités suivantes:
ContrĂŽle de flux complexe
Ăchappement automatique
Héritage des templates
Filtres de variables
Internationalisation (via
gettext
)Macros
Langage extensible
Syntaxe de Twig#
{{ ma_variable }}
{{ book.title }}
{% for book in books %}
{{ book.title }}
{% endfor %}
<ul>
{% for book in books %}
<li>
<strong>{{ book.title }}</strong>
</li>
{% endfor %}
</ul>
Filtres dans un template Twig#
Important
Les filtres fournissent des traitements sur une expression, si on les place aprÚs elle séparés par des pipes.
|
met une majuscule Ă la premiĂšre lettre dâune chaine de caractĂšres. |
|
met la chaine en lettres capitales. |
|
affiche la premiĂšre ligne dâun tableau. |
|
renvoie la taille de la variable. |
Variables spéciales et Twig#
loop
: contient les informations de la boucle dans laquelle elle se trouve. Par exemple loop.index donne le nombre dâitĂ©rations dĂ©jĂ survenue._route
: partie de URL située aprÚs le domaine
{{ path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')) }}
Installation de twig#
Un composer require
sur le package twig/twig
?
Twig et FlightPHP#
Initialisation
Pour commencer créer un répertoire views/
Ă la racine du projet.
Puis nous devons indiquer Ă Flight que nous allons utiliser Twig et le charger en extension mais tout dâabord nous devons charger Twig et le configurer.
index.php
#<?php
$loader = new \Twig\Loader\FilesystemLoader(dirname(__FILE__) . '/views');
$twigConfig = array(
// 'cache' => './cache/twig/',
// 'cache' => false,
'debug' => true,
);
Une fois que nous avons charger et configurer Twig, il convient dâindiquer Ă Flight de lâinscrire en tant quâextension
index.php
#<?php
Flight::register('view', '\Twig\Environment', array($loader, $twigConfig), function ($twig) {
$twig->addExtension(new \Twig\Extension\DebugExtension()); // Add the debug extension
});
DĂ©sormais Flight sera en mesure dâutiliser Twig.
Notre premiĂšre vue#
Et maintenant nous allons utiliser Twig conjointement avec Flight pour gĂ©nĂ©rer notre page Ă partir dâune vue.
<?php
Flight::route('/first_view/', function(){
Flight::view()->display('first_view.twig');
});
Ă faire
Que se passe tâil en se rendant sur notre page first_view ?
Créer le fichier
views/first_view.twig
pour corriger lâerreur.Un fichier vide câest bien, et si nous ajoutions un peu de HTML ?
Afficher des choses plus utiles#
Afficher du HTML via Twig câest bien, afficher le conteu de variables, tableaux, câest encore mieux. Nous allons dĂ©couvrir comment passĂ© des donnĂ©es Ă notre vue.
En reprenant notre vue:
<?php
Flight::route('/first_view/', function(){
Flight::view()->display('first_view.twig');
});
Nous allons la modifier, pour lui passer quelques données:
<?php
Flight::route('/first_view/', function(){
$data = [
'contenu' => 'Hello World!',
'name' => 'Ben Kenobi',
];
Flight::view()->display('first_view.twig', $data);
});
Nous passons Ă notre fichier twig le tableau data
qui contient deux éléments. Si nous rechargons notre page nous ne voyons pas nos données apparaßtre. Il faut donc modifier notre fichier .twig
pour afficher les données:
Ajoutez le code suivant Ă votre vue:
{{ contenu }}
{{ name }}
Twig et lâhĂ©ritage de template#
Important
La partie la plus puissante de Twig est lâhĂ©ritage des templates. LâhĂ©ritage de templates vous permet de crĂ©er un « squelette » de base contenant tous les Ă©lĂ©ments communs de votre site et dĂ©finissant les blocs que les modĂšles enfants peuvent remplacer.
Cela semble compliqué mais reste trÚs basique. Il est plus facile de comprendre cela en commençant par un exemple.
Template de base#
Ce template, que nous appellerons base.twig
, dĂ©finit un simple squelette de document HTML que vous pouvez utiliser pour une page simple Ă deux colonnes. Câest le travail des templates « enfants » de remplir les blocs vides de contenu:
<!DOCTYPE html>
<html lang="en">
<head>
{% block head %}
<link rel="stylesheet" href="style.css" />
<title>{% block title %}{% endblock %} - My Webpage</title>
{% endblock %}
</head>
<body>
<main>{% block content %}{% endblock %}</main>
<footer>
{% block footer %}
© Copyright 2008 by <a href="http://domain.invalid/">you</a>.
{% endblock %}
</footer>
</body>
</html>
Dans cet exemple, les balises {% block %}
définissent quatre blocs que les modÚles enfants peuvent remplir.
Note
La balise de bloc indique simplement au moteur de gabarit quâun modĂšle enfant peut remplacer les espaces rĂ©servĂ©s quâil contient.
Template enfant#
Un modĂšle enfant pourrait ressembler Ă ceci:
{% extends "base.twig" %}
{% block title %}Index{% endblock %}
{% block head %}
<style type="text/css">
.important { color: #336699; }
</style>
{% endblock %}
{% block content %}
<h1>Index</h1>
<p class="important">
Welcome to my awesome homepage.
</p>
{% endblock %}
Note
La balise {% extend %}
est la clĂ© ici. Il indique au moteur de modĂšle que ce modĂšle « étend » un autre modĂšle. Lorsque le systĂšme de gabarit Ă©value ce gabarit, il localise dâabord le parent. La balise extend devrait ĂȘtre la premiĂšre balise du modĂšle.
Variables global et filtre#
Parfois nous avons besoins de passer la mĂȘme valeur Ă plusieurs voir toutes nos vues, Twig intĂ©gre un mĂ©canisme trĂšs intĂ©ressant appellĂ© global.
<?php
Flight::register('view', '\Twig\Environment', array($loader, $twigConfig), function ($twig) {
$twig->addExtension(new \Twig\Extension\DebugExtension()); // Add the debug extension
$twig->addGlobal('ma_valeur', "Hello There!");
});
Ainsi la variable ma_valeur
sera passĂ© Ă chaque vue, il est possible de rendre cela plus intĂ©ressant en passant des variables plus complexes, voir le rĂ©sultat dâappel de fonction.
Twig et les Filtres#
Twig intégre de nombreux filtres par défaut, il est possible de créer nos propres filtres au besoin:
<?php
Flight::register('view', 'Twig_Environment', array($loader, $twigConfig), function ($twig) {
// Twig loading treatment
$twig->addFilter(new \Twig\TwigFilter('trad', function($string){
return $string;
}));
});
Note
Il sâagit dâun filtre trĂšs intĂ©ressant qui retourne la valeur inchangĂ©e.. Le but est ici juste de vous prĂ©senter la syntaxe pour crĂ©er vos propres filtres.
Shortcut#
Faire appel Ă Twig pour rendre nos templates câest chouette, toutefois faire appel Ă cette ligne de code :
<?php
Flight::view()->display('first_view.twig');
Reste assez complexe. Et si nous utilisions un raccourci pour faire appel Ă cette fonction ?
AprĂšs lâenregistrement de Twig ajouter le code suivant:
<?php
Flight::map('render', function($template, $data=array()){
Flight::view()->display($template, $data);
});
Ce code permet de dire que lorsque que nous ferons appel à la méthode render
de Flight, nous utiliserons Twig.
Sans shortcut |
Avec shortcut |
<?php
Flight::route('/first_view/', function(){
Flight::view()->display('first_view.twig');
});
|
<?php
Flight::route('/first_view/', function(){
Flight::render('first_view.twig');
});
|
Ă faire
En utilisant lâapproche TDD, les Tests unitaires et dâintĂ©grations
CrĂ©er une fonctions permettant de rĂ©cupĂ©rer les livres lister Ă lâadresse suivante https://ingen.ugaritic.fr/api/books/,
CrĂ©er une route ainsi quâune vue (template Twig) pour afficher le nombre de livres ainsi que les diffĂ©rents livres.
Voir aussi
Il reste encore pas mal dâaspects de twig Ă dĂ©couvrir comme Les structures de contrĂŽles , ou encore lâescaping
Formatter du Markdown en PHP#
Voir aussi
Pour en savoir un peu plus sur le đ Markdown.
Pour générer du HTML à partir de markdown on utilise en PHP la librairie michelf/php-markdown
(composer require ?)
Dans votre fichier functions.php
, ajouter la fonction suivante:
<?php
use MichelfMarkdown;
function renderHTMLFromMarkdown($string_markdown_formatted)
{
return Markdown::defaultTransform($string_markdown_formatted);
}
Et si nous ajoutions une route (markdown_test
) pour utiliser notre fonction ?
<?php
Flight::route('/markdown_test', function(){
echo renderHTMLFromMarkdown("##HELLO WORLD!");
});
Allons un peu plus loin#
Il est plus intĂ©ressant de stocker le contenu de nos pages statiques (prĂ©sentation de lâentreprise, mentions lĂ©gales, Ă propos, ..) dans diffĂ©rents fichiers puis de lire leurs contenu Ă la demande.
Créer dans à la racine de votre projets un répertoire
pages
Créer dans le répertoire
pages/
un fichiertest.md
avec le contenu suivant:
## Test
Indication
Pour rĂ©cupĂ©rer le contenu dâun fichier, PHP nous fournit la fonction file_get_contents.
Ainsi nous pouvons créer dans notre fichier tests/UnitariesTest.php
la fonction de test suivante:
<?php
public function test_readFileContent(){
$this->assertEquals("## Test", readFileContent("pages/test.md"));
}
On relance notre suite de tests, test_readFileContent échoue .. parfait !
Ajoutons la fonction
readFileContent
<?php
function readFileContent($filepath){
return file_get_contents($filepath);
}
Remplacer dans notre controller pour
/markdown_test
, la string##HELLO WORLD
par le contenu du fichierpages/test.md
Ă faire
Créer un template Twig pour afficher le contenu de votre page dans un template HTML,
Le code HTML produit sâaffiche correctement ? Lâutilisation du filtre
raw
pourra vous ĂȘtre utile,CrĂ©er une fonction
readPagesContent
qui prend en paramĂštre uniquement le nom de votre fichier.md
(sans lâextension.md
) et qui vous retourne le contenu de la pages (TDD?),Convertir le markdown en HTML nâest pas un job pour notre controller, il sâagit dâun boulot pour notre vue ! CrĂ©er un filtre Twig pour convertir du Markdown en HTML
Indication
La fonction sprintf
permet de faire du formatage de chaßne de caractéres.
<?php
$name = "Ben";
$hello_string = sprintf("hello %s", $name); // Hello Ben
Jurassic Park en PHP#

Un site commandé par InGen#

Note
La société InGen, spécialisée dans la création de créatures préhistoriques génétiquement modifiées; souhaite créer un site pour son dernier projet.
La majeure partie de son activitĂ© consiste Ă faire naĂźtre des dinosaures et Ă les prĂ©senter au sein de Jurassic Park. John Hammond, le PDG de lâentreprise InGen, travaille Ă la crĂ©ation dâun parc dâattractions sur Isla Nublar, une Ăźle quâil possĂšde au large du Costa Rica. Le parc comporte des animaux disparus tels que les dinosaures, comme attractions. Les crĂ©atures ont Ă©tĂ© clonĂ©s dans des installations spĂ©ciales Ă proximitĂ© sur Isla Sorna et amenĂ©s au parc.
ĂnoncĂ© du projet Jurassic Park en PHP#
Note
Le but de cet exercice est de contrĂŽler votre acquisition de connaissances par un simple exercice. Il convient de mettre en application les notions vues.
En appliquant les notions vues sur PHP, composer, les frameworks, etc. vous rĂ©aliserez un site web basique prĂ©sentant les diffĂ©rents dinosaures du parc. Les donnĂ©es vous sont pour cela fournit via lâAPI REST suivante API Dinosaurs.
Création de deux pages différentes (accueil et détails sur un dinosaure),
Mise en oeuvre du TDD (Test Driven Development),
Versionning sous Git (pensez à versionner votre projet au fur et à mesure de votre avancé),
Les donnĂ©es sont disponibles via lâAPI Dinosaurs ,
Les fichiers css, dâimages, etc. sont disponibles
ici
,Les templates HTML vous sont fournis dans la suite de cet énoncé,
Quelques conseils également.
Résultat du projet PHP
Page dâaccueil listant lâensemble des dinosaures
Lâurl de cette page devra ĂȘtre la racine de votre site (
/
),Les donnĂ©es seront rĂ©cupĂ©rer depuis lâAPI Dinosaurs.
Page de détails sur un dinosaure
Lâurl de cette page devra ĂȘtre sous la forme
/dinosaur/<slug du dinosaure>/
(oĂč le slug correspond au slug retournĂ© par lâAPI Dinosaurs);Les donnĂ©es dâun seul dinosaure peuvent ĂȘtre rĂ©cupĂ©rĂ©es via lâAPI Dinosaurs, par exemple https://ingen.ugaritic.fr/api/dinosaurs/brachiosaurus permet de rĂ©cupĂ©rer les informations du brachiosaure;
Les « Top Rated Dinosaurs » sont une rĂ©cupĂ©ration alĂ©atoire de trois dinosaures parmis les septs retournĂ©es par lâAPI Dinosaurs , lâutilisation de la fonction PHP
array_rand
vous est vivement conseillé.
Indication
CrĂ©er dâabord votre projet sous Gitlab et pensez directement Ă le cloner;
RĂ©cupĂ©rer les fichiers dâassets et placer les dans un rĂ©pertoire assets Ă la racine de votre projet;
Penser Ă faire un composer require de toutes les libs;
Lâapproche TDD vous aidera grandement, quelles sont les fonctions que je vais devoir dĂ©velopper et les T.U associĂ©s, les pages et les T.I associĂ©es;
Avancer par Ă©tape, dâabord la rĂ©cupĂ©ration de tous les dinosaures (test ?) puis la page dâaccueil, puis la page de dĂ©tail et enfin les  » Top Rated Dinosaurs « ;
Respirer câest important;
Aller câest cadeau un petit exemple de la fonction
array_rand
(par contre la grande question demeure .. comment recrĂ©er un tableau Ă partir des clĂ©s dâun autre tableau ?):
<?php
$colors = array("red","green","blue","yellow","brown");
$random_keys = array_rand($colors, 3); // On récupére trois clés aléatoires
echo $colors[$random_keys[0]];
echo $colors[$random_keys[1]];
echo $colors[$random_keys[2]];
Quelques templates ?
<!DOCTYPE html>
<html>
<head>
<title>{%block title %}{% endblock %}Jurassic Park</title>
<meta charset="utf8" />
<link rel="stylesheet" type="text/css" href="/assets/css/reset.css" />
<link rel="stylesheet" type="text/css" href="/assets/css/style.css" />
<link href="https://fonts.googleapis.com/css?family=Montserrat|Staatliches" rel="stylesheet">
</head>
<body>
<header>
<a href="/">
Jurassic Park
</a>
<nav>
<a href="/">Home</a>
</nav>
</header>
<main>
{% block main %}{% endblock %}
</main>
<footer>
<img src="/assets/img/logojp.png" alt="Jurassic Park" />
</footer>
</body>
</html>
<!-- Héritage de template ? Block(s) ? -->
<section>
<h2>The world of Jurassic Park</h2>
<!-- iterate here ? -->
<a href="">
<figure>
<img src="" alt="" />
<figcaption>Discover the Brachiosaurus</figcaption>
</figure>
</a>
</section>
<!-- Héritage de template ? Block(s) ? -->
<div class="grid">
<article>
<h2>Discover the Brachiosaurus</h2>
<div class="description">
Lorem ispum
</div>
<div class="card">
<img src="" alt="" />
<dl>
<dt>Name</dt>
<dd>Brachiosaurus</dd>
<dt>Name meaning</dt>
<dd>Brachiosaurus</dd>
<dt>Diet</dt>
<dd>Brachiosaurus</dd>
<dt>Height</dt>
<dd>Brachiosaurus m.</dd>
<dt>Length</dt>
<dd>Brachiosaurus m.</dd>
<dt>Weight</dt>
<dd>Brachiosaurus kg.</dd>
</dl>
</div>
</article>
<aside>
<h3>Top rated dinosaurs</h3>
<!-- iterate here ? -->
<a href="">
<figure>
<img src="" alt="" />
<figcaption>Discover the Brachiosaurus</figcaption>
</figure>
</a>
</aside>
</div>
ORM et FlightPHP#
Note
Un ORM est une technique de programmation informatique qui crĂ©e lâillusion dâune base de donnĂ©es orientĂ©e objet Ă partir dâune base de donnĂ©es relationnelle en dĂ©finissant des correspondances entre cette base de donnĂ©es et les objets du langage utilisĂ©. On pourrait le dĂ©signer par « correspondance entre monde objet et monde relationnel ».
Découverte de Paris#
Paris est un ORM PHP open source disponible Ă cette adresse , il se base sur idiorm. Il sâagit dâune introduction Ă lâinstallation et lâutilisation de Paris. Je ne peux que vous encourager Ă aller consulter la documentation de celui-ci.
Comme toujours un simple composer require j4mie/paris
La base de données de tweets#
AprÚs avoir installé le package j4mie/paris
il suffit de configurer une connexion à notre base de données. Pour la suite nous allons utiliser la base de données SQLite tweets.sqlite3
.
Diagramme UML de la base de données tweets#
Configuration de Paris#
Astuce
Nous allons utiliser une capacitĂ© spĂ©ciale de Flight, le filtering pour ajouter un traitement avant que le framework ne traite notre requĂȘte.
Nous allons donc ajouter la connexion automatique Ă notre basse de donnĂ©es avant que celui-ci ne soit dĂ©marrĂ© (ce code doit ĂȘtre placĂ© juste aprĂšs lâenregistrement de lâextension Twig ):
<?php
Flight::before('start', function(&$params, &$output){
ORM::configure('sqlite:tweets.sqlite3');
});
Notre premier Model avec Paris#
Dans le dossier src créer le fichier models.php
, pensez Ă lâajouter au composer.json
<?php
class User extends Model {
public static $_table = 'Users';
}
VoilĂ ! Notre model est créé, Ă nous de lâutiliser !
Note
Il est inutile de prĂ©ciser la nature de notre table, lâORM se chargera pour nous de dĂ©duire la structure de nos objets Ă partir de la base de donnĂ©es. Le mapping de nos champs se fait automatiquement Ă partir de la structure de notre table.
Ainsi il sera possible dâaccĂ©der au champ name dâun utilisateur via lâattribut name qui sera automatiquement gĂ©nĂ©rĂ© lors de lâĂ©xĂ©cution par lâORM.
Par convention, les champs de nos tables ne doivent contenir ni préfixe, ni suffixe, les alias ont cette utilité ! De plus la clé primaire (unique) de notre table sera toujours nomée par convention id.
RequĂȘte via paris#
Pour plus dâinformations sur la maniĂšre dâĂ©crire des requĂȘtes, je vous invite Ă vous rendre Ă cette page de la documentation.
Dans le fichier index.php
nous allons crĂ©er une route pour afficher lâensemble des utilisateurs au sein dâun fichier de vue users.twig
.
<?php
User::find_many();
Cette ligne permet de rĂ©cupĂ©rer tout les utilisateurs prĂ©sent en bases. A vous maintenant dâitĂ©rer sur le tableau retourner afin dâobtenir une liste des utilisateurs au sein de votre vue.
Ă faire
Créer la classes dans le fichier
models.php
pour les tweets,Créer une route pour lister tous les tweets présent en base,
Récupérer les tweets de chaque utilisateur, cf la documentation sur les associations.
CrĂ©er une vue pour afficher uniquement les informations dâun seul utilisateur en prenant en paramĂštre
@username
le nom dâutilisateur cf la partie sur le requĂȘtage de la documentation.CrĂ©er une vue pour afficher un formulaire permettant dâajouter un tweet en base.
Indication
Nous venons de voir que manipuler une base de données est extrÚmement simple avec les bons outils, je vous invite donc à lire la documentation de Paris notamment sur la partie Querying.
API REST & JSON#
Note
Une API (Application Programming Interface) est une interface pour les applications; elle permet la manipulations de donnĂ©es, mĂ©thodes, fonctions etc. Câest un mĂ©canisme Ă la base de tout gĂ©nie logiciel complexe.
Nous allons voir dans cette partie comment dĂ©velopper une API en PHP qui retournera un rĂ©sultat sous la forme dâune rĂ©ponse au format JSON (JavaScript Object Notation).
Note
REST ( Representational State Transfer ) est un standard créé en 2000 par Roy Fielding dans sa thÚse « Architectural Styles and the Design of Network-based Software Architectures ».
Les API sur Internet
Les API sont un moyen dâaccĂ©der aux donnĂ©es dâun site sans avoir lâautorisation dâaccĂ©der directement Ă la base de donnĂ©es. Il y a beaucoup de portails sĂ©curisĂ©s permettant Ă vos applications web de manipuler les donnĂ©es renvoyĂ©es par ces sites.
Lâexemple parfait est Twitter. Elle permet de lire la timeline dâune personne en particulier, de rechercher des statuts Ă partir dâun mot clĂ©, de modifier les paramĂštres de votre compte, etc.
Ou encore lâAPI proposer par sur ce site Ă savoir ingen.ugaritic.fr
Important
Les API REST sont basĂ©es sur le Protocole HTTP ( Hypertext Transfer Protocol ) le protocole au coeur du web ! Bien sĂ»r, toutes les API ne sont pas basĂ©es sur HTTP, mais en choisissant une API REST, vous simplifiez lâintĂ©gration et lâutilisation de votre API en utilisant un protocole ouvert, standardisĂ© et simple dâutilisation.
Les API REST imitent la façon dont le web lui-mĂȘme marche dans les Ă©changes entre un client et un serveur. Une API REST est donc:
Sans Ă©tat (aucune idĂ©e de lâĂ©tat du client entre deux requĂȘtes, donc aucune liaison entre elles),
Cacheable (avec cache = mémoire),
Orienté client-serveur.
Pourquoi le format JSON ?
Vous pouvez utiliser les API avec de nombreux langages et retourner les donnĂ©es de plusieurs façons. Lâune dâelles est le JSON (JavaScript Object Notation). Câest un format de donnĂ©es lĂ©ger, facile Ă lire et Ă Ă©crire et compatible avec pas mal de langages de dĂ©veloppement.
Sa structure est composĂ©e dâobjets et de tableaux. Sa flexibilitĂ© fait de JSON le parfait candidat pour retourner des donnĂ©es.
Une API avec PHP & Flight#
Pour créer une api rien de bien complexe, il suffit de:
Définir une route (par exemple
/api/helloworld
),Retourner des données au format JSON depuis cette route.
Nous souhaitons créer une API associé à la route /api/helloworld
qui nous retourne un résultat équivalent à :
{"data":"Hello World!"}
Nous allons créer une nouvelle classe de test (donc un nouveau fichier php dans le répertoire tests
) ApiTest
qui servira Ă tester notre api !
<?php
require_once 'vendor/autoload.php';
class ApiTest extends IntegrationTest{
public function test_api_helloworld()
{
$response = $this->make_request("GET", "/api/helloworld");
$this->assertEquals(200, $response->getStatusCode());
$this->assertContains("application/json", $response->getHeader('Content-Type')[0]);
$body = $response->getBody()->getContents();
$json_result = json_encode(['data' => 'Hello World!']);
$this->assertEquals($json_result, $body);
}
}
Quelques précisions
Le test test_api_helloworld
effectue une requĂȘte sur /api/helloworld
et vérifie les assertions suivantes:
Le code statut de la requĂȘte est Ă©gale Ă 200,
Le type de réponse est bien
application/json
et nontext/html
,Le contenu de la rĂ©ponse est Ă©gale Ă la conversion en JSON dâun tableau associatif contenant une clĂ©
data
avec la valeurHello World
.
<?php
Flight::route('/api/helloworld', function(){
$data = [
'data' => 'Hello World!',
];
Flight::json($data);
});
Flight nous permet de retourner directement des données au format JSON via la méthode Flight::json
.
Ă faire
Créer une route (et les tests associés)
/api/helloworld/@name
qui retourneHello $name
,Créer une route (et les tests associés)
/api/users
qui retourne lâensemble des utilisateurs de la base de donnĂ©es tweets.CrĂ©er une route
/api/user/@username
qui retourne un utilisateur selon son nom dâutilisateur et lâensemble de ses tweets.
Javascript#

Note
JavaScript (qui est souvent abrégé en « JS ») est un langage de script léger, orienté objet, principalement connu comme le langage de script des pages web.
Mais il est aussi utilisé dans de nombreux environnements extérieurs aux navigateurs web tels que Node.js, Apache CouchDB voire Adobe Acrobat.
Le code JavaScript est interprĂ©tĂ© ou compilĂ© Ă la volĂ©e (JIT). Câest un langage Ă objets utilisant le concept de prototype, disposant dâun typage faible et dynamique qui permet de programmer suivant plusieurs paradigmes de programmation : fonctionnelle, impĂ©rative et orientĂ©e objet.
Une définition générale#
JavaScript est un langage de programmation qui permet dâimplĂ©menter des mĂ©canismes complexes sur une page web. Ă chaque fois quâune page web fait plus que simplement afficher du contenu statique â afficher du contenu mis Ă jour Ă des temps dĂ©terminĂ©s, des cartes interactives, des animations 2D/3D, des menus vidĂ©o dĂ©filants, etc.
JavaScript a de bonnes chances dâĂȘtre impliquĂ©. Câest la troisiĂšme couche des technologies standards du web, les deux premiĂšres Ă©tant HTML et CSS. Les trois couches viennent sâempiler naturellement.
Premier exemple de javascript#
Attention
Je vous conseille de mettre cette exemple dans une route Ă part de votre site par exemple /js/exemple1
Nous pouvons la baliser en HTML pour définir sa structure et son but:
<p>Player 1: Ben</p>
Nous pouvons ensuite ajouter du CSS pour rendre ça plus joli:
p {
font-family: 'helvetica neue', helvetica, sans-serif;
letter-spacing: 1px;
text-transform: uppercase;
text-align: center;
border: 2px solid rgba(0,0,200,0.6);
background: rgba(0,0,200,0.3);
color: rgba(0,0,200,0.6);
box-shadow: 1px 1px 2px rgba(0,0,200,0.4);
border-radius: 10px;
padding: 3px 10px;
display: inline-block;
cursor:pointer;
}
Et enfin utiliser JavaScript pour ajouter un comportement dynamique :
let para = document.querySelector('p');
para.addEventListener('click', updateName);
function updateName() {
let name = prompt('Enter a new name');
para.textContent = 'Player 1: ' + name;
}
Pensez Ă placer le code javascript en fin de fichier HTML dans les balises:
<script type="text/javascript">
</script>
JavaScript peut faire bien plus. Voyons cela plus en détail.
Que peut-il vraiment faire ?#
Le cĆur de JavaScript est constituĂ© de fonctionnalitĂ©s communes de programmation permettant de :
- stocker des valeurs utiles dans des variables.
Dans lâexemple plus haut, nous demandons un nouveau nom Ă lâutilisateur puis le stockons dans une variable appellĂ©e name.
- faire des opérations sur des strings.
Dans lâexemple plus haut, nous prenons la chaĂźne de caractĂšres « Player 1:  » et lui adjoinions la variable name pour crĂ©er lâĂ©tiquette texte complĂšte ââPlayer 1: Chris ».
- exécuter du code en réponse à certains évÚnements se produisant sur une page web.
Nous avons utilisĂ© un Ă©vĂšnement (« event ») click dans lâexemple plus haut pour dĂ©tecter quand lâutilisateur clique sur le bouton et alors exĂ©cuter le code qui met Ă jour lâĂ©tiquette texte.
Et bien plus encore!
Ajax#
AJAX est un raccourci pour Asynchronous JavaScript + XML (JavaScript asynchrone plus XML) inventĂ© par Jesse James Garrett. Pour simplifier, il sâagit dâemployer lâobjet non standard XMLHttpRequest
pour communiquer avec des scripts situés sur le serveur.
Lâobjet permet dâĂ©changer des informations sous diffĂ©rents formats (dont XML, HTML ou texte), mais son principal attrait est sa nature « asynchrone » qui implique quâil peut communiquer avec le serveur, Ă©changer des donnĂ©es et mettre Ă jour sans avoir Ă sans recharger la page.
Les deux fonctionnalités combinées vous permettent de :
faire des requĂȘtes vers le serveur sans avoir Ă recharger la page ;
analyser et travailler avec des documents XML.
XMLHttpRequest#
Pour faire une requĂȘte HTTP vers le serveur Ă lâaide de JavaScript, il faut disposer dâune instance dâune classe fournissant cette fonctionnalitĂ©. Câest ici que la classe XMLHttpRequest
intervient. Une telle classe a dâabord Ă©tĂ© introduite dans Internet Explorer sous la forme dâun objet ActiveX appelĂ© XMLHTTP.
Par la suite, Mozilla, Safari et dâautres navigateurs ont suivi en implĂ©mentant une classe XMLHttpRequest
qui fournit les mĂȘmes mĂ©thodes et propriĂ©tĂ©s que lâobjet ActiveX original de Microsoft. Dans lâintervalle, Microsoft a Ă©galement implĂ©mentĂ© XMLHttpRequest
.
Par conséquent, pour créer une instance (un objet) de la classe désirée fonctionnant sur plusieurs navigateurs, vous pouvez utiliser :
httpRequest = new XMLHttpRequest();
Un exemple simple#
Notre JavaScript demande un document HTML situĂ© Ă lâURL /js/test/
, qui contient le texte "Je suis un test."
, et nous affichons le contenu de cette ressource dans un message alert()
.
Note
Remarquez que cet exemple nâutilise que JavaScript (jQuery nâest pas utilisĂ© ici).
<script type="text/javascript" language="javascript">
function makeRequest(url) {
var httpRequest = false;
httpRequest = new XMLHttpRequest();
if (!httpRequest) {
alert('Abandon :( Impossible de créer une instance XMLHTTP');
return false;
}
httpRequest.onreadystatechange = function() { alertContents(httpRequest); };
httpRequest.open('GET', url, true);
httpRequest.send(null);
}
function alertContents(httpRequest) {
if (httpRequest.readyState == XMLHttpRequest.DONE) {
if (httpRequest.status == 200) {
alert(httpRequest.responseText);
} else {
alert('Un problĂšme est survenu avec la requĂȘte.');
}
}
}
</script>
<span
style="cursor: pointer; text-decoration: underline"
onclick="makeRequest('/js/test')">
Effectuer une requĂȘte
</span>
Dans cet exemple :
Lâutilisateur clique sur le lien « Effectuer une requĂȘte » dans le navigateur ;
Ceci appelle la fonction
makeRequest()
avec un paramĂštre: lâurl/js/test/
;la requĂȘte est faite et ensuite (
onreadystatechange
) lâexĂ©cution est passĂ©e ĂalertContents()
;alertContents()
vérifie si la réponse a été reçue et est correcte, et affiche ensuite la contenu de la ressource dans un messagealert()
.
Un deuxiĂšme exemple#
Pour finir, envoyons quelques données au serveur et réceptionons la réponse.
Notre JavaScript demandera cette fois çi une réponse dynamique, /api/hello/
qui prendra notre contenu envoyé et revera une chaßne « calculée »
"Bonjour, [user data] !"
que nous transmettrons Ă la fonction alert()
.
Nous allons dĂ©jĂ ajouter un boĂźte de texte dans notre HTML afin que lâutilisateur puisse saisir son nom :
<label>Vore nom :
<input type="text" id="ajaxTextbox" />
</label>
<span id="ajaxButton" style="cursor: pointer; text-decoration: underline">
Lancer une requĂȘte
</span>
Nous allons Ă©galement ajouter une ligne Ă notre gestionnaire dâĂ©vĂ©nement pour obtenir les donnĂ©es de lâutilisateur de la boite de texte et lâenvoyer Ă la fonction makePostRequest()
ainsi que lâURL de notre script cĂŽtĂ© serveur :
document.getElementById("ajaxButton").onclick = function() {
var userName = document.getElementById("ajaxTextbox").value;
makePostRequest('/api/hello',userName);
};
Nous devons créer makePostRequest()
afin quâil accepte les donnĂ©es de lâutilisateur et les transmette jusquâau serveur.
function makeRequest(url, userName) {
var httpRequest = false;
httpRequest = new XMLHttpRequest();
if (!httpRequest) {
alert('Abandon :( Impossible de créer une instance XMLHTTP');
return false;
}
httpRequest.onreadystatechange = function() { alertNameContents(httpRequest); };
httpRequest.open('POST', url);
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
httpRequest.send('userName=' + encodeURIComponent(userName));
}
La fonction alertNameContent()
peut ĂȘtre Ă©crite de la mĂȘme maniĂšre quâau dessus pour afficher notre chaĂźne calculĂ©e, si câest tout ce que le serveur renvoie.
Cependant, le serveur renvoie et la phrase calculée et la donnée originale. Donc si notre utilisateur saisi « Ben », la réponse du serveur ressemblera à :
{"userData":"Ben","computedString":"Bonjour, Ben !"}
Pour utiliser cette phrase dans alertNameContent()
, nous pouvons simplement afficher une alerte avec le contenu de responseText, nous devons la récupérer et afficher computedString, la propriété que nous souhaitons :
function alertNameContents() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
var response = JSON.parse(httpRequest.responseText);
alert(response.computedString);
} else {
alert('Un problĂšme est survenu avec la requĂȘte.');
}
}
}
Ă faire
CrĂ©er une nouvelle route qui contiendra le code javascript qui chargera les dinosaures depuis lâapi dĂ©veloppĂ© au sein de notre projet,
Et qui les ajoutera au sein de la page HTML, je vous conseille la lecture de cet article de MDN.