La méthode find() est toute indiquée pour rechercher un enregistrement par son identifiant.
Cette méthode retourne une instance du modèle recherché (ex : un objet de type Produit) ou null si l'enregistrement n'a pas été trouvé.
Ex :
$produit = Produit::find(2);
// toujours vérifier si l'enregistrement a été trouvé
if (isset($produit)) {
...
}
Si on omet de vérifier si find() a instancié un objet et que l'objet est nul, le programme plantera lorsqu'on tentera d'accéder aux propriétés de l'objet et vous obtiendrez le message « Trying to get property of non-object ».
Il est également possible de travailler avec la méthode findOrFail(). Avec cette méthode, si aucun enregistrement ne correspond à l'identifiant demandé, une exception de type ModelNotFoundException sera levée.
Il est fortement suggéré de placer l'appel à findOrFail() dans un try...catch. De cette façon, il sera possible de réagir de façon appropriée lorsque l'enregistrement n'est pas trouvé (ex : poursuivre la recherche, afficher un message d'avertissement, etc.).
Pour que l'instruction catch fonctionne, il faut prendre soin de fournir l'espace de nom de la classe d'erreur dans le catch, incluant tout son chemin. En effet, puisque la classe ModelNotFoundException n'est pas définie dans le même espace de nom que le contrôleur, Laravel ne saurait pas où rechercher la définition de cette classe et le catch serait complètement ignoré.
Puisqu'une instruction pourrait échouer pour d'autres raisons qu'un enregistrement non trouvé, on fera suivre par un second catch qui attrapera toute autre exception. La classe Throwable est celle qui permet un tel comportement.
class ProduitsController extends Controller
{
/**
* Affiche les détails d'un produit.
*
* @param int $id
* @return @return IlluminateViewView
*/
public function show(int $id) : View
{
try {
$produit = Produit::findOrFail(2);
...
}
catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
...
}
catch (\Throwable $e) {
\Log::error('Erreur inattendue : ', [$e]);
}
...
}
...
}
Une autre alternative consiste à ajouter une instruction use.
Ex :
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Throwable;
...
class ProduitsController extends Controller
{
/**
* Affiche les détails d'un produit.
*
* @param int $id
* @return @return IlluminateViewView
*/
public function show(int $id) : View
{
try {
$produit = Produit::findOrFail(2);
...
}
catch (ModelNotFoundException $e) {
...
}
catch (Throwable $e) {
\Log::error('Erreur inattendue : ', [$e]);
}
...
}
...
}
Si on omet le try...catch et que l'enregistrement recherché n'est pas trouvé, ou encore si on omet de préciser l'espace de nom de la classe ModelNotFoundException (par un use ou en l'écrivant au long dans le catch), c'est Laravel qui récupérera l'exception. Par défaut, les configurations de Laravel font en sorte que le ModelNotFoundException génère une erreur 404.
En fait, un findOrFail() sans le try...catch est l'équivalent de :
$produit = Produit::find(2);
if (!$produit) {
abord(404);
}
La méthode find() permet de rechercher d'un seul coup plusieurs enregistrements, toujours à partir de leur identifiant. Pour y arriver, on fournira en paramètre un tableau d'identifiants et find() retournera une collection d'objets.
Le résultat sera une collection des instances trouvées.
Dans l'exemple suivant, $produits sera une collection contenant deux instances de Produit puisque le produit 36 n'existe pas.
$produits = Produit::find([1, 2, 36]);
L'utilisation de findOrFail() est moins intéressante ici puisqu'elle lèvera une exception dès qu'un des enregistrements demandés n'est pas trouvé.
« Eloquent: Getting Started - Retrieving Single Models / Aggregates ». Laravel. https://laravel.com/docs/master/eloquent#retrieving-single-models
▼Publicité