Compare commits

..

6 Commits

Author SHA1 Message Date
Ulysse JARNOUEN DE VILLARTAY a4580652f8 correction-ulysse (#2)
# Correction pour les TP1 TP2 et TP3

Je n'ai pas testé la connexion à la DB pour le moment car je ne peux pas me co sur https://dwarves.iut-fbleau.fr/phpmyadmin

Co-authored-by: JARNOUEN DE VILLARTAY Ulysse (SAFRAN AIRCRAFT ENGINES) <ulysse.jarnouen-de-villartay@safrangroup.com>
Reviewed-on: monnerat/web_2025#2
2026-04-15 15:34:46 +02:00
Denis Monnerat 045ec81ae2 ajout tp4 cookies et sessions 2026-04-12 17:58:57 +02:00
Denis Monnerat 3c100c0200 cookies et sessions 2026-04-10 09:46:07 +02:00
Denis Monnerat 5ef7c7b630 src.tar.gz 2026-04-08 10:12:01 +02:00
Denis Monnerat c165b74c99 tp3 2026-04-08 08:49:36 +02:00
Denis Monnerat 91524fb5e5 api mysqli 2026-04-03 09:43:50 +02:00
45 changed files with 1372 additions and 20 deletions
+20 -3
View File
@@ -30,9 +30,12 @@ Les notions suivantes seront abordées :
| Semaine | Cours | TD/TP | | Semaine | Cours | TD/TP |
| ------------------ | -------------------------------------------------------- | ------------------ | | ------------------ | -------------------------------------------------------- | ------------------ |
| 1 : 16/03 - 20/03| [Bases du langages](./cours/cm_bases_php.pdf) | | | 1 | [Bases du langages](./cours/cm_bases_php.pdf) | |
| 2 : 23/03 - 27/03 | | [tp1](./tp/tp1) | | 2 | | [tp1](./tp/tp1) |
| 3 : 30/03 - 03/04 | [Intéractions avec le client](./cours/cm_interaction_client_serveur.pdf) | [tp2](./tp/tp2) | | 3 | [Intéractions avec le client](./cours/cm_interaction_client_serveur.pdf) | [tp2](./tp/tp2) |
| 4 | [PHP/MySQL](./cours/cm_extension_mysqli.pdf) | [tp3](./tp/tp3) |
| 5 | [Cookies et sessions](./cours/cm_cookies_sessions.pdf) | [tp3](./tp/tp3) , [tp4](./tp/tp4) |
## Les TPS ## Les TPS
@@ -49,4 +52,18 @@ aborde la récupération des données de formulaires avec PHP.
À chaque exercice correspond un sous répertoire avec À chaque exercice correspond un sous répertoire avec
des fichiers à compléter. des fichiers à compléter.
#### TP3 : PHP/Mysql
Le [tp3](./tp/tp3)
aborde l'interfaçage de php avec mysql, au moyen de l'extention
[mysqli](http://php.net/manual/fr/book.mysqli.php) de php.
À chaque exercice correspond un sous répertoire avec
des fichiers à compléter.
#### TP4 : Cookies et sessions
Le [tp4](./tp/tp4)
aborde la notion de cookies et de sessions,et
les fonctions php dédiées.
À chaque exercice correspond un sous répertoire avec
des fichiers à compléter.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1,5 +1,5 @@
<?php <?php
include './include/data.inc.php'; include_once './include/data.inc.php';
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="fr"> <html lang="fr">
+1 -1
View File
@@ -1,5 +1,5 @@
<?php <?php
include './include/favoris.inc.php'; include_once './include/favoris.inc.php';
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="fr"> <html lang="fr">
+1 -1
View File
@@ -1,5 +1,5 @@
<?php <?php
include './include/fonction.php'; include_once './include/fonction.php';
$alphabet = "@#!*^&azertyuiopqsdfghjkklmwxcvbnAZERTYUIOPLMKJHGFDSQWXCVBN1234567890"; $alphabet = "@#!*^&azertyuiopqsdfghjkklmwxcvbnAZERTYUIOPLMKJHGFDSQWXCVBN1234567890";
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
+9 -12
View File
@@ -1,21 +1,18 @@
<?php <?php
$table = filter_input(INPUT_GET, 'table', FILTER_VALIDATE_INT); $table = filter_input(INPUT_GET, 'table', FILTER_VALIDATE_INT);
$tableSaisie = filter_input(INPUT_GET, 'table', FILTER_UNSAFE_RAW);
$tableSaisie = is_string($tableSaisie) ? trim($tableSaisie) : '';
$lignes = []; $lignes = [];
$messageErreur = ''; $messageErreur = '';
if ($tableSaisie !== '') { if ($table === false || $table === null) {
if ($table === false || $table === null) { $messageErreur = 'Veuillez saisir un entier valide.';
$messageErreur = 'Veuillez saisir un entier valide.'; } else {
} else { for ($multiplicateur = 1; $multiplicateur <= 10; $multiplicateur++) {
for ($multiplicateur = 1; $multiplicateur <= 10; $multiplicateur++) { $lignes[] = [
$lignes[] = [ 'multiplicateur' => $multiplicateur,
'multiplicateur' => $multiplicateur, 'resultat' => $table * $multiplicateur,
'resultat' => $table * $multiplicateur, ];
];
}
} }
} }
+1 -1
View File
@@ -20,7 +20,7 @@ include_once 'include/controller.php';
type="number" type="number"
name="table" name="table"
placeholder="table" placeholder="table"
value="<?php echo htmlspecialchars($tableSaisie, ENT_QUOTES, 'UTF-8'); ?>" value="<?php echo htmlspecialchars($table, ENT_QUOTES, 'UTF-8'); ?>"
> >
<button type="submit">ENVOYER</button> <button type="submit">ENVOYER</button>
</form> </form>
+140
View File
@@ -0,0 +1,140 @@
# TP 3 : Passage de paramètres à un script, PHP-MariaDB avec l'extension **mysqli**.
> Le style utilisé dans les sources est [picocss](https://picocss.com/).
### Ex1.
Le but est d'écrire un script php simulant le jeu de hasard pierre,
feuille ciseaux (encore appelé chifoumi).
<div align="center">
<img src="./img/chifoumi.png">
</div>
Le joueur joue en cliquant sur l'icone représentant le coup qu'il
a choisi. Celui-ci est un lien vers le même script, auquel est passé
en GET un paramètre représentant son choix. Par exemple :
```html
<a href="?choice=0"><img href="rock.png"></a>
<a href="?choice=1"><img href="paper.png"></a>
<a href="?choice=2"><img href="scissors.png"></a>
```
Le script récupère le coup du joueur, fait un tirage aléatoire, et
affiche les deux coups joués avec un message pour indiquer le
résultat de la partie.
Le code est organisé sommairement suivant le pattern `MVC`. Le script `index.php` fait office de contrôleur.
- il récupére le choix du joueur,
- il fait jouer l'ordinateur (tirage aléatoire),
- il calcule l'issue de la partie,
- il affiche (include) les différentes parties de la vue finale, avec les variables nécessaires.
Remarque : pour éviter un code trop verbeux au niveau des tests pour calculer le résultat d'une partie,
vous pouvez utiliser un tableau pour représenter les règles du jeu. Par exemple,
```php
<?php
// 0 rock, 1 paper, 2 scissors
$rules = [ 0 => [ 0 => "Draw", 1 => "Loss", 2 => "Win"], ... ];
```
### Ex2.
**Avant de commencer**
>- Vous diposez, sur le serveur mysql qui tourne sur la machine
> dwarves.iut-fbleau.fr, d'un compte identifié par votre login. Le mot de
> passe a été initailisé avec votre login. Pensez à le changer
> rapidement.
>- Vous disposez en lecture/écriture d'une seule base de données
> identifiée là encore par votre login.
>- Vous avez aussi accès à cette
> [url](https://dwarves.iut-fbleau.fr/phpmyadmin/) à une interface web
> (phpmyadmin) de gestion de votre base.
Pour travailler, importez dans votre base les tables et leurs contenus
```sql
Artiste (idArtiste,nom,prenom,anneeNaiss)
---------
Genre (code)
----
Pays (code,nom,langue)
----
Film (idFilm,titre,annee,#idMes,#genre,resume,#codePays,urlImage)
------
Role (#idFilm,#idActeur,nomRole)
------- -------- -------
```
qui se trouvent dans le fichier **cinema.sql**. Vous pouvez directement
l'importer à partir de phpmyadmin. Examinez les tables, leurs
structures et relations.
![](./img/db.gif) Par pitié !
**Testez directement vos requêtes sql avec phpmyadmin (ou autre) avant
des les "intégrer" à php !**
1. Complétez le script **films.php** qui affiche la liste de tous les films
de votre base sous forme d'une table html, classée par titre, avec
l'année, le genre et le réalisateur.
![](./img/film.png)
<details><summary>Conseils</summary>
<div>
- le serveur tourne sur le serveur http, donc pour vous connecter,
utiliser `localhost` comme nom.
- Pour récuperer les informations demandées, pensez à faire une
jointure entre Film et Artiste.
</div>
</details>
2. Modifiez le script précédent afin de paginer l'affichage des films.
![](./img/film1.png)
<details><summary>Conseils</summary>
<div>
- La clause `LIMIT` dans un SELECT permet de restreindre le nombre de
résultats de la requête.
- L'option `SQL_CALC_FOUND_ROWS` permet, en présence de la clause
LIMIT, de savoir combien de resultats auraient été selectionnée en
son absence.
Il faut utliser juste après la requête la fonction MySQL
`FOUND_ROWS()`.
</div>
</details>
3. Ajoutez dans le script précédent un formulaire avec une liste déroulante
qui permet de filtrer les films par réalisateur.
![](./img/film2.png)
<details><summary>Conseils</summary>
<div>
Il faut récupérer dans la table Artiste les réalisateurs, et peupler une
liste déroulante. La valeur envoyé par le formulaire sera bien sûr
l'identifiant du réalisateur.
Faites en sorte, comme sur la capture d'écran, de réafficher la liste
déroulante avec le nom du réalisateur dernièrement selectionné.
</div>
</details>
4. On veut dans cette question, à partir de la liste, afficher le détail
d'un film. Pour cela, chaque titre, dans le tableau, sera un lien qui
conduira à la fiche du film. L'identifiant du film sera passé dans
l'url du lien.
<a href="./fiche.php?film=1">Vertigo</a>
![](./img/film3.png)
5. Pour ceux qui s'ennuient, faites en sorte que l'on puisse trier
l'affichage sous forme de tableau par odre de titre, année, ou genre.
+13
View File
@@ -0,0 +1,13 @@
.center{
text-align:center;
}
.Win{
color:#2E8B57;
}
.Loss{
color:#FF6347;
}
.Draw{
color:#DAA520;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

+35
View File
@@ -0,0 +1,35 @@
<?php
$ROCK = 0;
$PAPER = 1;
$SCISSORS = 2;
$images = ["rock.png", "paper.png", "scissors.png"];
$rules = [
$ROCK => [$ROCK => "Draw", $PAPER => "Loss", $SCISSORS => "Win"],
$PAPER => [$ROCK => "Win", $PAPER => "Draw", $SCISSORS => "Loss"],
$SCISSORS => [$ROCK => "Loss", $PAPER => "Win", $SCISSORS => "Draw"],
];
$playerChoice = filter_input(
INPUT_GET,
'choice',
FILTER_VALIDATE_INT,
['options' => ['min_range' => 0, 'max_range' => 2]]
);
$isPlaying = ($playerChoice !== null && $playerChoice !== false);
if ($isPlaying) {
$computerChoice = mt_rand(0, 2);
$message = $rules[$playerChoice][$computerChoice];
$class = $message;
$imagePlayer = $images[$playerChoice];
$imageComputer = $images[$computerChoice];
}
include_once './views/header.php';
if ($isPlaying) {
include_once './views/game.php';
include_once './views/message.php';
}
include_once './views/footer.php';
+3
View File
@@ -0,0 +1,3 @@
</main>
</body>
</html>
+15
View File
@@ -0,0 +1,15 @@
<div class="grid">
<article>
<header>Player</header>
<section class="center">
<img src="./images/<?php echo $imagePlayer;?>">
</section>
</article>
<article>
<header>Computer</header>
<section class="center">
<img src="./images/<?php echo $imageComputer;?>">
</section>
</article>
</div>
+25
View File
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" >
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
/>
<link rel="stylesheet" href="./css/style.css">
<title>Chifoumi</title>
</head>
<body>
<main class="container">
<h3>Rock Paper Scissors</h3>
<section class="center">
<p>Choose : </p>
<a href="?choice=0"><img width="100px" src="./images/rock.png"></a>
<a href="?choice=1"><img width="100px" src="./images/paper.png"></a>
<a href="?choice=2"><img width="100px" src="./images/scissors.png"></a>
</section>
+3
View File
@@ -0,0 +1,3 @@
<h2 class="center">
<span class="<?php echo $class;?>"><?php echo $message;?></span>
</h2>
File diff suppressed because one or more lines are too long
+18
View File
@@ -0,0 +1,18 @@
table{
width:100%;
}
img{
width:500px;
}
td + td + td + td{
width : 20%;
}
td:first-child + td{
width:10%;
}
td:first-child{
width:30%;
}
td:first-child + td + td {
width:30%;
}
+37
View File
@@ -0,0 +1,37 @@
<?php
include_once './modeles/modeleFilms.php';
$currentPage = filter_input(
INPUT_GET,
'page',
FILTER_VALIDATE_INT,
['options' => ['min_range' => 1]]
);
if ($currentPage === null || $currentPage === false) {
$currentPage = 1;
}
$perPage = 10;
$data = getFilms($currentPage, $perPage);
$films = $data['films'];
$errorMessage = $data['error'];
$totalFilms = $data['total'];
$totalPages = max(1, (int) ceil($totalFilms / $perPage));
if ($currentPage > $totalPages && $totalFilms > 0) {
$currentPage = $totalPages;
$data = getFilms($currentPage, $perPage);
$films = $data['films'];
$errorMessage = $data['error'];
$totalFilms = $data['total'];
}
//
// on "charge" la vue
//
include_once './vues/header.php';
include_once './vues/vueFilms.php';
include_once './vues/footer.php';
@@ -0,0 +1,69 @@
<?php
function getConnection()
{
static $conn = null;
if ($conn === null) {
$host = getenv('DB_HOST') ?: 'https://dwarves.iut-fbleau.fr';
$login = getenv('DB_USER') ?: getenv('USER') ?: getenv('USERNAME') ?: 'root';
$password = getenv('DB_PASSWORD') ?: $login;
$database = getenv('DB_NAME') ?: $login;
$conn = mysqli_connect($host, $login, $password, $database);
if ($conn !== false) {
mysqli_set_charset($conn, 'utf8mb4');
}
}
return $conn;
}
function getFilms($page = 1, $perPage = 10)
{
$conn = getConnection();
if ($conn === false) {
return [
'films' => [],
'total' => 0,
'error' => 'Connexion MySQL impossible.',
];
}
$page = max(1, (int) $page);
$perPage = max(1, (int) $perPage);
$offset = ($page - 1) * $perPage;
$sql = "SELECT SQL_CALC_FOUND_ROWS
F.idFilm,
F.titre,
F.annee,
G.code AS genre,
A.prenom,
A.nom
FROM Film AS F
INNER JOIN Artiste AS A ON F.idMes = A.idArtiste
INNER JOIN Genre AS G ON F.genre = G.code
ORDER BY F.titre ASC
LIMIT {$offset}, {$perPage}";
$result = mysqli_query($conn, $sql);
if ($result === false) {
return [
'films' => [],
'total' => 0,
'error' => 'Exécution de la requête impossible.',
];
}
$films = mysqli_fetch_all($result, MYSQLI_ASSOC);
$totalResult = mysqli_query($conn, 'SELECT FOUND_ROWS() AS total');
$totalRow = $totalResult ? mysqli_fetch_assoc($totalResult) : ['total' => 0];
$total = isset($totalRow['total']) ? (int) $totalRow['total'] : 0;
return [
'films' => $films,
'total' => $total,
'error' => null,
];
}
+3
View File
@@ -0,0 +1,3 @@
</main>
</body>
</html>
+14
View File
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<title>Films</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
/>
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<main class="container">
+64
View File
@@ -0,0 +1,64 @@
<!--
Variables de la vue
$films : les films de la page
-->
<h2>Films</h2>
<?php if (!empty($errorMessage)) { ?>
<article><?php echo htmlspecialchars($errorMessage, ENT_QUOTES, 'UTF-8'); ?></article>
<?php } ?>
<table>
<thead>
<tr>
<th>Titre</th>
<th>Année</th>
<th>Genre</th>
<th>Réalisateur</th>
</tr>
</thead>
<tbody>
<?php
foreach ($films as $film) {
$titre = htmlspecialchars($film['titre'], ENT_QUOTES, 'UTF-8');
$annee = htmlspecialchars((string) $film['annee'], ENT_QUOTES, 'UTF-8');
$genre = htmlspecialchars($film['genre'], ENT_QUOTES, 'UTF-8');
$realisateur = htmlspecialchars($film['prenom'] . ' ' . $film['nom'], ENT_QUOTES, 'UTF-8');
echo "
<tr>
<td><a href='#'>{$titre}</a></td>
<td>{$annee}</td>
<td>{$genre}</td>
<td>{$realisateur}</td>
</tr>";
}
?>
</tbody>
</table>
<?php if ($totalPages > 1) { ?>
<nav>
<ul>
<li>
<?php if ($currentPage > 1) { ?>
<a href="?page=<?php echo $currentPage - 1; ?>">Précédent</a>
<?php } else { ?>
<span>Précédent</span>
<?php } ?>
</li>
</ul>
<ul>
<li>Page <?php echo $currentPage; ?> / <?php echo $totalPages; ?></li>
</ul>
<ul>
<li>
<?php if ($currentPage < $totalPages) { ?>
<a href="?page=<?php echo $currentPage + 1; ?>">Suivant</a>
<?php } else { ?>
<span>Suivant</span>
<?php } ?>
</li>
</ul>
</nav>
<?php } ?>
Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 KiB

Binary file not shown.
+76
View File
@@ -0,0 +1,76 @@
# TP4 : Cookies et sessions en PHP.
### Ex1.
Complétez le script `index.php` de l'exercice 1 de manière à
mémoriser grâce à un cookie votre os préféré (parmi Linux, Windows et
MacOS). Le cookie est valable pendant une minute, et l'os par
défaut est Linux.
![](./img/cookie.png)
### Ex2.
Le but est de créer un min-jeu de morpion.
![](./img/ttt.png)
Les variables de session :
- `grid` : le plateau du jeu. tableau de 9 cases, prennant les valeurs 0 (libre), 1 (joueur 1), 2 (joueur 2).
- `playerTurn` : le joueur qui joue.
Le script prend en paramètre la variable `pos` : la position du coup joué par le joueur.
### Ex3.
On désire rendre les pages du [tp3](./../tp3) (cinema) accessibles
uniquement à des utilisateur **inscrits au préalable**.
1. Rajouter à la base une table `user` qui comprend un **login**,
**email** et un **password**. (login est la clé)
2. Ecrire un formulaire d'inscription au site qui comprend les
champs correspondants. Vous enregistrerez dans la base la mot de
passe hashé avec la fonction
[password\_hash](http://php.net/manual/fr/function.password-hash.php)
de php.
3. Faire en sorte que toutes les pages de l'application soient
accessibles **uniquement** si l'utilisateur s'est authentifié.
(utiliser une session)
Ecrire les scripts ou pages suivants
<dl>
<dt><code>inscription.php</code></dt>
<dd>formulaire d'inscription, et qui traite les données du formulaire.
Si le formulaire n'est pas correctement rempli, Il est réaffiché.
(les champs correctes sont conservés !)</dd>
<dt><code>authentification.html</code></dt>
<dd>formulaire d'authentification.</dd>
<dt><code>verification.php</code></dt>
<dd>traite le formulaire précédent et vérifie si l'utilisateur est
enregistré. En cas de succés, renvoie vers la page d'accueil du
site. Pour éviter des attaques force brute, ajoutez une
temporisation qui ralentira de telles attaques.</dd>
<dt><code>securite.php</code></dt>
<dd>morceau de code que vous inclurez systématiquement dans vos pages
que vous voulez rendre accessible uniquement aux utilisateurs dûment
authentifiés. Ce script vérifiera l'existence d'une variable de
session créée lors de la connexion.</dd>
</dl>
Pour permettre l'authentification d'un utilisateur, il faut que
login et le mot de passe conviennent. On compare le hash de
l'utilisateur stocké dans la base avec le hashage calculé du
password soumis lors de l'authentification :
```php
<?php
// Voir l'exemple fourni sur la page de la fonction password_hash()
// pour savoir d'où cela provient.
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';
if (password_verify('rasmuslerdorf', $hash)) {
echo 'Le mot de passe est valide !';
} else {
echo 'Le mot de passe est invalide.';
}
?>
```
+6
View File
@@ -0,0 +1,6 @@
<?php
$osSet = ['linux','apple','windows'];
$os = "linux";
include './views/main.php';
?>
+44
View File
@@ -0,0 +1,44 @@
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<main class="container">
<form method="POST">
<fieldset class="grid">
<legend>Changez votre os</legend>
<label>
<input type="radio" name="os" value="linux">
<i class="fa fa-linux fa-2x" aria-hidden="true"></i>
</label>
<label>
<input type="radio" name="os" value="windows">
<i class="fa fa-windows fa-2x" aria-hidden="true"></i>
</label>
<label>
<input type="radio" name="os" value="apple">
<i class="fa fa-apple fa-2x" aria-hidden="true"></i>
</label>
</fieldset>
<button type="submit">Envoyer</button>
</form>
<article>
<header>Votre os</header>
<?php echo "<i class='fa fa-$os fa-5x'></i>";?>
<footer>
Rafraîchir la page <a href=""><i class="fa fa-refresh" aria-hidden="true"></i></a>
</footer>
</article>
</main>
</body>
</html>
+32
View File
@@ -0,0 +1,32 @@
table.morpion{
border-collapse: collapse;
table-layout:fixed;
margin-left:auto;
margin-right:auto;
display:inline-block;
width:auto;
}
table.morpion td {
border : 1px solid #aaaaaa;
width:10rem;
height:10rem;
padding : 0px;
margin:0px;
overflow: hidden;
white-space: nowrap;
text-align:center;
vertical-align:middle;
}
table.morpion i {
font-size:8rem;
}
table.morpion a {
display : inline-block;
width : 8rem;
height: 8rem;
}
.center{
text-align:center;
}
+54
View File
@@ -0,0 +1,54 @@
<?php
function isWinner($grid, $player)
{
$winStates = array
(
array(0, 1, 2), array(3, 4, 5), array(6, 7, 8), // Horizontal
array(0, 3, 6), array(1, 4, 7), array(2, 5, 8), // Vertical
array(0, 4, 8), array(2, 4, 6) // Diagonal
);
foreach ($winStates as $winState)
{
if ($grid[$winState[0]] == $player &&
$grid[$winState[1]] == $player &&
$grid[$winState[2]] == $player)
{
return true;
}
}
return false;
}
function noWinner($grid)
{
for($i = 0; $i < 9; $i++)
if ($grid[$i] == 0)
return false;
return true;
}
function displayGrid($grid)
{
echo '<table class="morpion">';
for ($i = 0; $i < 3; $i ++){
echo "<tr>";
for ($j = 0; $j < 3; $j ++){
echo "<td>";
$pos = 3*$i + $j;
if ($grid[$pos] == 0)
echo "<a href='?pos=$pos'></a>";
if ($grid[$pos] == 1)
echo '<i class="fa fa-times" aria-hidden="true"></i>';
if ($grid[$pos] == 2)
echo '<i class="fa fa-circle-o" aria-hidden="true"></i>';
echo "</td>";
}
echo "</tr>";
}
echo "</table>";
}
+11
View File
@@ -0,0 +1,11 @@
<?php
include 'helpers.php';
// view variables
$message = "";
$grid = [0,1,0,1,0,2,2,0,0];
$playerTurn = 1; // 1 or 2
include './views/tictactoe.php';
+24
View File
@@ -0,0 +1,24 @@
<html>
<head>
<meta charset="UTF-8">
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
/>
<link rel="stylesheet" href="./css/style.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<main class="container center">
<h4>Tic Tac Toe : <?php echo "player $playerTurn turn";?></h4>
<?php
displayGrid($grid);
if ($message != "")
echo "<h5>$message <a href='.'>new game</a></h5>";
?>
</main>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.