Chargement de fichiers par la méthode PUT
Comme nous l'avons vu dans notre étude du protocole HTTP, chaque action à réaliser sur le serveur possède idéalement une méthode propre. GET pour la lecture, POST pour la modification, DELETE pour la suppression, HEAD pour avoir les en-têtes d'un document ainsi que PUT pour la création de nouvelles ressources.
Côté client
Idéalement donc, nous ne devrions donc pas utiliser la méthode POST pour envoyer des fichiers (du moins, lors de la création de ressources) mais la méthode PUT. Le formulaire idéal que nous devrions posséder pour la création d'une nouvelle ressource devrait donc avoir la forme suivante :
<form method="put">
<p>
<label for="titre">Titre</label>
<input type="text" id="titre" name="titre" />
</p>
<p>
<label for="image">Image</label>
<input type="file" id="image" name="image" />
</p>
<input type="submit" value="ajouter" />
</form>
Malheureusement, nous ne pourrons commencer à voir apparaître ce genre de formulaires qu'avec HTML5.
Une surcouche simple avec JavaScript ?
En attendant la sortie de HTML5 et donc le support de la méthode PUT, nous pourrions créer des surcouches simple en JavaScript pour envoyer nos fichiers. En effet la fameuse interface XMLHTTPRequest de JavaScript (à l'origine de ce que l'on appelle AJAX) implémente elle toutes les méthodes du protocole HTTP.
Il suffirait donc de créer un formulaire de ce type :
<?xml version="1.0" encoding="utf-8"?>
<!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" lang="fr">
<head>
<title>Upload</title>
<meta http-equiv="content-type" content="text/html; charset= utf-8" />
<script type="text/javascript">
window.onload = function() {
document.getElementById("test").onsubmit = function() {
var xhr = null;
if(window.XMLHttpRequest)
xhr = new XMLHttpRequest();
else if(window.ActiveXObject){
try {
xhr = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
} else {
alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
xhr = false;
}
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
if (xhr.status == 200) {
this.innerHTML = "Le fichier "+this.fichier.value+" a bien ete charge";
} else {
this.innerHTML = "Impossible de charger le fichier "+this.fichier.value;
}
}
}
xhr.open("PUT", "script.php", false);
xhr.send(this.fichier);
return false;
}
}
</script>
</head>
<body>
<form method="put" id="test">
<p>
<label for="fichier">Fichier</label>
<input type="file" id="fichier" name="fichier" />
</p>
<input type="submit" value="envoyer" />
</form>
</body>
</html>
Cependant cette solution se borne à un problème de sécurité de taille. Il est impossible en JavaScript de pouvoir lire le contenu du fichier appartenant encore au client. Il existe cependant des astuces pour palier à ce problème. Mais les mettre en place relève du calvaire.
Ressources utiles sur le sujet
- http://www.xorax.info/blog/programmation/114-input-file-iframe.html
- http://www.xorax.info/blog/programmation/127-ajax-upload-input-file.html
Côté serveur
Côté serveur néanmoins, les choses sont plus simples. Car le duo Apache/PHP permet d'implémenter facilement le traitement des requêtes de type PUT voire DELETE aussi d'ailleurs.
La directive Script d'Apache
La première chose à faire si vous souhaitez que votre script réponde à des requêtes HTTP avec la méthode PUT sera de signaler à Apache ce qu'il doit faire lorsqu'on lui demandera de traiter une telle requête. Nous utiliserons pour cela la directive « Script » d'Apache.
Vous pouvez placer cette directive n'importe où dans votre fichier de configuration d'Apache. Généralement on l'insère dans un bloc <Directory> ou parfois même directement dans un <VirtualHost>.
Nous allons voir un exemple simple, permettant de charger un fichier. A chaque utilisation de la méthode PUT, nous demanderons donc à Apache d'exécuter le fichier « put.php » :
Script PUT /put.php
Traitement de la méthode PUT en PHP
Une fois Apache configuré pour exécuter notre script lors d'une requête avec la méthode PUT il n'y a rien de plus simple à traiter en PHP.
Il suffit de lire le flux entrant qui contiendra les données du fichier, puis d'aller les écrire dans un fichier de destination sur le serveur.
$putdata = fopen("php://input", "r");
$fp = fopen("myputfile.ext", "w");
and write to the file */
while ($data = fread($putdata, 1024))
fwrite($fp, $data);
fclose($fp);
fclose($putdata);