3分鐘短文:Laravel slug,讓你的url地址更好記

2020-10-06 程式設計師小助手

引言

網絡資源訪問,路由是多麼重要不消多言了。而友好的url地址更是能讓人一目了然,增加用戶的好感。同時對於爬蟲也是好的示例,搜尋引擎可以友好地展開工作了。

本文就來講講,如何在laravel中構造友好的url路由。

啥是slug?

在早期的網際網路時代,為了在頁面之間傳遞數據,複雜的交互一般都會使用cookie等本地緩存,但是瀏覽器版本的約束,使得伺服器端交互仍然需要即時訪問。所以各種各樣的url地址,帶參數跳轉的,表單提交的,混為一談,製作出符合統一規範的路由很不容易。

比如下面的路由,訪問一個地址,並且攜帶querystring參數:

http://example.com/events.php?id=42

相應地,不同的用戶,這個id也不相同。不同的頁面,也不相同。像這樣帶參傳遞的路由地址,是最為原始的。我們在之前的章節已經使用laravel Route功能,重新構造了url,所以訪問起來像是連貫的:

http://example.com/events/42

直接使用位置參數綁定的方式傳遞。因為數字42對用戶而言沒有實際意義,而對資料庫來說是索引欄位。如果使用如下方式,效果要友好的多:

http://example.com/events/laravel-hacking-and-coffee

這種基於字符串位置參數綁定的URL方式,被稱為 slug。有一個第三方類庫專門用於url的友好化。使用 composer 安裝:

composer require cviebrock/eloquent-sluggable:^4.3

模型引入 Slug 功能

引入 eloquent-sluggable 類庫,只需要在laravel模型文件內引入對應trait,並重載實現sluggable方法:

use Cviebrock\EloquentSluggable\Sluggable;class Event extends Model {    use Sluggable;    public function sluggable()   {        return [            'slug' => [           'source' => 'name'           ]       ];   }}

上述 sluggable 方法指定了,哪個欄位用於slug搜索,(此處是 slug)。以及slug欄位對應的資料庫表的欄位來源,此處是 name 欄位。

接著我們需要修改 events 表,為其追加 slug 欄位。命令行創建遷移文件:

php artisan make:migration add_slug_column_to_events_table --table=events

執行成功返回:

Created Migration: 2020_10_04_225240_add_slug_column_to_events_table

然後手動實現遷移文件的 up 方法:

public function up(){    Schema::table('events', function (Blueprint $table) {   $table->string('slug')->nullable();   });}

以及回滾使用的 down 方法:

public function down(){    Schema::table('events', function (Blueprint $table) {   $table->dropColumn('slug');   });}

在命令行執行遷移成功後,資料庫表events就會追加上slug欄位了。

如果原來資料庫表內已經又生產數據,此時我們需要手動更新一下。使用 tinker 快捷操作:

namespace App;$events = Event::all();foreach($events as $event) {    $event->save();}

數據量不大,我們也不考慮效率不效率的問題了。foreach循環直接用了。


創建基於 slug 的模型查詢

資料庫準備好了,模型準備好了,現在讓我們把slug功能用起來。

如果你有印象的話,應該會記得laravel模型的find等方法,是基於primary key進行索引,以便加快查詢速度。拿到模型的ID,查詢該條目數據,然後返回模型實例。這是基於ID這個integer類型的查詢。

而slug查詢,是基於字符串的,如果要使用slug此功能,需要改寫默認的列名。在模型文件內手動重寫如下方法:

public function getRouteKeyName(){ return 'slug';}

返回字符串,就是查詢所依據的「欄位名」。這樣默認的查詢就不走默認的 $primaryKey = 'id' 這個欄位,而是使用手動指定的 slug欄位了。

當然了,如果沒有使用路由參數綁定,eloquent-sluggable類庫也為我們提供了友好的trait,在模型文件內直接引入就好了:

use Cviebrock\EloquentSluggable\Sluggable;use Cviebrock\EloquentSluggable\SluggableScopeHelpers;class Event extends Model{ use Sluggable, SluggableScopeHelpers;}

從名字你就能猜測的到,SluggableScopeHelpers 是一個全局作用域文件,這是我們上一章所講內容,不再贅述。

完成引入後,在使用模型進行查詢時,就可以這樣使用了:

$event = Event::findBySlug('laravel-hacking-and-coffee');$event = Event::findBySlugOrFail('laravel-hacking-and-coffee');

歸根結底,就是使用slug欄位記錄查詢的字符串,而slug欄位在對應關係中定義為 source => 『name』 欄位,所以SQL查詢仍然是根據slug欄位嚴格匹配約束返回數據集。

數據量大了之後,這種等於的WHERE子句性能必然不如ID欄位的主鍵索引來的快。所以在資料庫層面也同樣需要優化。


寫在最後

本文介紹了在模型文件內,引入slug的功能,並通過修改模型的查詢方式,讓模型的默認查詢方式修改為通過字符串進行查詢,從而可以在路由文件內構造更友好的查詢url。

Happy coding :-)


我是@程式設計師小助手,專注編程知識,圈子動態的IT領域原創作者

相關焦點

  • 3分鐘短文:Laravel路由加模型等於?
    引言上一章我們用3分鐘時間光速入門了laravel控制的用法,本章不準備說控制器了,說一說另外倆模塊,就是路由Route和模型Model代碼時間還是最早我們講的那種方式,在路由地址上通過位置參數綁定,我們可以獲取到用戶輸入的數據。只不過,為了與模型文件對應起來,可以直接在路由處理方法的閉包內調用模型方法,並組裝數據返回。
  • 3分鐘短文:Laravel路由註冊,你必須掌握的「動詞」
    引言無論是web頁面還是API接口,我們都繞不開的是路由地址,網絡資源定位也只能依賴於路由地址,它是銜接網絡請求與應用程式的橋梁。', function ($id = 'fallbackId') { //});不僅於此,你還可以直接在路由上對傳入數據進行有效性判斷,把無效的數據攔截到路由層。
  • 3分鐘短文:Laravel路由註冊,你必須掌握的「動詞」!
    引言無論是web頁面還是API接口,我們都繞不開的是路由地址,網絡資源定位也只能依賴於路由地址,它是銜接網絡請求與應用程式的橋梁。本期為大家說一說用laravel註冊路由的那些必知必會的方法。, function ($id = 'fallbackId') {//});不僅於此,你還可以直接在路由上對傳入數據進行有效性判斷,把無效的數據攔截到路由層。
  • 3分鐘短文:Laravel路子真野啊!路由暱稱前綴中間件
    引言上一章內容我們介紹了使用laravel路由動詞定義方便的url,以及通過url參數綁定傳遞數據, 本文我們繼續深入Route功能,學習一些提升生產力的方法,在現實場景中也非常實用。300到500條,光是管理這些路由地址不重複,或者是瀏覽某些部分的路由, 都將是一件非常考驗腦力的事兒。
  • 3分鐘短文 | Laravel 靈活地獲取當前請求的路由地址
    學習時間在 Laravel 4 中你可以使用系統提供的Route 對象,直接訪問其方法實現:Route::currentRouteName();雖然laravel做了很多努力向下兼容,但是隨著PHP的版本升級, 以及框架的改良,實現同一功能的方法也越來越靈活。
  • 3分鐘短文|Laravel 靈活地獲取當前請求的路由地址
    引言Laravel程序上下文內,我們需要動態地獲取當前的路由地址,應該怎麼寫呢? 本文就通過從 Laravel 4 到 5 及以上版本的實現方法,帶大家重溫這一知識點。學習時間在 Laravel 4 中你可以使用系統提供的 Route 對象,直接訪問其方法實現:Route::currentRouteName();雖然laravel做了很多努力向下兼容,但是隨著PHP的版本升級, 以及框架的改良,實現同一功能的方法也越來越靈活。
  • 3分鐘短文:有面子!Laravel教你簡單寫出專業的API
    laravel提供了簡單的標準方式,可以讓我們遵循最佳實踐寫出專業的url。比如對於資源,使用restful風格聲明一下的url路由地址:第一列是http請求方法,第二列是laravel內聲明的路由規則,第三列是對應的控制器方法。
  • 3分鐘短文:有面子!Laravel教你簡單寫出專業的RestfulAPI
    laravel提供了簡單的標準方式,可以讓我們遵循最佳實踐寫出專業的url。 比如對於資源,使用restful風格聲明一下的url路由地址:第一列是http請求方法,第二列是laravel內聲明的路由規則,第三列是對應的控制器方法。上面的資源列表,涵蓋了增刪改查的所有動作,可以說很全面了。如何快捷地生成上述控制器方法呢?
  • 3分鐘短文:使用Laravel為靜態頁面加點「料」
    此時在瀏覽器內訪問對應url地址,就順利地可以看到 $id 的變量字符的輸出。如果用戶訪問了正確的url並傳參, 那麼在程序的控制器內,就可以直接訪問 $category 和 $subcategory 這倆變量。
  • 3分鐘短文:可能是Laravel模板最直白的用法了,沒有之一
    引言上一期我們通過分配路由地址,在url中接收位置參數並傳遞給控制器方法, 並且在控制器內簡單地列印輸出接收的參數。模板文件的地址在 resources/views/events/show.blade.php,我們追加一行內容:<p>We&{{ $id }}.
  • 3分鐘短文:Laravel跟用戶打交道,從拿他們的數據開始
    本文不會教你規避危險!代碼時間我們在講路由規劃的時候,說了如何使用url的位置參數綁定的方式進行導向,其實那也是一種獲取用戶輸入數據的方式, 只不過,傳入的位置參數一般都人畜無害,公開訪問,任你來來往往。
  • 3分鐘短文:刀刃向內,Laravel緩存測試簡單入門
    打開命令行工具,進入到laravel工作根目錄,運行命令:.laravel使用了Faker庫用於偽數據的生成,我們通過一個工廠方法,實現為每個用戶創建頭像的需求。那麼只需在測試方法中這樣實現:在中間件內實時聲明cookie名不加密,然後請求url
  • 3分鐘短文:太爽了,用Laravel寫API接口
    laravel默認的api接口路由在 routes/api.php 文件內定義,默認的情況下預定義了一個資源類型的api接口,代碼如下:Route::middleware('auth:api')->get('/user', function
  • 3分鐘短文:太爽了,用Laravel寫API接口!
    本期為大家說一說用laravel寫restful風格的API,看看能有多簡單。以路由開端寫API接口,與傳統的渲染前端模板頁面有什麼區別?少了視圖,只需要準備好數據, 並按照規則格式化,返回就可以了。laravel默認的api接口路由在 routes/api.php文件內定義,默認的情況下預定義了一個資源類型的api接口,代碼如下:Route::middleware('auth:api')->get('/user', function (Request $request) {return $request->user();});
  • 3分鐘短文:Laravel控制器用法光速入門
    >本文用最簡單的示例,讓你明白laravel中控制器是幹什麼的,以及怎麼用。接下來,為了這個方法可以被訪問到,需要路由的配合,在 routes/web.php 文件內添加一條路由地址:Route::get('/', 'TasksController@home');編輯完成並保存後,在瀏覽器直接訪問根目錄
  • 3分鐘短文:使用Laravel實現一個最簡單的web靜態頁面
    創建laravel應用首先我們通過命令行安裝laravel應用。為了方便創建,先全局安裝 laravel installer, 在命令行中運行下面的指令:composer global require laravel/installer安裝成功後,laravel 二進位文件就會註冊到環境變量,在命令行中查看安裝是否成功
  • 3分鐘短文:Laravel請求體內JSON格式數據的處理辦法
    解析為關聯數組,輸出內容大概如下:[ { "name": "John", "location": "Boston" }, { "name": "Dave", "location": "Lancaster" }]前端請求數據時,可以採用純手動組裝JSON字符串,然後整體提交的方式:$.ajax({type: "POST", url
  • 3分鐘短文|Laravel命令行調用控制器方法,你會幾個?
    $request = Request::create($this->argument(&39;), &39;);這裡構造的請求體非常靈活,你可以模擬任何有效的請求,地址,方法,參數,等等。然後重點來了,我們使用laravel框架提供的 Container 容器構造一個調用:app()->make(\Illuminate\Contracts\Http\Kernel::class)->handle($request);就醬。為了讓你的命令在laravel生命周期內可被註冊,還需要手動註冊一下。
  • 3分鐘短文:Laravel請求體內JSON格式數據的處理辦法
    解析為關聯數組,輸出內容大概如下:[ { &34;: &34;, &34;: &34; }, { &34;: &34;, &34;: &34; }]前端請求數據時,可以採用純手動組裝JSON字符串,然後整體提交的方式:$.ajax({ type: &34;, url
  • 3分鐘短文:素未謀面,Laravel資料庫模型初階入門
    本期就來講講laravel的模型初階用法。代碼時間模型是在代碼中抽象一層,把資料庫操作提取出來。laravel支持常用的資料庫產品, 我們以MySQL為例。首先在配置文件內,配置參數對資料庫連接。在配置文件 config/database.php 內,默認的配置如下:包括資料庫連接名,資料庫地址,埠,用戶名和密碼,資料庫名等等信息,就完成了初始化配置。