2017-08-31 94 views
0

目前,我正在編寫基於Laravel的電子商務應用程序。我的項目的主導航結構如下:Laravel - 類別導航路由錯誤

  • 首頁(/)
  • 類別1(例如/汽車)
  • 類別2(例如/汽車/大衆)
  • 3類(如/汽車/大衆/高爾夫)

該模型的名稱是'類別'和控制器是'類別控制器'。型號表產生與遷移

<?php 

use Illuminate\Support\Facades\Schema; 
use Illuminate\Database\Schema\Blueprint; 
use Illuminate\Database\Migrations\Migration; 

class CreateCategoriesTable extends Migration 
{ 
    /** 
    * Run the migrations. 
    * 
    * @return void 
    */ 
    public function up() 
    { 
     Schema::create('categories', function (Blueprint $table) { 
      $table->increments('id'); 
      $table->string('name'); 
      $table->integer('parent_id'); 
      $table->timestamps(); 
     }); 
    } 

    /** 
    * Reverse the migrations. 
    * 
    * @return void 
    */ 
    public function down() 
    { 
     Schema::dropIfExists('categories'); 
    } 
} 

爲此我創建了以下航線web.php

Route::get('/{category1}', '[email protected]'); 

Route::get('/{category1}/{category2}', '[email protected]'); 

Route::get('/{category1}/{category2}/{category3}', '[email protected]'); 

這是我CategoryController

<?php 

namespace App\Http\Controllers; 

use Illuminate\Http\Request; 
use App\Category as CategoryModel; 

class CategoryController extends Controller 
{ 
    public function category1(CategoryModel $category1) 
    { 
     // Do some stuff 
    } 

    public function category2(CategoryModel $category1, CategoryModel $category2) 
    { 
     // Do some stuff 
    } 

    public function category3(CategoryModel $category1, CategoryModel $category2, CategoryModel $category3) 
    { 
     // Do some stuff 
    } 
} 

最後,像localhost/cars/volksw這樣的頁面agen/golf可以打開。問題是如果我在瀏覽器中請求本地主機/高爾夫,服務器會將頁面發送給我。該頁面不是我想要的。這個頁面只能通過localhost/cars/volkswagen/golf。

你有一些建議如何解決這個問題?

編輯1:我仍然想要頁/ category1 /和/ category1/category2 /交付。本頁面顯示可用產品的概覽。

+0

您是否驗證其功能,它實際上正在經歷?嘗試'Log :: info(__ FUNCTION __);'作爲每個函數的第一行,然後在瀏覽到該頁面後檢查日誌。 – aynber

+0

@aynber它正在通過所有的功能: [2017-09-01 05:50:24] local.INFO:category1 [2017-09-01 05:50:30] local.INFO:category2 [ 2017-09-01 05:50:35] local.INFO:category3 – glembo

回答

0

我自己找到了解決方案。爲了避免不同類別可以輸入到URL的「錯誤」部分,我必須在RouteServiceProvider的引導方法中定義我自己的解析邏輯。這被稱爲Route Model Binding

這是代碼insinde的RouteServiceProvider,對我的項目工程:

public function boot() 
    { 
     parent::boot(); 

     Route::bind('cytegory1', function ($value) { 
      return Category::where('name', $value)->where('parent_id', 0)->first(); 
     }); 

     Route::bind('category2', function ($value) { 

      $category2 = Category::where('name', $value)->first(); 

      // Check if level 2 

      if($category2->parent_id == 0) { 
       // 1st level -> 404 error 
       abort(404); 
      } else { 
       // level 2 or 3 

       // get parent object 
       $parent_id= $category2->parent_id; 
       $parent = Category::where('id', $parent_id)->first(); 
        if($parent->parent_id == 0){ 
         // level 2 
         return Category::where('name', $value)->first(); 
        } else { 
         // level 3 
         abort(404); 
         return false; 
        } 
      } 

     }); 

     Route::bind('category3', function ($value) { 

      $category3= Category::where('name', $value)->first(); 

      // check if level 1 

      if($category3->parent_id == 0) { 
       // 1st level -> 404 Fehler 
       abort(404); 
      } else { 
       // level 2 or 3 

       // get parent object 
       $parent_id= $category3->parent_id; 
       $parent = Category::where('id', $parent_id)->first(); 
        if($parent->parent_id == 0){ 
         // level 2 
         abort(404); 
         return false; 
        } else { 
         // level 3 
         return Category::where('name', $value)->first(); 
        } 
      } 

     }); 
    } 

想像這樣本地主機/汽車/大衆/高爾夫的最終到達網址。在數據庫中,汽車被定義爲類別1(id = 1,parent_id = 0),大衆汽車被定義爲類別2(id = 2,parent_id = 1)並且高爾夫被定義爲類別3(id = 3,parent_id = 2 )。

EDIT1:

作爲URL圖案爲localhost /類別1 /類別2 /類別3我只能進入汽車作爲1相同的類別的值是有效的大衆作爲第2類和高爾夫球作爲第3類如果我試圖進入其中之一:

  • 本地主機/大衆或
  • 本地主機/高爾夫或
  • 本地主機/汽車/高爾夫

應用程序正在響應404錯誤。這是預期的行爲。 請給我你的意見,以進一步改善。

0

正如已創建三個不同的路線:

Route::get('/{category1}', '[email protected]'); 

Route::get('/{category1}/{category2}', '[email protected]'); 

Route::get('/{category1}/{category2}/{category3}', '[email protected]'); 

每當你傳遞一個參數時,其匹配的路線即將被執行。首先一個,同樣如果傳遞兩個參數發生。

如果你願意,這條路由只能用三個參數工作,刪除前兩條路由並且只保留那條有3個路由參數的路由。

+0

我仍然想要頁面/ category1 /和/ category1/category2 /交付,所以我需要它們嗎?本頁面顯示可用產品的概覽。 – glembo

0

解決問題「問題是如果我在我的瀏覽器中請求本地主機/高爾夫球,服務器會爲我提供頁面。」寫1類這樣的路線,因爲用於組別的PARENT_ID爲0,我們可以寫驗證通過這條路線:

Route::get('category/{category1}', function(App\Category $category1) 
{ 
    if ($category1->parent_id==0) 
    { 
     return (new App\Http\Controllers\CategoryController)->category1($category1); 
    } 

});