升級說明
升級說明
升級指南
- 從 5.7 升級到 5.8.0
高影響的改變
- 以秒為單位緩存 TTL
- 緩存鎖的安全性改進(jìn)
- Markdown 文件路徑改變
- Nexmo / Slack 通知頻道改變
中等影響的改變
- 容器生成器和標(biāo)簽服務(wù)
- SQLite 版本約束
- 在字符串和數(shù)組方面用類取代 Helpers
- 棄用 Deferred 服務(wù)提供者
- 符合 PSR-16 規(guī)范
- 改進(jìn)不規(guī)則復(fù)數(shù)的模型名稱結(jié)尾
- 自定義中間表模型增加自增 id 屬性
- 支持 Pheanstalk 4.0 庫
從 Laravel 5.7 更新到 5.8
預(yù)計升級時間:1 小時
注:我們試圖記錄每一個可能發(fā)生的變化。因為大部分破壞性的變化在框架的內(nèi)部,這些更改僅有一部分的更改可能影響你的應(yīng)用。
更新依賴
在 composer.json
中,將 laravel/framework
依賴項更新為 5.8.*
。
接下來,檢查應(yīng)用程序中已安裝的第三方包是否支持 Laravel 5.8,并檢查已安裝的版本是否正確。
應(yīng)用契約
environment
方法
影響可能性:非常低
Illuminate/Contracts/Foundation/Application
類 environment
方法的簽名已修改。如果在您的應(yīng)用程序中重寫了這個方法,您應(yīng)該更新此方法的簽名:
/** * 獲取或檢查當(dāng)前應(yīng)用程序的環(huán)境 * * @param string|array $environments * @return string|bool */public function environment(...$environments);
新添加的方法
影響可能性:非常低
以下新添加方法 bootstrapPath
, configPath
, databasePath
, environmentPath
, resourcePath
, storagePath
, resolveProvider
, bootstrapWith
, configurationIsCached
, detectEnvironment
, environmentFile
, environmentFilePath
, getCachedConfigPath
, getCachedRoutesPath
, getLocale
, getNamespace
, getProviders
, hasBeenBootstrapped
, loadDeferredProviders
, loadEnvironmentFrom
, routesAreCached
, setLocale
, shouldSkipMiddleware
, terminate
將會被添加到 Illuminate/Contracts/Foundation/Application
中.
如果你實(shí)現(xiàn)了這個接口,你應(yīng)該將這些方法添加到實(shí)現(xiàn)類中。
認(rèn)證
重置密碼通知路由參數(shù)
影響可能性:低
當(dāng)用戶點(diǎn)擊重置密碼鏈接時,Laravel 使用 route
助手生成 URL ,以創(chuàng)建指向以 password.reset
命名的路由,當(dāng)使用 Laravel 5.7 的時候,token 將會被傳遞到不帶顯式名稱的 route
助手,比如:
route('password.reset', $token);
當(dāng)你使用 Laravel 5.8 時,token 作為顯式參數(shù)傳遞給 route
助手:
route('password.reset', ['token' => $token]);
因此,如果你要定義自己的 password.reset
路由,則它的 uri 中一定要包含一個 token 參數(shù)。
默認(rèn)密碼長度改變
影響可能性:低
選擇或重置密碼時所需的密碼長度 更改為至少八個字符 。
緩存
TTL 以秒為單位
影響可能性:非常高
為了在存儲數(shù)據(jù)時允許更精細(xì)的到期時間,緩存數(shù)據(jù)的生存時間從分改為秒。 Illuminate\Cache\Repository
類和它的擴(kuò)展類的 put
, putMany
, add
, remember
和 setDefaultCacheTime
方法,以及所有緩存存儲器的 put
方法都完成了此更新。詳情請看 相關(guān)的 PR 。
如果要向這些方法中的任何一個傳遞整數(shù),請更新代碼以確保保留在緩存中的數(shù)據(jù)傳遞的數(shù)值是秒。另外,你可以傳遞一個 DateTime
實(shí)例指示數(shù)據(jù)何時到期:
// Laravel 5.7 - 存儲數(shù)據(jù)30分鐘 Cache::put('foo', 'bar', 30);// Laravel 5.8 - 存儲數(shù)據(jù)30秒 Cache::put('foo', 'bar', 30);// Laravel 5.7 / 5.8 - 存儲數(shù)據(jù)30秒 Cache::put('foo', 'bar', now()->addSeconds(30));
{提示} 此更改使 Laravel 緩存系統(tǒng)完全符合 PSR-16 緩存庫標(biāo)準(zhǔn) 。
遵循 PSR-16
影響可能性:中等
除了以上返回值有變化之外,本次升級還更新了 Illuminate\Cache\Repository
類中的 put
, putMany
和 add
方法的 TTL 參數(shù),使之更符合 PSR-16 規(guī)范。新特性提供了一個默認(rèn)的 null
,所以如果不指定 TTL 值,那么緩存將會永久存儲不會過期。此外,如果緩存項的 TTL 為 0 或者更小,那么將會被清除。參閱 相關(guān)的 PR 獲取更多信息。
KeyWritten
事件基于這些變動 也進(jìn)行了更新 。
鎖安全性改善
影響可能性:高
在 Laravel 5.7 以及 Laravel 更早的版本的中,一些緩存驅(qū)動提供的 “原子鎖” 特性,可能由于一些意外行為導(dǎo)致鎖被提前釋放。
例如: 客戶端 A 獲取了一個 10 秒過期的鎖 foo
。客戶端 A 實(shí)際上需要耗費(fèi) 20 秒來完成它的任務(wù)。在客戶端 A 任務(wù)執(zhí)行期間,鎖被緩存系統(tǒng)自動釋放。之后 客戶端 B 獲取到鎖 foo
。最終 客戶端 A 完成了它的任務(wù)并釋放掉鎖 foo
,但是無意中釋放了 客戶端 B 所持有的鎖。這時候 客戶端 C 又可以獲取到鎖。
為了緩解這種情況,現(xiàn)在使用嵌入的「范圍令牌」生成鎖,這樣可以確保在正常情況下,只有鎖的持有者才能釋放鎖。
如果你正在使用 Cache::lock()->get(Closure)
方法使用鎖,則不需要進(jìn)行任何更改:
Cache::lock('foo', 10)->get(function () { // 鎖將會被安全的自動釋放});
但是,如果要手動調(diào)用, Cache::lock()->release()
,則必須更新代碼以維護(hù)鎖的實(shí)例。然后,在完成任務(wù)后,可以在同一個鎖實(shí)例上調(diào)用 release
方法。例如:
if (($lock = Cache::lock('foo', 10))->get()) { // 執(zhí)行任務(wù)… $lock->release();}
有時,您可能希望在一個進(jìn)程中獲取鎖定并在另一個進(jìn)程中釋放它。例如,您可以在 Web 請求期間獲取鎖定,并希望在該請求觸發(fā)的排隊作業(yè)結(jié)束時釋放鎖定。在這種情況下,您應(yīng)該將鎖定的作用域「owner token」傳遞給排隊的作業(yè),以便作業(yè)可以使用給定的令牌重新實(shí)例化鎖:
// 在控制器中…$podcast = Podcast::find(1); if (($lock = Cache::lock('foo', 120))->get()) { ProcessPodcast::dispatch($podcast, $lock->owner());}// 在進(jìn)程廣播隊列中… Cache::restoreLock('foo', $this->owner)->release();
如果您想在不尊重其當(dāng)前所有者的情況下釋放鎖定,您可以使用以下 forceRelease
方法:
Cache::lock('foo')->forceRelease();
Repository
和 Store
契約
影響可能性:非常低
為了完全符合 PSR-16
的要求,Illuminate\Contracts\Cache\Repository
契約的 put
和 forever
方法的返回值以及 Illuminate\Contracts\Cache\Store
契約的 put
, putMany
和 forever
方法 已更改 從 void
到 bool
。
集合
firstWhere
方法
影響可能性:非常低
firstWhere
方法參數(shù) 已更改 匹配 where
方法的簽名。如果要重寫此方法,則應(yīng)更新方法的參數(shù)來匹配其父級:
/** * Get the first item by the given key value pair. * * @param string $key * @param mixed $operator * @param mixed $value * @return mixed */public function firstWhere($key, $operator = null, $value = null);
終端
Kernel
契約
影響可能性:非常低
terminate
方法 已經(jīng)添加到 Illuminate/Contracts/Console/Kernel
契約中。如果你實(shí)現(xiàn)了這個接口,則應(yīng)該將這個方法添加到實(shí)現(xiàn)類中。
容器
生成器 & 標(biāo)記服務(wù)
影響可能性:中等
容器的 tagged
方法使用 PHP 生成器通過給定的標(biāo)記惰性地實(shí)例化服務(wù)。由于這種改變,tagged
方法返回 iterable
類型,而不是 數(shù)組
。如果你這個方法使用了類型提示的返回值,則應(yīng)確保將類型提示也更改為 iterable
類型。
另外,不能再通過數(shù)組偏移值直接訪問標(biāo)記服務(wù) ,比如 $container->tagged('foo')[0]
。
resolve
方法
影響可能性:非常低
resolve
方法 接收一個新布爾參數(shù),該參數(shù)指示事件在對象實(shí)例化期間是否應(yīng)觸發(fā) / 執(zhí)行(解析回調(diào))。如果你重寫了這個方法,你必須更新方法簽名以匹配父方法。
addContextualBinding
方法
影響可能性:非常低
Illuminate\Contracts\Container\Container
契約增加了 addContextualBinding
方法。如果要實(shí)現(xiàn)此接口,則應(yīng)將此方法加到你的實(shí)現(xiàn)中。
tagged
方法
影響可能性:低tagged
方法現(xiàn)在 改為 返回 iterable
類型而不是 array
類型。如果你的代碼參數(shù)有類型提示,找到所有 tagged
方法提示 array
類型的地方,將類型提示改為 iterable
類型。
flush
方法
影響可能性:非常低
Illuminate\Contracts\Container\Container
契約增加了 flush
方法。如果要實(shí)現(xiàn)此接口,則應(yīng)將此方法加到你的實(shí)現(xiàn)中。
數(shù)據(jù)庫
未被引號包圍的 MySQL JSON 值
影響可能性:低
在使用 MySQL 和 MariaDB 的時候,Query 構(gòu)造器返回的 JSON 值將不會使用引號包圍。其他數(shù)據(jù)庫將和這里的行為保持一致:
$value = DB::table('users')->value('options->language'); dump($value); // Laravel 5.7... '"en"' // Laravel 5.8... 'en'
因此,不再支持或不再需要 ->>
操作符了。
SQLite
影響可能性:中等
從 Laravel 5.8 開始, 最早版本 SQLite 支持 一直到 SQLite 3.7.11。如果你使用的是更早之前的 SQLite 版本,你應(yīng)該升級 (推薦升級到 SQLite 3.8.8+)。
Eloquent
模型命名中的不規(guī)則復(fù)數(shù)結(jié)尾
影響可能性:中等
從 Laravel 5.8 起,含有不規(guī)則復(fù)數(shù)形式結(jié)尾的復(fù)合名稱模型命名 現(xiàn)在可以正確的進(jìn)行復(fù)數(shù)化.
// Laravel 5.7... App\Feedback.php -> feedback (正確的復(fù)數(shù)形式) App\UserFeedback.php -> user_feedbacks (錯誤的復(fù)數(shù)形式) // Laravel 5.8 App\Feedback.php -> feedback (正確的復(fù)數(shù)形式) App\UserFeedback.php -> user_feedback (正確的復(fù)數(shù)形式)
如果你的模型名稱沒有正確的使用復(fù)數(shù)名稱,你在模型中定義 $table
屬性之后還是可以繼續(xù)使用它的:
/** * 與模型關(guān)聯(lián)的數(shù)據(jù)表名稱。 * * @var string */protected $table = 'user_feedbacks';
帶有遞增 ID 的自定義中繼模型
如果你用一個自定義的中繼模型定義了多對多的關(guān)系,而且這個中繼模型擁有一個自增的主鍵,你應(yīng)當(dāng)確保這個自定義中繼模型類中定義了一個 incrementing
屬性其值為 true
:
/** * 標(biāo)識 ID 是否自增 * * @var bool */public $incrementing = true;
loadCount
方法
影響可能性:低
基礎(chǔ)類 Illuminate\Database\Eloquent\Model
中添加了 loadCount
方法。如果你的應(yīng)用中也定義了 loadCount
方法,可能會和 Eloquent 中的相沖突。
originalIsEquivalent
方法
影響可能性:非常低
Illuminate\Database\Eloquent\Concerns\HasAttributes
trait 中的 originalIsEquivalent
成員方法從 protected
改變?yōu)?public
。
deleted_at
屬性的自動軟刪除轉(zhuǎn)換
影響可能性:低
當(dāng)你的 Eloquent 模型使用了 Illuminate\Database\Eloquent\SoftDeletes
trait 時 deleted_at
成員屬性 現(xiàn)將會自動轉(zhuǎn)換 成為一個 Carbon
實(shí)例。你可以重寫這個行為,通過為該成員屬性編寫你的自定義 accessor 或者手動將它添加到 casts
屬性中:
protected $casts = ['deleted_at' => 'string'];
BelongsTo
的 getForeignKey
方法
影響可能性:低
BelongsTo
關(guān)聯(lián)關(guān)系中的 getForeignKey
和 getQualifiedForeignKey
方法已分別重命名為 getForeignKeyName
和 getQualifiedForeignKeyName
,使得方法名和在 Laravel 提供的其他關(guān)聯(lián)關(guān)系中保持一致。
事件
fire
方法
影響可能性:低
Illuminate/Events/Dispatcher
類中的 fire
方法 (在 Larevel 5.4 中不贊成使用) 已經(jīng)被 移除 了。
你應(yīng)當(dāng)使用它的替代方法 dispatch
。
異常處理器
ExceptionHandler
契約
影響可能性:低
Illuminate\Contracts\Debug\ExceptionHandler
契約中新增了 shouldReport
方法。 現(xiàn)在當(dāng)你實(shí)現(xiàn)異常處理器的接口時,你需要同時實(shí)現(xiàn)此方法。
renderHttpException
方法
影響可能性:低
Illuminate\Foundation\Exceptions\Handler
類中 renderHttpException
方法的簽名 有改動 。現(xiàn)在如果你在異常處理器中重寫此方法,應(yīng)當(dāng)修改方法的簽名以和其父類保持一致:
/** * 將給定的 Http 異常轉(zhuǎn)換為 Http 響應(yīng)。 * * @參數(shù) \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface $e * @返回 \Symfony\Component\HttpFoundation\Response */protected function renderHttpException(HttpExceptionInterface $e);
Facades
Facade 服務(wù)解析
影響可能性:低
getFacadeAccessor
方法現(xiàn)在可以 只返回代表服務(wù)容器標(biāo)識的字符串 ,之前該方法會返回一個對象實(shí)例。
郵件
Markdown 文件路徑更改
影響可能性:高
如果你已經(jīng)使用 vendor:publish
命令發(fā)布了 Laravel 的 Markdown 郵件組件,你需要將 /resources/views/vendor/mail/markdown
路徑重命名為 text
。
并且 markdownComponentPaths
方法 已被重命名 為 textComponentPaths
。如果你要重寫這個方法,你應(yīng)該更新方法名,使之與其父類一致。
PendingMail
類中的方法形參改變
影響可能性:非常低
Illuminate\Mail\PendingMail
類中的 send
, sendNow
, queue
, later
和 fill
方法 已被更改 為需接收一個 Illuminate\Contracts\Mail\Mailable
實(shí)例作為參數(shù),而不是 Illuminate\Mail\Mailable
實(shí)例。如果你要重寫其中的方法,你需要更新其形參,和其父類保持一致。
隊列
Pheanstalk 4.0
影響可能性:中
Laravel 5.8 提供了支持 ~4.0
發(fā)布版本的 Pheanstalk 隊列。如果你正在應(yīng)用中使用 Pheanstalk 庫,請通過 Composer 升級你的庫到 ~4.0
發(fā)布版本。
Job
契約
影響可能性:非常低
isReleased
, hasFailed
和 markAsFailed
方法 已被加入到 Illuminate\Contracts\Queue\Job
契約中 。如果你正在實(shí)現(xiàn)這個 interface ,你應(yīng)該添加這些方法到你的實(shí)現(xiàn)代碼中。
Job::failed
& FailingJob
類
影響可能性:非常低
在 Laravel 5.7 中,當(dāng)一個隊列任務(wù)失敗后,隊列 worker 將執(zhí)行 FailingJob::handle
方法。在 Laravel 5.8 中,FailingJob
類中的邏輯已被遷移到了 fail
方法中,該方法就定義在這個任務(wù)類中。正因如此, fail
方法被納入了 Illuminate\Contracts\Queue\Job
契約。
Illuminate\Queue\Jobs\Job
基類包含了 fail
的實(shí)現(xiàn),在常規(guī)的應(yīng)用里不需要改任何代碼。然而,如果你正在搭建自定義的隊列驅(qū)動,起了一個任務(wù)類,該任務(wù)類 沒有 繼承由 Laravel 提供的任務(wù)基類,你應(yīng)該在你自定義的任務(wù)類中手動實(shí)現(xiàn) fail
方法。作為實(shí)現(xiàn)的參考,你可以查閱 Laravel 的任務(wù)基類。
這個改變允許定制隊列驅(qū)動,從而在對任務(wù)刪除過程獲得更多的控制。
Redis Blocking Pop
影響可能性:非常低
現(xiàn)在使用 Redis 隊列驅(qū)動的 「blocking pop」特性是安全的。在之前,如果 Redis 服務(wù)或者 worker 掉線的同時取出任務(wù),可能造成隊列中的任務(wù)丟失(小概率事件)。 為了讓 blocking pops 變得安全,將給每一個 Laravel 隊列創(chuàng)建一個新的帶有 :notify
后綴的 Redis list 。
請求
TransformsRequest
中間件
影響可能性:低
現(xiàn)在,當(dāng)請求輸入是一個數(shù)組時, Illuminate\Foundation\Http\Middleware\TransformsRequest
中間件的 transform
方法將接收到「全限定」 請求輸入的 key :
'employee' => [ 'name' => 'Taylor Otwell',],/** * 轉(zhuǎn)換給定的值. * * @param string $key * @param mixed $value * @return mixed */protected function transform($key, $value){ dump($key); // 'employee.name' (Laravel 5.8) dump($key); // 'name' (Laravel 5.7)}
路由
UrlGenerator
協(xié)議
影響可能性:非常低
previous
方法 已經(jīng)添加到 Illuminate\Contracts\Routing\UrlGenerator
contract 中。如果要調(diào)用這個接口,你應(yīng)該將這個方法添加到你的實(shí)現(xiàn)中。
Illuminate/Routing/UrlGenerator
中的 cachedSchema
特性
影響可能性:非常低
Illuminate/Routing/UrlGenerator
中的 $cachedSchema
屬性 (在 Laravel 5.7 中已被棄用) 已更改為 $cachedScheme
。
Sessions
StartSession
中間件
影響可能性:非常低
Session 的持久性邏輯已 從 terminate()
方法移動到 handle()
方法。 如果你要重寫其中的方法, 則應(yīng)該更新它們以反映這些更改。
Support
優(yōu)先使用字符串和數(shù)組類而不是輔助函數(shù)
影響可能性:中等
所有的 array_*
and str_*
全局輔助函數(shù) 都被廢棄。你需要直接使用 Illuminate\Support\Arr
和 Illuminate\Support\Str
提供的方法。
這個調(diào)整的影響被標(biāo)記為中等,因為這些輔助函數(shù)被轉(zhuǎn)移到新的 laravel/helpers 擴(kuò)展包中,以便更好地向后兼容。
延遲的服務(wù)提供者
影響可能性:中等
服務(wù)提供程序的用于指示是否延遲提供程序的 defer
布爾屬性已經(jīng)被廢棄。現(xiàn)在如果要將服務(wù)提供者標(biāo)記為延遲的需要通過實(shí)現(xiàn) Illuminate\Contracts\Support\DeferrableProvider
契約來完成。
測試
PHPUnit 8
影響可能性:可選
默認(rèn)情況下, Laravel 5.8 使用 PHPUnit 7.。不過, 你可以升級到 PHPUnit 8,但是這需要 PHP >= 7.2。更多細(xì)節(jié)請閱讀 PHPUnit 8 版本聲明。
setUp
和 tearDown
方法現(xiàn)在要求返回 void 類型:
protected function setUp(): voidprotected function tearDown(): void
驗證
Validator
契約
影響可能性:非常低
Illuminate\Contracts\Validation\Validator
中 新增了 validated
方法:
/** * 獲取已驗證的屬性和值。 * * @return array */public function validated();
如果你調(diào)用了這個接口,需要添加此方法的實(shí)現(xiàn)。
ValidatesAttributes
特性
影響可能性:非常低
Illuminate\Validation\Concerns\ValidatesAttributes
特性中的 parseTable
、 getQueryColumn
和 requireParameterCount
方法可見性從 protected
調(diào)整為了 public
。
DatabasePresenceVerifier
類
影響可能性:非常低
Illuminate\Validation\DatabasePresenceVerifier
類的 table
方法可見性從 protected
調(diào)整為了 public
。
Validator
類
影響可能性:非常低
Illuminate\Validation\Validator
類的 getPresenceVerifierFor
方法可見性從 protected
調(diào)整為了 public
。
郵箱驗證
影響可能性:非常低
郵箱驗證規(guī)則現(xiàn)在回檢測郵箱地址是否兼容 RFC5630, 使驗證邏輯和 SwiftMailer 保持一致。在 Laravel 5.7, email
規(guī)則只驗證郵箱地址是否兼容 RFC822。
因此 當(dāng)使用 Laravel 5.8 時,之前認(rèn)為無效的郵箱地址現(xiàn)在將被視為有效,如 (e.g hej@b?r.se
)。 通常,這被看做一個 bug 修復(fù); 不過, 我們還是將其列到這里給你一個提醒。如果您遇到有關(guān)此更改的任何問題,請通知我們。
視圖
getData
方法
影響可能性:非常低
Illuminate\Contracts\View\View 契約中新增了 getData
方法。如果你調(diào)用了這個接口, 則需要添加該方法的實(shí)現(xiàn)。
通知
Nexmo / Slack 通知頻道
影響可能性:高
Nexmo 和 Slack 通知頻道已經(jīng)被提前到官方擴(kuò)展中。要在自己的應(yīng)用中使用這些頻道,需要安裝以下擴(kuò)展包:
composer require laravel/nexmo-notification-channel composer require laravel/slack-notification-channel
其他
我們還鼓勵你查看 laravel/laravel
代碼倉庫的更新日志。盡管其中的很多更新不是必須的,但是你可以將你的應(yīng)用中的這些文件與代碼倉庫保持同步。其中一些更新已經(jīng)在這篇升級指南中提到了,但是還有很多其他的小更新(如對配置文件或注釋的更改)就不會列出。你可以通過 GitHub 比較工具 查看哪些更新對你而言更加重要。