Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Votre site est envahi par des inscriptions de bot (des robots qui s'inscrivent plusieurs fois à des sites dans le but de publier des messages publicitaires, sur un livre d'or, un forum, etc.).
Il existe de nombreuses solutions pour empêcher les bots d'agir, comme proposer un champ avec une opération mathématique à résoudre (simple à réaliser), mais dans ce tutoriel, nous allons créer une image aléatoire composée de chiffres, avec un lien vers un fichier son qui contiendra la formule vocale du code afin que les personnes mal-voyantes puissent s'inscrire sur votre site.
Nous allons tout d'abord simplement (

) générer l'image aléatoire. Dans ce TP, elle sera composée uniquement de chiffres, mais rien ne vous empêche d'inclure des lettres.
Nous procéderons donc ainsi :
- créer une image aléatoire, et vérifier que celle-ci correspond au code
- nous verrons comment générer le fichier wave (fichier son) qui dictera aux visiteurs les chiffres à inscrire dans le champ du formulaire.
Allez : au boulot.
Notre script sera composé de 3 fichiers.
- Le fichier formulaire.php contiendra l'image et le formulaire d'inscription, par exemple (ici, il vérifiera si le code est le bon, mais rien ne vous empêche de faire une autre page).
- Le fichier image.php qui sera l'image png générée par php.
- Le fichier sound.php qui générera un fichier wave.
On va commencer par le fichier
image.php.
L'image
Ce que l'on veut
- Un nombre à 5 chiffres : ce nombre sera utilisé comme une chaîne de caractères.
- Une image de ces chiffres.
- Des éléments "perturbateurs", tels qu'une barre.
Pour obtenir une image de ce type :
Code aléatoire
La chaîne aléatoire
Une chaîne simple composée de 5 chiffres.
Code : PHP 1
2
3
4
5
6
7
8
9
10
11 | <?php
function chaineAleatoire($nombre = 5)
{
$chaine = '';
for($i = 0; $i < $nombre; $i++)
{
$chaine .= mt_rand(0,9);
}
return $chaine;
}
?>
|
image.php
Il existe d'autres méthodes bien entendu.
Je vous conseille quand même de lire tout le cours PHP de M@teo21, en particulier
le cours sur la librairie GD si ce n'est déjà fait afin de comprendre le code suivant.
L'image
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | <?php
function image($chaine)
{
$largeur = (strlen($chaine) * 10); // Environ la largeur d'un caractere
$hauteur = 20; // La bonne hauteur
$image = imagecreate($largeur,$hauteur);
$blanc = imagecolorallocate($image, 255, 255, 255); // On colore tout en blanc
$noir = imagecolorallocate($image, 0, 0, 0);
$milieuHauteur = ($hauteur / 2) - 8; // Pour centrer le texte en hauteur
imagestring($image, 6, (strlen($chaine) / 2 ), $milieuHauteur, $chaine, $noir); // On ecrit au milieu (augmenter le nombre de caracteres pour voir ;) )
ImageRectangle ($image, 1, 1, $largeur - 1, $hauteur - 1, $noir); // Le rectangle autour pour l'esthetique
$hauteur1 = mt_rand(2,$hauteur); // Barre aleatoire
$hauteur2 = mt_rand(2,$hauteur); // Fin de la barre aleatoire
ImageLine ($image, 2,$hauteur1, $largeur - 2, $hauteur2, $noir); // Barre aleatoire
ImageLine ($image, 2, $milieuHauteur + 8, $largeur - 2, $milieuHauteur + 8, $noir); // Barre standard
imagepng($image); // On dessine
}
?>
|
image.php (suite)
Et de deux
Enregistrez le fichier
image.php avec ces deux fonctions.
Code html basique
Ce code est le code d'un formulaire simple, nous incorporerons l'image de validation après.
Code : HTML 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" ><head>
<title>Image Anti-Bot</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" media="screen" type="text/css" title="" href="" />
</head>
<body>
<div>
<form action="" method="post">
<label>Pseudo : <input type="text" name="pseudo" /></label><br />
<img src="image.php?nombre=5" alt="" /><br /> <!-- on appelle l'image php -->
<label>Cle : (respectez la casse) <input type="text" name="cle" /></label><br />
<input type="submit" value="envoyer" />
</form>
</div>
</body>
</html>
|
formulaire.php
Vérifions que le code de l'image correspond à ce qui est entré
Nous aurons besoin des
sessions car le code sera stocké dans une variable de session : là encore, référez-vous au cours de php de ce site.
Code : PHP
image.php (tout en haut)
formulaire.php (tout en haut)
=> En haut de
formulaire.php et de
image.php.
De plus,
image.php est normalement une image ; nous avons donc besoin de le spécifier au navigateur par le biais d'un
header :
Code : PHP1 | header ("Content-type: image/png");
|
image.php (tout en haut)
Code : PHP1
2
3 | $chaine = chaineAleatoire($_GET['nombre']); // Comme on l'appelle avec ?nombre=5 (caracteres)
$_SESSION['chaine'] = $chaine; // Tout l'interet des sessions ;)
image($chaine); // On genere l'image avec la chaine obtenue.
|
image.php (tout en bas)
Maintenant, il va falloir modifier le fichier qui "réceptionne" le formulaire : dans notre cas, ce sera
formulaire.php.
1. On vérifie si on a cliqué sur le bouton
.
2. On vérifie si le code est le même.
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 | <?php
session_start();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" >
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" media="screen" type="text/css" title="" href="" />
</head>
<body>
<?php
if(isset($_POST['cle']))
{
if($_POST['cle'] == $_SESSION['chaine'])
{
echo 'Votre nom est '. $_POST['pseudo'];
}
else
{
echo 'Clé non identifiée';
echo '<br /><a href="formulaire.php">Ressayer</a>';
}
}
else
{
?>
<div>
<form action="" method="post">
<label>Pseudo : <input type="text" name="pseudo" /></label><br />
<img src="aleatoire.php?nombre=5" alt="" /><br />
<label><couleur nom="rouge">Cle : (respectez la casse)</couleur> <input type="text" name="cle" /></label><br />
<input type="submit" value="envoyer" />
</form>
</div>
<?php
}
?>
</body>
</html>
|
formulaire.php (final)
A ce stade, vous avez déjà un bon formulaire anti-bot, fonctionnel, mais il manque quelque chose : en effet, le web se veut accessible, et vous devez y contribuer.
Imaginons donc la situation suivante : votre espace-membre donne accès à un contenu riche et intéressant.
Une personne ayant des problèmes de vue se rend sur votre site à l'aide d'un navigateur auditif ou braille, etc. Vous commencez à comprendre ?
Cette personne ne peut s'inscrire. Comme sur les sites professionnels, je vais vous apprendre à créer un fichier wave qui "lira" l'image à vos visiteurs !
Je ne suis pas sûr que vous comprendrez toutes les notions utilisées ici ; néanmoins, vous pouvez vous renseigner sur le format wave, il existe quelques sites qui vous en apprendront un peu plus sur la façon dont est écrit un fichier wave, voici quelques-unes de ces adresses :
Ensuite, regardez du côté de
pack(),
unpack().
Je vais tout de même essayer d'être le plus clair possible.
Vous devez savoir qu'un fichier contient généralement une en-tête ; ici, c'est sur celui-ci que nous allons le plus travailler. L'en-tête d'un fichier est écrite en binaire, heureusement les fonctions
pack() et
unpack() savent faire la transcription entre nombres entiers, chaînes de caractères, etc. et langage binaire. La première transcrit une variable d'une forme que l'on peut traiter avec php (
int,
string,
bool, etc.) à une forme
binaire (suite de 0 et de 1). La fonction
unpack() fait l'inverse.
Chaque fichier a sa propre en-tête et son propre type d'encodage des données. Ici nous nous occuperons d'un fichier wave, mais le principe est le même pour les
zip, les images, etc.
Voici l'arborescence du script fini :
Arborescence
Nous avons déjà écrit les deux fichiers :
formulaire.php et
image.php.
Le fichier
sound.php est une
classe (
lien vers un tuto d'un zéro)"
wave" composée des méthodes suivantes :
- __construct : le constructeur, qui entraîne la génération du fichier wave,
- analyse : analyse l'en-tête d'un fichier wave, et retourne soit toutes les caractéristiques, soit une seule (taille par exemple),
- get_datas : renvoie les données brutes d'un fichier wave sans l'en-tête,
- package : mélange les données brutes de plusieurs wave et ajoute l'en-tête appropriée. Renvoie le fichier final.
Liens vers les fichiers wav :
Télécharger.
Analyse d'un fichier wave
Il faut savoir qu'un fichier wave est composé d'une en-tête (ici, de 44 octets en l'occurrence) et du contenu à proprement parler du fichier.
Cette en-tête permet d'avoir des informations concernant la vitesse d'échantillonnage, la durée, le nombre de bits, etc.
Je vous épargne tout cela ; voilà seulement une fonction que j'ai écrite qui gère l'en-tête :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 | <?php
public function analyse($wav,$arg = FALSE)
{
if(file_exists('../'.$wav))
{
$entete_unpack = 'a4file_type/Lfile_size/a4file_id/A4nom_zone1/Ltaille_zone1/SFormatTag/SChannels/LSamplesPerSec/LAvgBytesPerSec/SBlockAlign/SBitsPerSample/A4nom_data/Ltaille_data';
$fp = fopen('../'.$wav,'r');
$file = fread($fp, 44 );
$entete = unpack($entete_unpack,$file);
fclose($fp);
if( ($entete['file_type'] !== chr(0x52).chr(0x49).chr(0x46).chr(0x46) ) OR ( $entete['file_id'] !== chr(0x57).chr(0x41).chr(0x56).chr(0x45) ) )
{
/* La fonction trigger_error genere une erreur comme celles qui apparaissent lorsque vous oubliez un argument d'une fonction, un point virgule, etc. (consultez la doc pour plus d'informations) */
trigger_error('Le fichier '.$wav.' n ''est pas un fichier wav',E_USER_ERROR); // je double l'apostrophe pour mieux colorer le code sur le site, mais dans vos codes, echappez juste une seule apostrophe, comme ceci : \'
}
if(!$arg)
return $entete;
else
return $entete[$arg];
}
else
{
trigger_error('fonction analyse, le fichier '.$wav.' est necessaire mais manquant', E_USER_ERROR);
return FALSE;
}
}
?>
|
sound.php
Si vous ne comprenez pas tout ce qui est écrit, ce n'est pas très grave : sachez seulement que la fonction prend le nom d'un fichier
wav, l'ouvre, lit l'en-tête, et renvoie au choix :
- tout l'en-tête
- une seule caractéristique.
Le constructeur de la classe
Le paramètre à lui transmettre est le nombre à dicter, le constructeur lancera la procédure de création du wave en appelant les bonnes fonctions :
Citation : Paramètre du constructeur(int) nombre
Ce qui en php donne cela :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | <?php
public function __construct($nombre)
{
if(!empty($nombre))
{
$this->nombre = $nombre.'r'.$nombre; // Nombre, "je repete", nombre
$strlen = strlen($this->nombre);
$binary = ''; // Contiendra les donnees, juste les donnees.
/* Parcours chaque fichier wav qui contient un nombre utilisé dans la chaine */
for($i = 0; $i < $strlen; $i++)
{
$binary .= $this->get_datas('../'.$this->nombre{$i}.'.wav');
}
$this->package($binary);
}
}
?>
|
sound.php (constructeur)
Ça ne devrait pas vous poser de problème, normalement

.
Récupérer les données du fichier wav
Notre fonction
get_datas() doit récupérer les données brutes, c'est-à-dire le son proprement dit d'un fichier wav, c'est juste l'utilisation de
fopen,
fread,
fclose. Seulement la fonction
analyse() va nous donner la taille en octets des données brutes.
Voici la fonction
get_datas, j'explique en commentaires.
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | <?php
private function get_datas($wav)
{
if(file_exists('../'.$wav))
{
$fp = fopen('../'.$wav,'r');
fseek($fp, 44 ); // On place le curseur à 44 octets, juste apres les donnees
$datas = fread($fp, $this->analyse($wav, 'taille_data')); // On lit juste la taille des donnees d'apres analyse().
fclose($fp);
return $datas; // On renvoie au constructeur qui ajoutera les donnees a la fin de la chaine des donnees.
}
else
{
trigger_error('fonction analyse, le fichier '.$wav.' est necessaire mais manquant', E_USER_ERROR);
return FALSE;
}
}
?>
|
Ce code n'est lui non plus pas trop compliqué, seules les fonctions
analyse() et
package() (que nous allons voir) sont un peu plus difficiles car elles utilisent des fonctions de traitement binaire : il faut donc connaître la structure d'un fichier wav.
Package, on crée le fichier wav final
Notre fonction
package doit assembler toutes les données des fichiers requis, ajouter une en-tête et envoyer le tout au navigateur.
Allez, je vous laisse

.
Vous n'y arrivez pas ? C'est un peu normal, c'est la fonction la plus compliquée de notre classe.
La voici :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 | <?php
private function package($datas)
{
$entete_pack = 'a4La4A4LSSLLSSA4L'; // En-tete d'un fichier wav transcrit pour la fonction pack / unpack, cela veut dire que l'on transcrit en binaire 4 chaines, un entier long non signe, 4 chaines, etc.
$entete = $this->analyse('../'.$this->nombre{0}.'.wav'); // On prend l'en-tete du premier fichier utilise comme base pour les autres, si les autres n'ont pas les memes caracteristiques, on arrete tout (voir plus bas)
for($i = 1;$i<strlen($this->nombre); $i ++)
{
$entete2 = $this->analyse('../'.$this->nombre{$i}.'.wav');
/* Verification des en-tetes. */
if($entete !== $entete2)
{
if($entete['Channels'] !== $entete2['Channels'])
{
trigger_error('fonction package, un ou plusieurs fichiers wad n''ont pas le meme nombre de canaux',E_USER_ERROR); // Note, j'ai encore double l'apostrophe
}
if($entete['BitsPerSample'] !== $entete2['BitsPerSample'])
{
trigger_error('fonction package, un ou plusieurs fichiers wad, n''ont pas le meme nombre d''echantillons par seconde', E_USER_ERROR);
}
if($entete['SamplesPerSec'] !== $entete2['SamplesPerSec'])
{
trigger_error('fonction package, un ou plusieurs fichiers wad, n''ont pas la meme frequence d''echantillonage', E_USER_WARNING);
}
}
}
/* On calcule la taille des donnees que l'on a crees selon la formule de soundeditor (voir liens tout en haut)*/
$entete['taille_data'] = strlen($datas);
$entete['taille_data'] /= $entete['BlockAlign'];
$entete['taille_data'] *= $entete['BlockAlign'];
$entete['file_size'] = 44 + strlen($datas); // Taille totale du fichier
/* on "pack" l en-tete et on y ajoute les donnees */
/* Transcription en binaire */
$binary = pack($entete_pack, $entete['file_type'],$entete['file_size'],$entete['file_id'],$entete['nom_zone1'],
$entete['taille_zone1'],$entete['FormatTag'],$entete['Channels'],$entete['SamplesPerSec'],$entete['AvgBytesPerSec'],
$entete['BlockAlign'],$entete['BitsPerSample'],$entete['nom_data'],$entete['taille_data']);
$binary .= $datas; // Ajoute les donnees à la fin et c'est bon !!
/* On transmet ou enregistre */
header('Content-type: audio/x-wav'); // Indique que le navigateur recoit un fichier wav
header('Content-Disposition: attachment; filename="code.wav"'); // Indique que l'on transmet le fichier directement
echo $binary; // Sortie santard.
}
?>
|
Code final de la classe sound.php
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 | <?php
class wave
{
public $nombre;
public function __construct($nombre = 0)
{
if(!empty($nombre))
{
$this->nombre = $nombre.'r'.$nombre;
$strlen = strlen($this->nombre);
$binary = ''; // Contiendra les donnees, juste les donnees.
for($i = 0; $i < $strlen; $i++)
{
$binary .= $this->get_datas('../'.$this->nombre{$i}.'.wav');
}
$this->package($binary);
}
}
public function analyse($wav,$arg = FALSE)
{
if(file_exists('../'.$wav))
{
$entete_unpack = 'a4file_type/Lfile_size/a4file_id/A4nom_zone1/Ltaille_zone1/SFormatTag/SChannels/LSamplesPerSec/LAvgBytesPerSec/SBlockAlign/SBitsPerSample/A4nom_data/Ltaille_data';
$fp = fopen('../'.$wav,'r');
$file = fread($fp, 44 );
$entete = unpack($entete_unpack,$file);
fclose($fp);
if( ($entete['file_type'] !== chr(0x52).chr(0x49).chr(0x46).chr(0x46) ) OR ( $entete['file_id'] !== chr(0x57).chr(0x41).chr(0x56).chr(0x45) ) )
{
trigger_error('Le fichier '.$wav.' n\'est pas un fichier wav',E_USER_ERROR);
}
if(!$arg)
return $entete;
else
return $entete[$arg];
}
else
{
trigger_error('fonction analyse, le fichier '.$wav.' est necessaire mais manquant', E_USER_ERROR);
return FALSE;
}
}
private function get_datas($wav)
{
if(file_exists('../'.$wav))
{
$fp = fopen('../'.$wav,'r');
fseek($fp, 44 );
$datas = fread($fp, $this->analyse($wav, 'taille_data'));
fclose($fp);
return $datas;
}
else
{
trigger_error('fonction analyse, le fichier '.$wav.' est necessaire mais manquant', E_USER_ERROR);
return FALSE;
}
}
private function package($datas)
{
$entete_pack = 'a4La4A4LSSLLSSA4L';
$entete = $this->analyse('../'.$this->nombre{0}.'.wav');
for($i = 1;$i<strlen($this->nombre); $i ++)
{
$entete2 = $this->analyse('../'.$this->nombre{$i}.'.wav');
if($entete !== $entete2)
{
if($entete['Channels'] !== $entete2['Channels'])
{
trigger_error('fonction package, un ou plusieurs fichiers wad n\'ont pas le meme nombre de canaux',E_USER_ERROR);
}
if($entete['BitsPerSample'] !== $entete2['BitsPerSample'])
{
trigger_error('fonction package, un ou plusieurs fichiers wad, n\'ont pas le meme nombre d\'echantillons par seconde', E_USER_ERROR);
}
if($entete['SamplesPerSec'] !== $entete2['SamplesPerSec'])
{
trigger_error('fonction package, un ou plusieurs fichiers wad, n\'ont pas la meme frequence d\'echantillonage', E_USER_WARNING);
}
}
}
/* On calcule la taille des donnees que l'on a creees selon la formule de soundeditor */
$entete['taille_data'] = strlen($datas);
$entete['taille_data'] /= $entete['BlockAlign'];
$entete['taille_data'] *= $entete['BlockAlign'];
$entete['file_size'] = 44 + strlen($datas);
/* on "pack l en-tete et on y ajoute les donnees */
$binary = pack($entete_pack, $entete['file_type'],$entete['file_size'],$entete['file_id'],$entete['nom_zone1'],
$entete['taille_zone1'],$entete['FormatTag'],$entete['Channels'],$entete['SamplesPerSec'],$entete['AvgBytesPerSec'],
$entete['BlockAlign'],$entete['BitsPerSample'],$entete['nom_data'],$entete['taille_data']);
$binary .= $datas;
/* On transmet ou enregistre */
header('Content-type: audio/x-wav');
header('Content-Disposition: attachment; filename="code.wav"');
echo $binary;
}
}
?>
|
Ouf, c'est fini : oui, votre classe fonctionne très bien, cependant il faut l'inclure avec le formulaire.
Nous verrons ici comment faire marcher votre formulaire en entier.
Modifications
Le formulaire
Voici les modifications à apporter au fichier formulaire pour qu'il fonctionne avec les autres fichiers.
Image pour lancer le fichier wave :

.
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 | <?php
session_start();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" ><head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" media="screen" type="text/css" title="" href="" />
</head>
<body>
<?php
if(isset($_POST['cle']))
{
if($_POST['cle'] == $_SESSION['chaine'])
{
echo 'Votre nom est '. $_POST['pseudo'];
session_destroy();
}
else
{
echo 'Cle non identifié';
echo '<br /><a href="formulaire.php">Ressayer</a>';
}
}
else
{
?>
<div>
<form action="" method="post">
<label>Pseudo : <input type="text" name="pseudo" /></label><br />
<img src="aleatoire.php?nombre=5&type=numerique" alt="" /><a href="wave/sound.php"><img src="hp.png" alt="Je ne peux pas voir le message" title="Je ne peux pas voir le message" /></a><br />
<label><couleur nom="rouge">Cle : ( respectez la case )</couleur> <input type="text" name="cle" /></label><br />
<input type="submit" value="envoyer" />
</form>
</div>
<?php
}
?>
</body>
</html>
|
formulaire.php
On a juste rajouté un lien vers
sound.php.
Le fichier sound.php
Il faut rajouter
Code : PHPen haut et
Code : PHP1 | $wav = new wave($_SESSION['chaine']);
|
en bas.
Ce qui donne donc :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128 | <?php
session_start();
class wave
{
public $nombre;
public function __construct($nombre = 0)
{
if(!empty($nombre))
{
$this->nombre = $nombre.'r'.$nombre;
$strlen = strlen($this->nombre);
$binary = ''; // Contiendra les donnees, juste les donnees.
for($i = 0; $i < $strlen; $i++)
{
$binary .= $this->get_datas('../'.$this->nombre{$i}.'.wav');
}
$this->package($binary);
}
}
public function analyse($wav,$arg = FALSE)
{
if(file_exists('../'.$wav))
{
$entete_unpack = 'a4file_type/Lfile_size/a4file_id/A4nom_zone1/Ltaille_zone1/SFormatTag/SChannels/LSamplesPerSec/LAvgBytesPerSec/SBlockAlign/SBitsPerSample/A4nom_data/Ltaille_data';
$fp = fopen('../'.$wav,'r');
$file = fread($fp, 44 );
$entete = unpack($entete_unpack,$file);
fclose($fp);
if( ($entete['file_type'] !== chr(0x52).chr(0x49).chr(0x46).chr(0x46) ) OR ( $entete['file_id'] !== chr(0x57).chr(0x41).chr(0x56).chr(0x45) ) )
{
trigger_error('Le fichier '.$wav.' n\'est pas un fichier wav',E_USER_ERROR);
}
if(!$arg)
return $entete;
else
return $entete[$arg];
}
else
{
trigger_error('fonction analyse, le fichier '.$wav.' est necessaire mais manquant', E_USER_ERROR);
return FALSE;
}
}
private function get_datas($wav)
{
if(file_exists('../'.$wav))
{
$fp = fopen('../'.$wav,'r');
fseek($fp, 44 );
$datas = fread($fp, $this->analyse($wav, 'taille_data'));
fclose($fp);
return $datas;
}
else
{
trigger_error('fonction analyse, le fichier '.$wav.' est necessaire mais manquant', E_USER_ERROR);
return FALSE;
}
}
private function package($datas)
{
$entete_pack = 'a4La4A4LSSLLSSA4L';
$entete = $this->analyse('../'.$this->nombre{0}.'.wav');
for($i = 1;$i<strlen($this->nombre); $i ++)
{
$entete2 = $this->analyse('../'.$this->nombre{$i}.'.wav');
if($entete !== $entete2)
{
if($entete['Channels'] !== $entete2['Channels'])
{
trigger_error('fonction package, un ou plusieurs fichiers wad n\'ont pas le meme nombre de canaux',E_USER_ERROR);
}
if($entete['BitsPerSample'] !== $entete2['BitsPerSample'])
{
trigger_error('fonction package, un ou plusieurs fichiers wad, n\'ont pas le meme nombre d\'echantillons par seconde', E_USER_ERROR);
}
if($entete['SamplesPerSec'] !== $entete2['SamplesPerSec'])
{
trigger_error('fonction package, un ou plusieurs fichiers wad, n\'ont pas la meme frequence d\'echantillonage', E_USER_WARNING);
}
}
}
/* On calcule la taille des donnees que l'on a creees selon la formule de soundeditor */
$entete['taille_data'] = strlen($datas);
$entete['taille_data'] /= $entete['BlockAlign'];
$entete['taille_data'] *= $entete['BlockAlign'];
$entete['file_size'] = 44 + strlen($datas);
/* on "pack l en-tete et on y ajoute les donnees */
$binary = pack($entete_pack, $entete['file_type'],$entete['file_size'],$entete['file_id'],$entete['nom_zone1'],
$entete['taille_zone1'],$entete['FormatTag'],$entete['Channels'],$entete['SamplesPerSec'],$entete['AvgBytesPerSec'],
$entete['BlockAlign'],$entete['BitsPerSample'],$entete['nom_data'],$entete['taille_data']);
$binary .= $datas;
/* On transmet ou enregistre */
header('Content-type: audio/x-wav');
header('Content-Disposition: attachment; filename="code.wav"');
echo $binary;
}
}
$wav = new wave($_SESSION['chaine']);
?>
|
sound.php