Heim  >  Artikel  >  PHP-Framework  >  Ein Artikel, der die Gründe und Lösungen für das Versagen der Laravel-Modellbindung erläutert

Ein Artikel, der die Gründe und Lösungen für das Versagen der Laravel-Modellbindung erläutert

PHPz
PHPzOriginal
2023-04-08 23:30:02975Durchsuche

Die Laravel-Modellbindung ist eine wichtige Funktion des Laravel-Frameworks. Sie bietet eine Funktion zum automatischen Einfügen von URL-Parametern in das angegebene Modell in der Controller-Methode und vermeidet so den mühsamen Prozess der manuellen Abfrage der Datenbank durch Entwickler. In der Praxis stoßen Entwickler jedoch manchmal auf Modellbindungsfehler, die zu Programmausnahmen führen. Dieser Artikel beginnt mit tatsächlichen Fällen, um mögliche Probleme und Lösungen für die Laravel-Modellbindung zu erläutern.

Beispiel:

Angenommen, wir haben eine Produktlistenseite. Die URL akzeptiert einen Kategorieparameter zur Darstellung der Produktkategorie. Der Controller verwendet die Modellbindung, um die Produkte unter der angegebenen Kategorie abzufragen und die Ansicht zurückzugeben. Dies erreichen wir durch den folgenden Code:

public function index(Category $category)
{
    $products = $category->products;
    return view('products.index', ['products' => $products]);
}

Wie Sie sehen können, binden wir das Category-Modell über den Parameter $category des index() code> Methode, dann erhalten Sie alle Produkte in dieser Kategorie. Wenn wir jedoch eine nicht vorhandene Kategorie in die Adressleiste des Browsers eingeben, löst das Programm eine Ausnahme aus, wie unten gezeigt: <code>index() 方法的参数 $category 来绑定 Category 模型,然后获取该分类下的所有产品。然而,当我们在浏览器地址栏中输入一个不存在的分类时,程序就会抛出异常,如下所示:

Illuminate\Database\Eloquent\ModelNotFoundException

No query results for model [App\Category].

我们发现,程序抛出的异常信息是 ModelNotFoundException,也就是说 Laravel 框架无法找到对应的模型。那么,出现这种问题的原因是什么呢?

问题原因:

模型绑定能够正常工作的前提是,URL 参数必须与数据库中对应的模型匹配。如果 URL 参数无法匹配,则会出现模型绑定失败的情况。在上面的示例中,我们在地址栏中输入了一个不存在的分类 ID,这就导致了程序无法找到对应的模型。

另外,如果我们在控制器方法中手动注入了模型,例如:

public function show(Product $product)
{
    return view('products.show', ['product' => $product]);
}

则还需要注意以下问题:

  1. 参数名必须与路由中的占位符名称相同。
  2. 参数类型必须是一个 Eloquent 模型类。
  3. 如果无法找到对应的模型,则会抛出 ModelNotFoundException 异常。

解决方案:

那么,我们该如何解决模型绑定失败的问题呢?下面是两种解决方案。

  1. 定义全局范围的解析器

我们可以在 boot() 方法中定义全局范围的解析器,以捕获所有的 ModelNotFoundException 异常,然后将其转换为自定义的异常。以下是实现方式:

(1)定义自定义异常:

namespace App\Exceptions;

use Exception;

class NotFoundException extends Exception
{
    public function render($request)
    {
        return response()->view('errors.404');
    }
}

该异常类在抛出异常时,将返回 resources/views/errors/404.blade.php 视图。

(2)在 AppServiceProvider.php 中注册解析器:

use App\Exceptions\NotFoundException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $this->app->bind(ModelNotFoundException::class, function ($e) {
            throw new NotFoundException;
        });
    }
}

boot() 方法中,我们绑定了 ModelNotFoundException 异常到自定义异常 NotFoundException,以便程序能够正确渲染 404 页面。

  1. 手动抛出异常

在控制器方法中,我们可以手动抛出自定义异常,例如:

public function show($id)
{
    $product = Product::findOrFail($id);

    if ($product->category->id !== $this->category->id) {
        throw new NotFoundException;
    }

    return view('products.show', ['product' => $product]);
}

在该方法中,我们手动查询产品模型,然后根据分类 ID 判断产品是否属于当前分类,如果不属于,则手动抛出自定义异常 NotFoundExceptionrrreee

Wir haben festgestellt, dass die vom Programm ausgelösten Ausnahmeinformationen ModelNotFoundException sind. Dies bedeutet, dass das Laravel-Framework das entsprechende Modell nicht finden kann. Was ist also der Grund für dieses Problem?

Ursache des Problems:

Damit die Modellbindung ordnungsgemäß funktioniert, müssen die URL-Parameter mit dem entsprechenden Modell in der Datenbank übereinstimmen. Wenn die URL-Parameter nicht übereinstimmen, schlägt die Modellbindung fehl. Im obigen Beispiel haben wir eine nicht vorhandene Kategorie-ID in die Adressleiste eingegeben, was dazu führte, dass das Programm das entsprechende Modell nicht finden konnte. 🎜🎜Wenn wir das Modell außerdem manuell in die Controller-Methode einfügen, zum Beispiel: 🎜rrreee🎜, müssen wir auch auf die folgenden Probleme achten: 🎜
  1. Der Parametername muss mit dem identisch sein Platzhaltername in der Route.
  2. Der Parametertyp muss eine Eloquent-Modellklasse sein.
  3. Wenn das entsprechende Modell nicht gefunden werden kann, wird eine ModelNotFoundException-Ausnahme ausgelöst.
🎜Lösung:🎜🎜Wie lösen wir also das Problem des Modellbindungsfehlers? Nachfolgend finden Sie zwei Lösungen. 🎜
  1. Definieren Sie einen globalen Bereichsparser
🎜Wir können einen globalen Bereichsparser in der Methode boot() definieren, um alle ModelNotFoundException zu erfassen. code> Ausnahme und konvertieren Sie sie dann in eine benutzerdefinierte Ausnahme. Das Folgende ist die Implementierungsmethode: 🎜🎜(1) Definieren Sie eine benutzerdefinierte Ausnahme: 🎜rrreee🎜Wenn eine Ausnahme von dieser Ausnahmeklasse ausgelöst wird, wird die <code>resources/views/errors/404.blade.php zurückgegeben Code> Ansicht. 🎜🎜(2) Registrieren Sie den Parser in <code>AppServiceProvider.php: 🎜rrreee🎜In der boot()-Methode binden wir die ModelNotFoundException-Ausnahme an eine Benutzerdefinierte Ausnahme NotFoundException, damit das Programm die 404-Seite korrekt rendern kann. 🎜
  1. Manuell Ausnahmen auslösen
🎜In der Controller-Methode können wir manuell benutzerdefinierte Ausnahmen auslösen, zum Beispiel: 🎜rrreee🎜In dieser Methode fragen wir manuell ab Produktmodell und bestimmen dann anhand der Kategorie-ID, ob das Produkt zur aktuellen Kategorie gehört. Ist dies nicht der Fall, lösen wir manuell eine benutzerdefinierte Ausnahme NotFoundException aus. 🎜🎜Fazit:🎜🎜Die Laravel-Modellbindung ist eine wichtige Funktion im Laravel-Framework, die Datenbankabfragen und Controller-Code erheblich vereinfachen kann. In der Praxis müssen wir jedoch auch auf einige Details achten, z. B. die Vermeidung der manuellen Injektion nicht vorhandener Modelle, die Definition globaler Parser zur Behandlung von Ausnahmen usw. Ich hoffe, dass jeder durch diesen Artikel die Bindung des Laravel-Modells besser verstehen und unnötige Probleme vermeiden kann. 🎜

Das obige ist der detaillierte Inhalt vonEin Artikel, der die Gründe und Lösungen für das Versagen der Laravel-Modellbindung erläutert. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn