Interfacer Flash, PHP et MySQL ?

Origine:

Voulant me lancer une bonne fois pour toutes dans le monde fascinant des bases de données, mais si possible en m'amusant, il me fallait une idée, à l'origine de celle-ci le site Mr Picasso Head, le concept était séduisant et sans aller forcement aussi loin dans les fonctionnalités, le défi semblait être à ma hauteur. Je résolus donc de simplifier au maximum, car après tous c'est mon premier site en Flash PHP MySQL, et puis si je voulais être intelligible autant ne pas créer une usine à gaz.... Le Tangram s'est alors imposé naturellement: un nombre connu (et relativement faible) de pièces et des commandes simples (bouger, tourner et retourner) pour une (quasi) infinité de combinaisons.

Structure globale:

Une fois le projet défini, il fallut ensuite s'attacher à définir l'architecture du site. Je voulais faire le site en PHP car je ne connaissais aucun langage serveur, mais celui-ci avait l'avantage d'être disponible chez tous les hébergeurs, et de posséder une syntaxe très proche de l'actionscript dont je suis familier. Pour la partie HTML, je me suis fixé sur l'XHTML 1 transitionel qui impose une syntaxe rigoureuse (ce qui est plutôt une bonne habitude à prendre) tout en permettant target="_blank", c'est-à-dire des liens permettant de sortir du site. Le XHTML incite également à séparer le fond de la forme, la mise en page étant assurée en CSS par une feuille de style séparé. Flash m'imposa l'encoding (ou charset) des pages, car il fonctionne en UTF-8, j'aurais put faire ma page en ISO-8859-1 mais j'aurais alors du transcrire, à l'aide d'utf8_encode() / utf8_decode(), tous les échanges entre ma base de données et mon affichage HTML d'une part et Flash d'autres part.

Structure MySQL:

Je m'attelais ensuite à réfléchir à la base de données, celle-ci serait composée de pas moins de 33 champs et en voici la structure (exporté avec phpMyAdmin):

CREATE `tangram` (
  `ID` smallint(4) NOT NULL auto_increment,
  `titre` varchar(12) NOT NULL default '',
  `description` varchar(50) NOT NULL default '',
  `auteur` varchar(12) NOT NULL default '',
  `date` date NOT NULL default '0000-00-00',
  `p1_posx` smallint(3) NOT NULL default '0',
  `p1_posy` smallint(3) NOT NULL default '0',
  `p1_angle` tinyint(1) NOT NULL default '0',
  `p1_flip` tinyint(1) NOT NULL default '0',
  `p2_posx` smallint(3) NOT NULL default '0',
  `p2_posy` smallint(3) NOT NULL default '0',
  `p2_angle` tinyint(1) NOT NULL default '0',
  `p2_flip` tinyint(1) NOT NULL default '0',
  `p3_posx` smallint(3) NOT NULL default '0',
  `p3_posy` smallint(3) NOT NULL default '0',
  `p3_angle` tinyint(1) NOT NULL default '0',
  `p3_flip` tinyint(1) NOT NULL default '0',
  `p4_posx` smallint(3) NOT NULL default '0',
  `p4_posy` smallint(3) NOT NULL default '0',
  `p4_angle` tinyint(1) NOT NULL default '0',
  `p4_flip` tinyint(1) NOT NULL default '0',
  `p5_posx` smallint(3) NOT NULL default '0',
  `p5_posy` smallint(3) NOT NULL default '0',
  `p5_angle` tinyint(1) NOT NULL default '0',
  `p5_flip` tinyint(1) NOT NULL default '0',
  `p6_posx` smallint(3) NOT NULL default '0',
  `p6_posy` smallint(3) NOT NULL default '0',
  `p6_angle` tinyint(1) NOT NULL default '0',
  `p6_flip` tinyint(1) NOT NULL default '0',
  `p7_posx` smallint(3) NOT NULL default '0',
  `p7_posy` smallint(3) NOT NULL default '0',
  `p7_angle` tinyint(1) NOT NULL default '0',
  `p7_flip` tinyint(1) NOT NULL default '0',
  PRIMARY KEY  (`ID`),
  KEY `titre` (`titre`,`description`,`auteur`),
  FULLTEXT KEY `titre_2` (`titre`,`description`,`auteur`)
)

-> Les 5 premiers champs servent à l'identification des Tangrams:

-> Les 28 suivants servent à positionner les 7 pièces:

function.php

Il est utile quand on crée un site en php de regrouper toutes les fonctions et déclarations de variables communes à toutes les pages dans un même fichier puis de l'inclure dans chaque page, cela facilite la maintenance puisque si on veut modifier le menu pour ajouter une page supplémentaire, la modification de cet unique fichier se répercute naturellement sur toutes les pages ou il est inclus.

légende: les parties PHP et les parties HTML

<?php
##############le header: toutes la partie du head + le bandeau Flash + le menu #################
function monheader($onglet) {
echo '<?xml version="1.0" encoding="UTF-8" ?>';
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Tangram: <?php echo $onglet?></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="author" content="Matthieu Billon Lanfrey" />
<meta name="copyright" content="&copy; 2005 Annecy Graphisme" />
<meta name="date" content="2005-11-15T08:00:00+00:00" />
<meta name="robots" content="index, follow, all" />
<meta name="revisit-after" content="30 Days" />
<meta name="Description" content="Un site de création de Tangram,
 prétexte à l'apprentissage de Flash PHP MySQL. Tous le monde peut, sans s'enregistrer,
 déposer un puzzle Tangram, ou bien sur s'amuser à résoudre les puzzles laissé par d'autres..." />
<meta name="keywords" content="Tangram, puzzle, jouer, créer, flash, php, mysql, css" />
<link rel="shortcut icon" href="http://le-tangram.com/favicon.ico" />
<link href="http://le-tangram.com/tangram.css" rel="stylesheet" type="text/css" />
</head>
<body id="<?php echo $onglet?>">
<div id="conteneur">
<object type="application/x-shockwave-flash" data="http://le-tangram.com/bandeau.swf"
 width="750" height="100">
<param name="movie" value="bandeau.swf" />
</object>
<div id="menu">
<ul>
<li><a href="http://le-tangram.com/index.php" id="accueilnav"
 title="Qu'est ce que le Tangram">accueil</a></li>
<li><a href="http://le-tangram.com/jouer.php" id="jouernav"
 title="Tenter de resoudre un tangram">jouer</a></li>
<li><a href="http://le-tangram.com/creer.php" id="creernav"
 title="Proposer un nouveau tangram">créer</a></li>
<li><a href="http://le-tangram.com/sources.php" id="sourcesnav"
 title="Comment faire un site comme celui la">sources</a></li>
<li><a href="http://le-tangram.com/liens.php" id="liensnav"
 title="D'autres liens sur le tangram">liens</a></li>
</ul>
</div>
<hr />
<?php
}
##############le footer: GoogleAds + mention légale + crédits ################
function monfooter($onglet) {
?>
<hr />
<div id="sitefooter">
<script type="text/javascript">
<!--
google_ad_client = "votre_numéro_client";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text_image";
google_ad_channel ="";
google_color_border = "993333";
google_color_bg = "DDDDCC";
google_color_link = "993333";
google_color_url = "993333";
google_color_text = "000000";
//-->
</script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
<hr />
<a href="http://www.macromedia.com/fr/downloads/" title="télécharger Flash Player" target="_blank">
<img src="http://le-tangram.com/image/flash.png" alt="télécharger Flash Player" /></a>
<?php
switch($onglet) {
	case 'jouer':
	case 'creer':
		echo '<img src="http://le-tangram.com/image/espace.png" />';
		break;
	default:
		echo '<a href="http://validator.w3.org/check?uri=referer"  target="_blank">
<img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0 Transitional" /></a>';
		break;
}
?>
<span>site optimisée 800 * 600 - 16 millions de couleurs</span>
<a href="http://jigsaw.w3.org/css-validator/validator?uri=http://le-tangram.com/tangram.css"
 target="_blank"><img src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!" /></a>
<a href="http://annecy-graphisme.com/" title="Site crée par Annecy-Graphisme.com" target="_blank">
<img src="http://le-tangram.com/image/agraph.png" alt="Réalisation Annecy Graphisme" /></a>
<hr />
<p>Copyleft: cette oeuvre est libre, vous pouvez la redistribuer et/ou la modifier selon les termes
 de la Licence Art Libre. Vous trouverez un exemplaire de cette Licence sur le site Copyleft Attitude:
  <a href="http://www.artlibre.org" target="_blank">http://www.artlibre.org</a>
   ainsi que sur d'autres sites.</p>
</div>
</div>
</body>
</html>
<?php
}
############## formattagedes donnees pour Flash: ?nom=valeur&nom=valeur&etc... #######
function envoi_flash($unarray) {
	$sortie='?';
	foreach ($unarray as $name => $value){
			$sortie .= $name.'='.$value.'&';
	}
	return substr($sortie, 0, -1);
}
############################## protection des donnees recues #########################
$trucavirer = array("<", ">");
function protection($value) {
	// Stripslashes
	if (get_magic_quotes_gpc()) {
		$value = stripslashes($value);
	}
	// Protection si ce n'est pas un entier
	if (!is_numeric($value)) {
		$value mysql_real_escape_string($value);
		$value = str_replace($trucavirer," ",$value);
	}
	return $value;
}
############################## les infos de connexions ###############################
$host="nom_du_serveur";
$login=""nom_d_utilisateur"";
$password="mot_de_passe";
$db="nom_de_la_base";
$table="no_de_la_table";
?>

tangram.css

La feuille de style n'a rien d'extraordinaire, je commence par supprimer tous les paddings et margins, car IE et FF ne les géres pas de la même manière (pour éviter toutes surprises, je prefere remettre les compteurs à zéro), après je redefinis les balises communes à toutes les pages, et enfin distingue les différentes parties...

* {
margin: 0px;
padding: 0px;
}
html,body {
width: 100%;
height: 100%;
background:#ddc;
font-family:"Courier New", Courier, monospace;
font-size: 1em;
text-align:center;
color: #000;
text-decoration: none;
}
h1 {
font-size: 1.5em;
font-weight:bold;
}
h2 {
font-size: 1.2em;
font-weight:bold;
}
hr {
height: 20px;
clear: both;
visibility: hidden;
}
select {
width:100px;
}
a {
color: #900;
text-decoration: none;
}
a:hover {
color: #F00;
}
/* CONTENEUR */
#conteneur {
position: relative;
margin: 0 auto;
width: 750px;
}
/* MENU */
#menu {
width:750px;
height:20px;
}
#menu ul {
list-style-type: none;
width: 100%;
}
#menu li {
float: left;
}
#menu a {
display: block;
width: 146px;
height: 18px;
text-align: center;
text-decoration: none;
color: #000;
font-weight: bold;
border:solid 2px #966;
background:#eed;
}
#menu a:hover {
color: #933;
border:solid 2px #933;
background:#ffe;
}
body#accueil a#accueilnav,
body#jouer a#jouernav,
body#creer a#creernav,
body#sources a#sourcesnav,
body#liens a#liensnav {
color: #933;
border:solid 2px #933;
background:#ffe;
}
/* ACCUEIL */
img.float {
float: left;
width: 400px;
height: 400px;
}
p.float {
float: left;
text-align:left;
width: 340px;
height: 390px;
}
/* JOUER */
#current {
color: #F00;
}
dl.view {
float: left;
width: 150px;
}
.view dt {
font-size:1.1em;
text-transform:capitalize;
font-weight:bold;
}
.view dd {
font-size:0.9em;
font-style:italic;
font-weight:lighter;
}
/* SOURCES */
#contenusources * {
text-align: left;
padding: 5px;
}
#contenusources h1,
#contenusources h2 {
text-align: center;
padding: 10px;
}
pre {
font-size:0.9em;
display: block;
width: 750px;
border:solid 2px #966;
background:#eed;
}
.php {
color:#C60;
}
.html {
color:#069;
}
/* BAS DE PAGE */
#sitefooter {
font-size:0.7em;
}
#sitefooter img {
float: left;
width:88px;
height:31px;
border:0px;
}
#sitefooter span {
float: left;
width:373px;
height:31px;
line-height:31px;
}

Notez l'astuce du style du menu qui permet, en conjonction avec monheader($onglet) de fonction.php qui écrit le nom de la page comme ID du body, de sélectionner un style diffèrent pour le lien de la page ou l'on se trouve.

insert.php et tangram_make.fla

Après avoir créé ma structure, ainsi que ma base de données, je m'attelais enfin au travail le plus intéressant : le Flash permettant de manipuler et créer de nouvelles figures. Le fichier fla est disponible au téléchargement ici (clic droit puis enregistrer la cible sous...). Le fichier PHP d'insertion des données est très simple, il se contente de récupérer les données $_POST envoyé par Flash, supprime certains caractères pour éviter les problèmes de base de données ou de javascript, puis construit la requête d'insertion en oubliant pas d'y ajouter la date...

<?php
###################################################################
Fichier d'insertion de donnees pour le tangram Flash
# arrive en $_POST:# -> le titre ['titre']
# -> une description et/ou des mots clés['description']
# -> le nom de l'auteur ['auteur']
# -> pour chaque pieces p1 à p7: -> la position en X ['p1_posx']
#                                -> la position en Y ['p1_posy']
#                                -> l'angle ['p1_angle']
#                                -> si elle est flip ou non ['flip']
# actions:# -> on rajoute la date# -> on enregistre la nouvelle entrée dans la BDD
# -> on renvoie statut=ok ou statut=error
##################################################################
require 'function.php';
$connexion = mysql_connect($host,$login,$password);
if ($connexion) {
	$statut = 'ok';
} else {
	$statut = mysql_error();
}mysql_select_db($db);
//protection des donnes recues
$post_traite = array();
foreach($_POST as $key => $value) {
	$post_traite[$key] = protection($value);
}
//preparation de la requete d'insertion:
$query="INSERT INTO ".$table." VALUES ('', '";
$query.=$post_traite['titre']."', '".$post_traite['description']."', '".$post_traite['auteur']."',
 '".$post_traite['date']."', ";
$query.=$post_traite['p1_posx'].", ".$post_traite['p1_posy'].", ".$post_traite['p1_angle'].",
 ".$post_traite['p1_flip'].", ";
$query.=$post_traite['p2_posx'].", ".$post_traite['p2_posy'].", ".$post_traite['p2_angle'].",
 ".$post_traite['p2_flip'].", ";
$query.=$post_traite['p3_posx'].", ".$post_traite['p3_posy'].", ".$post_traite['p3_angle'].",
 ".$post_traite['p3_flip'].", ";
$query.=$post_traite['p4_posx'].", ".$post_traite['p4_posy'].", ".$post_traite['p4_angle'].",
 ".$post_traite['p4_flip'].", ";
$query.=$post_traite['p5_posx'].", ".$post_traite['p5_posy'].", ".$post_traite['p5_angle'].",
 ".$post_traite['p5_flip'].", ";
$query.=$post_traite['p6_posx'].", ".$post_traite['p6_posy'].", ".$post_traite['p6_angle'].",
 ".$post_traite['p6_flip'].", ";
$query.=$post_traite['p7_posx'].", ".$post_traite['p7_posy'].", ".$post_traite['p7_angle'].",
 ".$post_traite['p7_flip'].");";
//envoie de la requete d'insertion:
if (mysql_query($query)) {
	$statut = 'ok';
} else {
	$statut = mysql_error();
}
//retour Flash
echo "&statut=".$statut."&";
mysql_close();
?>

jouer.php, tangram_view.fla et tangram_play.fla

Les deux fichiers Flash sont diponibles ici: tangram_view.fla et tangram_play.fla (clic droit puis enregistrer la cible sous...).
La source du fichier jouer.php est détaillée ci-dessous:


<?php
require 'function.php';
monheader('jouer');
############## formattage de la date pour que ca soit plus lisible ######################################
function format_date($unedate) {
	$date_array = array();
	$date_array = explode("-",$unedate);
	return $date_array[2]."/".$date_array[1]."/".$date_array[0];
}
##################### initialisation de la connexion: ####################################################
$connexion = mysql_connect($host,$login,$password) or trigger_error(mysql_error(),E_USER_ERROR);
mysql_select_db($db);
##################### recupération des données de $_GET[] et verification ################################
$get_traite = array();
foreach($_GET as $key => $value) {
	$get_traite[$key] = protection(urldecode($value))
}
if (isset($get_traite['ID']) && is_numeric($get_traite['ID'])) {
	$ID=$get_traite['ID'];
} else {
	$ID='ID';
}
if (isset($get_traite['page']) && is_numeric($get_traite['page'])) {
	$page=$get_traite['page'];
} else {
	$page=1;
}
if (isset($get_traite['recherche'])) {
	$recherche_array = explode(" ",$get_traite['recherche']);
} else {
	$recherche='';
}
if (isset($get_traite['tri'])) {
	switch ($get_traite['tri']) {
		case 'auteur'
		$tri='auteur';
		break;
		case 'titre':
		$tri='titre';
		break;
		default:
		$tri='date';
		break;
	}
} else {
	$tri='date';
}
if (isset($get_traite['sens'])) {
	switch ($get_traite['sens']) {
	case 'croissant':
	$sens='croissant';
	break;
	default:
	$sens='decroissant';
	break;
	}
} else {
	$sens='decroissant';
}
if (isset($get_traite['resultats'])) {
	switch ($get_traite['resultats']) {
	case 5:
	$resultats=5;
	break;
	case 10:
	$resultats=10;
	break;
	case 20:
	$resultats=20;
	break;
	case 25:
	$resultats=25;
	break;
	default:
	$resultats=15;
	break;
	}
} else {
	$resultats=15;
}
##################### affichage du formulaire de recherche ###############################################
?>
<div id="form">
<form method="get" action="jouer.php">
rechercher:
<input name="recherche" type="text" size="30" value="<?php echo $recherche; ?>" />
trier les résultats par:
<select name="tri">
<option<?php if ($tri=='date') { echo ' selected="selected"'; } ?>>date</option>
<option<?php if ($tri=='auteur') { echo ' selected="selected"'; } ?>>auteur</option>
<option<?php if ($tri=='titre') { echo ' selected="selected"'; } ?>>titre</option>
</select>
<hr />
dans l'ordre:
<select name="sens">
<option<?php if ($sens=='croissant') { echo ' selected="selected"'; } ?>>croissant</option>
<option<?php if ($sens=='decroissant') { echo ' selected="selected"'; } ?>>decroissant</option>
</select>
et afficher:
<select name="resultats">
<option<?php if ($resultats==5) { echo ' selected="selected"'; } ?>>5</option>
<option<?php if ($resultats==10) { echo ' selected="selected"'; } ?>>10</option>
<option<?php if ($resultats==15) { echo ' selected="selected"'; } ?>>15</option>
<option<?php if ($resultats==20) { echo ' selected="selected"'; } ?>>20</option>
<option<?php if ($resultats==25) { echo ' selected="selected"'; } ?>>25</option>
</select>
résultats par page
<input type="submit" name="submit" value="Valider" />
</form>
</div>
<hr />
<?php
##################### preparation de la requete d'extraction: ############################################
$query_recup="SELECT *";
$query_compte="SELECT COUNT(*) AS nb_tangrams";
$query_mixte=" FROM ".$table." WHERE ID=".$ID;
if ($ID!='ID') {
	// si $ID!='ID' c'est que l'utilisateur à séléctionné un tangram, il n'y a donc qu'un resultat
	$nb_result = 1;
} else {
	//sinon elaboration de la requete de recherche dans la base
	if ($recherche!='') {
		foreach($recherche_array as $recherche_query) {
			$query_mixte.= " AND (titre LIKE '%".$recherche_query."%' ";
			$query_mixte.= "OR description LIKE '%".$recherche_query."%' ";
			$query_mixte.= "OR auteur LIKE '%".$recherche_query."%')";
		}
	}
	$query_mixte.= " ORDER BY ".$tri;
	if ($sens=='decroissant') {
		$query_mixte.= " DESC";
	}
##################### on compte le nombre d'enregistrement qu'il faudrait afficher #######################
	$query_compte = $query_compte.$query_mixte;
	$retour = mysql_query($query_compte) or die(mysql_error());
	$donnees = mysql_fetch_array($retour);
	$nb_result = $donnees['nb_tangrams'];
}
##################### il n'y a pas de resultat on affiche un message d'erreur ############################
if ($nb_result==0) {
mysql_close();
?>
<br />
<br />
<br />
<br />
<h1>Désolé, aucun résultat ne correspond à votre recherche</h1>
<br />
<br />
><br />
<br />
<?php
} else {
	$nombreDePages  = ceil($nb_result / $resultats);
##################### envoie de la requete d'extraction: ##################################################
	$premier_tangram_a_afficher = ($page - 1) * $resultats
	$query_limit = ' LIMIT ' . $premier_tangram_a_afficher . ', '.$resultats;
	$query_recup = $query_recup.$query_mixte.$query_limit;
	$rs_tangrams = mysql_query($query_recup) or die(mysql_error());
	mysql_close();
##################### il y a plusieurs resultats on les affiches avec tangram_view.swf ####################
	if ($nb_result>1) {
		$nb=0;
		echo "<h1>Choississez un Tangram: parmis ces ".$nb_result." résultats</h1>\n";
		if ($nombreDePages>1) {
			echo "<h2>Page : ";
			for ($i = 1 ; $i <= $nombreDePages ; $i++) {
				if ($page == $i) {
					echo '<span id="current">'.$i.'</span> ';
				} else {
					echo '<a href="jouer.php?page='.$i.'&recherche='.$recherche.'
&sens='.$sens.'&tri='.$tri.'&resultats='.$resultats.'">'.$i.'</a>';
				}
			}
			echo "</h2>\n";
		}
		echo "<hr />\n";
		while ($tangram = mysql_fetch_assoc($rs_tangrams)) {
			$nb++;
			$temp=envoi_flash($tangram);
?>
<dl class="view">
<dt><?php echo $tangram['titre']; ?></dt>
<dd>
<object type="application/x-shockwave-flash" data="tangram_view.swf<?php echo $temp; ?>" width="110"
 height="110">
<param name="movie" value="tangram_view.swf<?php echo $temp; ?>" />
</object>
</dd>
<dd>crée le <?php echo format_date($tangram['date']); ?></dd>
<dd>par: <?php echo $tangram['auteur']; ?></dd>
<dd><?php echo $tangram['description']; ?></dd>
</dl>
<?php
			if ($nb%5==0) {
				echo "<hr />\n";
			}
		}
##################### il n'y a q'un seul resultat on l'affiche avec tangram_play.swf #####################
	} else if ($nb_result==1 || $ID!='ID') {
		$tangram = mysql_fetch_assoc($rs_tangrams);
		$temp=envoi_flash($tangram);
?>
<object type="application/x-shockwave-flash" data="tangram_play.swf<?php echo $temp; ?>" width="750"
 height="550">
<param name="movie" value="tangram_play.swf<?php echo $temp; ?>" />
</object>
<?php
	}
}
monfooter('jouer');
?>

liens.php et liens.xml

Pour compléter cette introduction à PHP, Flash et MySQL, je rajoute ici un petit script de transformation de XML en XHTML. Vous pouvez trouver ici le XML source, et voici le code de liens.php:

<?php
require 'function.php';
monheader('liens');
$file = "liens.xml";
function trustedFile($file) {
   // ne faire confiance qu'au fichiers dont nous detenons les droits
   if (!eregi("^([a-z]+)://", $file) && fileowner($file) == getmyuid()) {
           return true;
   }
   return false;
}
function startElement($parser, $name, $attribs) {
	switch ($name) {
	case 'TITRE':
	   echo "<hr />\n<h1>";
	   break;
	case 'SOUSTITRE':
	   echo "<h2>";
	   break;
	case 'LIEN':
	   echo '<a href="';
	   break;
	case 'NOM':
	   echo '"  target="_blank">';
	   break;
	}
}
function endElement($parser, $name) {
	switch ($name) {
	case 'TITRE':
	   echo "</h1>\n";
	   break;
	case 'SOUSTITRE':
	   echo "</h2>\n";
	   break;
	case 'LIEN':
	   echo "</a><br />\n";
	   break;
	}
}
function characterData($parser, $data) {
   echo $data;
}
function PIHandler($parser, $target, $data) {
   switch (strtolower($target)) {
       case "php":
           global $parser_file;
           // Si le document est de confiance, on peut
           // executer du code PHP, sinon on affiche le XML
           if (trustedFile($parser_file[$parser])) {
               eval($data);
           } else {
               printf("<em>%s</em>\n", htmlspecialchars($data));
           }
           break;
   }
}
function externalEntityRefHandler($parser, $openEntityNames, $base, $systemId, $publicId) {
   if ($systemId) {
       if (!list($parser, $fp) = new_xml_parser($systemId)) {
           printf("N'as pas put ouvrir l'entitée %s à %s\n", $openEntityNames, $systemId);
           return false;
       }
       while ($data = fread($fp, 4096)) {
           if (!xml_parse($parser, $data, feof($fp))) {
               printf("erreur XML : %s à la ligne %d lors de l'analyse de l'entité %s\n",
 xml_error_string(xml_get_error_code($parser)), xml_get_current_line_number($parser), $openEntityNames);
               xml_parser_free($parser);
               return false;
           }
       }
       xml_parser_free($parser);
       return true;
   }
   return false;
}
function new_xml_parser($file) {
   global $parser_file;
   $xml_parser = xml_parser_create();
   xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 1);
   xml_set_element_handler($xml_parser, "startElement", "endElement");
   xml_set_character_data_handler($xml_parser, "characterData");
   xml_set_processing_instruction_handler($xml_parser, "PIHandler");
   xml_set_external_entity_ref_handler($xml_parser, "externalEntityRefHandler");
   if (!($fp = @fopen($file, "r"))) {
       return false;
   }
   if (!is_array($parser_file)) {
       settype($parser_file, "array");
   }
   $parser_file[$xml_parser] = $file;
   return array($xml_parser, $fp);
}
if (!(list($xml_parser, $fp) = new_xml_parser($file))) {
   die("Impossible d'ouvrir le fichier XML");
}
while ($data = fread($fp, 4096)) {
   if (!xml_parse($xml_parser, $data, feof($fp))) {
       die(sprintf("Erreur XML : %s à la ligne %d\n", xml_error_string(xml_get_error_code($xml_parser)),
 xml_get_current_line_number($xml_parser)));
   }
}
xml_parser_free($xml_parser);
monfooter('liens');
?>

Si vous avez d'autres questions, vous pouvez les poser ici sur le post dédié du Forum de hardware.fr