Laravel 4 : chapitre 5 : Les entrées
Nous avons vu comment une requête est dirigée selon son URI grâce aux routes. Nous avons aussi vu comment récupérer des paramètres présents dans cette URI. Maintenant nous allons voir comment récupérer les données transmises.
Récupérer des données transmises
La façon la plus classique de transmettre des informations est certainement l’usage d’un formulaire. Voici un formulaire élémentaire avec deux entrées (je décris la classe Form dans un article ultérieur) que j’ai inclus pour le moment dans la route de base :
Route::get('/', function() { echo Form::open(array('url' => 'log', 'method' => 'GET')); echo Form::label('nom', 'Nom :'); echo Form::text('nom'),'<br>'; echo Form::label('age', 'Age :'); echo Form::text('age'),'<br>'; echo Form::submit('Submit'); echo Form::close(); });
Voici ce que ça donne dans un navigateur (bon d’accord ce n’est pas folichon mais ce n’est pas le sujet) :
Nous allons créer une route pour intercepter l’URL de retour et prendre en compte les valeurs entrées :
Route::any('log', function() { return 'Le nom est '.Input::get('nom').'<br>'.'L\'âge est '.Input::get('age'); });
Vous remarquez que pour la route je n’ai utilisé ni get , ni post, mais any. Ainsi la route sera activée quelle que soit la méthode utilisée. En l’occurrence dans le formulaire j’ai prévu la méthode « get ». Par exemple pour les entrées toto et 28 l’URI prend cette forme :
http://localhost/laravel/public/log?nom=toto&age=28
Et on obtient en retour :
Le nom est toto L'âge est 28
Faites le même essai avec la méthode post (comme c’est la valeur par défaut on est pas obligé de la mentionner) :
Route::get('/', function() { echo Form::open(array('url' => 'log')); echo Form::label('nom', 'Nom :'); echo Form::text('nom'),'<br>'; echo Form::label('age', 'Age :'); echo Form::text('age'),'<br>'; echo Form::submit('Submit'); echo Form::close(); });
Vous obtenez le même résultat. On a donc pas à se soucier de la méthode utilisée, la syntaxe reste la même pour récupérer les valeurs :
Input::get('nom_de_la_valeur')
Tester les données transmises et valeur par défaut
Que se passe-t-il si une valeur attendue est absente ? Si nous poursuivons avec notre exemple, si l’âge est absent j’aurai cet affichage :
Le nom est toto L'âge est
Il y a une possibilité pour gérer ce problème, il faut tester la présence de la valeur :
Route::any('log', function() { $texte = 'Le nom est '.Input::get('nom'); if (Input::has('age')) $texte .='<br>'.'L\'âge est '.Input::get('age'); return $texte; });
Il est possible de prévoir une valeur par défaut si l’entrée est absente :
$texte = 'Le nom est '.Input::get('nom', 'Dupont');
Attention ! Il faut vraiment que la donnée soit absente, c’est à dire null pour que ça fonctionne, autrement dit un retour de formulaire avec un champ vide ne déclenchera pas cette option ! Il y a eu une discussion sur ce sujet.
Les données dans un tableau
Il est parfois pratique de récupérer toutes les données dans un tableau pour un traitement global. Voici comment faire :
Route::any('log', function() { return var_dump(Input::all()); });
Avec toujours le même formulaire et les mêmes entrées on obtient :
array(2) { ["nom"]=> string(4) "toto" ["age"]=> string(2) "28" }
On a la possibilité de sélectionner seulement certaines entrées pour le tableau. Enrichissons notre formulaire :
Route::get('/', function() { echo Form::open(array('url' => 'log')); echo Form::label('nom', 'Nom :'); echo Form::text('nom'),'<br>'; echo Form::label('ville', 'Ville :'); echo Form::text('ville'),'<br>'; echo Form::label('age', 'Age :'); echo Form::text('age'),'<br>'; echo Form::submit('Submit'); echo Form::close(); });
Ce qui donne :
Maintenant on veut récupérer dans un tableau uniquement les entrées Nom et Ville :
Route::any('log', function() { return var_dump(Input::only('nom', 'ville')); });
Voici ce que ça donne avec une saisie :
array(2) { ["nom"]=> string(6) "Durant" ["ville"]=> string(5) "Paris" }
On peut obtenir le même résultat en excluant l’âge :
Route::any('log', function() { return var_dump(Input::except('age')); });
Les fichiers
Voyons maintenant comment récupérer un fichier. Créons un formulaire élémentaire :
Route::get('/', function() { echo Form::open(array('url' => 'trans', 'enctype' => 'multipart/form-data')); echo Form::file('fichier'); echo Form::submit('Envoyer le fichier'); echo Form::close(); });
Et voici la route :
Route::any('trans', function() { echo var_dump(Input::file('fichier')); });
Et le résultat de l’action :
object(Symfony\Component\HttpFoundation\File\UploadedFile)[9] private 'test' => boolean false private 'originalName' => string 'routes.php' (length=10) private 'mimeType' => string 'text/plain' (length=10) private 'size' => int 642 private 'error' => int 0
Vous voyez ici que Laravel utilise un composant de Symfony
Vous constatez aussi qu’il est facile de trouver le nom du fichier, son type MIME et sa taille puisqu’on a un objet qui contient ces éléments. On reçoit un fichier il faut maintenant en faire quelque chose, normalement le placer dans un dossier quelque part, en effet par défaut PHP conserve un fichier téléchargé seulement jusqu’à la fin du script. Créez un dossier public/uploads :
Modifiez ainsi la route :
Route::any('trans', function() { Input::file('fichier')->move('uploads'); });
Utilisez le formulaire pour envoyer un fichier et regardez ensuite dans le dossier uploads :
Le fichier a bien été reçu et placé dans le bon dossier, par contre il se retrouve avec un nom différent et une extension tmp. On peut imposer un nom et une extension :
Route::any('trans', function() { Input::file('fichier')->move('uploads', 'mon_fichier.jpg'); });
Résultat :
14 commentaires
ChDUP
euh ….
Je viens de réessayer et le ‘any’ passe bien cette fois.
J’ai tellement fait de tests entre 2 que je suis incapable de retrouver ce qui clochait quand j’ai écrit ce message.
Désolé mais visiblement le problème se situait entre le clavier et la chaise.
ChDUP
perso, pour le premier exemple de récupération des données transmises,
avec le Route::any(‘log’, function() j’ai une erreur NotFoundHttpException
En revanche en passant par Route::get(‘log’, function() c’est ok.
bestmomo
C’est curieux ça ! Qu’est-ce qu’elle te raconte la page d’erreur ? C’est assez détaillé…
beesofts
« A un moment le framework prévoyait d’insérer une valeur par défaut, mais cette possibilité a disparu par la suite, c’est dommage… »
à priori c’est revenu
bestmomo
Oui je viens de vérifier dans la documentation mais une chose me chagrine un peu, ça ne semble pas fonctionner par exemple si je fais ça avec mon exemple :
Route::any('log', function() {
return 'Le nom est '.Input::get('nom', 'Dupont');
});
Je récupère une donnée de type string vide au retour du formulaire qui n’est pas interprétée comme une absence de données. Ce n’est que si la valeur est null, donc vraiment inexistante que celle par défaut est prise en compte. Du coup l’utilité de cette option devient limitée…
J’ai modifié le texte de ce fil en conséquence, merci ;).
Prestaspirit
Salut,
la méthode move opère un traitement mise à part le move_uploaded_file?
J’imagine qu’il existe d’autre méthode dans la classe UploadedFile pour faire les vérification d’usage lors d’un upload de fichier.
bestmomo
Salut,
La méthode move se contente du déplacement, la classe UploadedFile propose d’autres méthodes.
Prestaspirit
merci
endzero
Merci pour cette réponse si rapide.
J’étais passé par cette manière :
strrchr($_FILES[‘fichier’][‘name’],’.’);
Ca fonctionne mais les getters, c’est quand même plus propre.
Pour le type de fichier, je vais passer par la validation.
endzero
Surement un des meilleurs tuto sur laravel 4 du moment.
Juste une petite question : comment récupérer l’extension d’un fichier uploadé ?
Merci pour votre travail.
bestmomo
Pour récupérer une information il faut utiliser les getters de la classe UploadedFile de Symfony. L’extension de fichier nous est donnée par getClientOriginalExtension(), donc avec cette syntaxe dans notre contexte :
Input::file('fichier')->getClientOriginalExtension()
Petite remarque : c’est l’extension du fichier récupéré, ça ne nous donne aucune réelle information sur le type du fichier, autrement dit ce n’est pas parce qu’on a « jpg » que c’est effectivement une image ;).
thefree
Merci pour ce tuto 😀
Il est très bien conçu.
Je lui prédit un beau succès dans les mois à venir 😉
Nic'O
A la place du var_dump, on peut aussi utiliser un helper de Laraval dd($array) qui reproduit la même chose avec les et un die; à la fin.
lara
Le helper de la version 3 n’a pas été intégré dans la version 4, de même que d’autres fonctionnalités comme Form. On peut évidemment les réintégrer étant donné la modularité de cette version et je compte montrer plus tard comment on réalise cela.