升級說明
- 升級指南
從5.7 升級到5.8.0
- 高影響的改變以秒為單位快取TTL快取鎖定的安全性改進Markdown 檔案路徑改變
- 中等影響的改變容器產生器與標籤服務SQLite 版本限制在字串和陣列方面用類別取代Helpers棄用Deferred 服務提供者#符合PSR-16 規範改進不規則複數的模型名稱結尾
- 自訂中間表模型增加自增id 屬性
從 Laravel 5.7 更新到 5.8
預計升級時間:1 小時
:我們試著記錄每一個可能發生的變化。因為大部分破壞性的變化在框架的內部,這些變更僅有一部分的變更可能會影響你的應用。
更新依賴
在composer.json
中,將laravel/framework
依賴項更新為5.8.*
。
接下來,檢查應用程式中已安裝的第三方套件是否支援 Laravel 5.8,並檢查已安裝的版本是否正確。
應用契約
environment
方法
#影響可能性:非常低
##Illuminate /Contracts/Foundation/Application 類別
environment 方法的簽章已修改。如果在您的應用程式中重寫了這個方法,您應該更新此方法的簽章:
/** * 获取或检查当前应用程序的环境 * * @param string|array $environments * @return string|bool */public function environment(...$environments);新加入的方法
影響可能性:非常低
以下新新增方法bootstrapPath,
configPath,
databasePath,
environmentPath,
resourcePath,
storagePath,
resolveProvider,
bootstrapWith,
configurationIsCached,
detectEnvironment,
environmentFile,
detectEnvironment,
environmentFile,
environmentFilePath,
getCachedConfigPath,
getCachedRoutesPath,
getLocale,
getNamespace,
getProviders,
hasBeenBootstrappedspace,
getProviders,
hasBeenBootstrappedspace,
getProviders,
hasBeenBootstrappedspace,
getProviders,
hasBeenBootstrappedspace
getProviders
,hasBeenBootstrappedspace
,##,
loadDeferredProviders, loadEnvironmentFrom,
routesAreCached, setLocale
, shouldSkipMiddleware
, # 將會被加入到
Illuminate/Contracts/Foundation/Application
如果你實作了這個接口,你應該將這些方法加入實作類別。
重設密碼通知路由參數
影響可能性:低
當使用者點擊重設密碼連結時,Laravel 使用route
助手產生URL ,以建立指向以password.reset
命名的路由,當使用Laravel 5.7 的時候,token 將會被傳遞到不帶明確名稱的route
助手,例如:route('password.reset', $token);
當你使用Laravel 5.8 時,token 作為明確參數傳遞給route 助手:
route('password.reset', ['token' => $token]);因此,如果你要定義自己的###password.reset### 路由,則它的uri 中一定要包含一個token 參數。 ######預設密碼長度改變#########影響可能性:低##########選擇或重設密碼時所需的密碼長度變更為至少八個字元。 ######快取######TTL 以秒為單位#########影響可能性:非常高#######
為了在儲存資料時允許更精細的到期時間,快取資料的生存時間從分改為秒。 Illuminate\Cache\Repository
類別和它的擴充類別的 put
, putMany
, add
, #remember
和setDefaultCacheTime
方法,以及所有快取記憶體的put
方法都完成了此更新。詳情請看 相關的 PR 。
如果要向這些方法中的任何一個傳遞整數,請更新程式碼以確保保留在快取中的資料傳遞的數值是秒。另外,你可以傳遞一個 DateTime
實例指示資料何時到期:
// Laravel 5.7 - 存储数据30分钟 Cache::put('foo', 'bar', 30);// Laravel 5.8 - 存储数据30秒 Cache::put('foo', 'bar', 30);// Laravel 5.7 / 5.8 - 存储数据30秒 Cache::put('foo', 'bar', now()->addSeconds(30));
{提示} 此變更使 Laravel 快取系統完全符合 PSR-16 快取庫標準 。
遵循PSR-16
影響可能性:中等
除了上述回傳值有變化之外,本次升級也更新了Illuminate\Cache\Repository
類別中的 put
,putMany
和add
方法的TTL 參數,使之更符合PSR-16規範。新功能提供了一個預設的 null
,所以如果不指定 TTL 值,那麼快取將會永久儲存不會過期。此外,如果快取項目的 TTL 為 0 或更小,那麼將會被清除。請參閱 相關的 PR 以獲取更多資訊。
KeyWritten
事件基於這些變動 也進行了更新 。
鎖定安全性改善
影響可能性:高
#在Laravel 5.7 以及Laravel 更早的版本的中,一些快取驅動提供的「原子鎖」 特性,可能由於一些意外行為導致鎖被提前釋放。
例如: 客戶端 A 取得了一個 10 秒過期的鎖定 foo
。 客戶端 A 實際上需要耗費 20 秒來完成它的任務。在客戶端 A 任務執行期間,鎖定被快取系統自動釋放。之後 客戶端 B 取得到鎖定 foo
。最終 客戶端 A 完成了它的任務並釋放掉鎖定 foo
,但無意中釋放了 客戶端 B 所持有的鎖定。這時候 客戶端 C 又可以取得到鎖定。
為了緩解這種情況,現在使用嵌入的「範圍令牌」產生鎖,這樣可以確保在正常情況下,只有鎖的持有者才能釋放鎖。
如果你正在使用Cache::lock()->get(Closure)
方法使用鎖,則不需要進行任何更改:
Cache::lock('foo', 10)->get(function () { // 锁将会被安全的自动释放});
但是,如果若要手動調用, Cache::lock()->release()
,則必須更新程式碼以維護鎖定的實例。然後,在完成任務後,可以在同一個鎖定實例上呼叫 release
方法。例如:
if (($lock = Cache::lock('foo', 10))->get()) { // 执行任务… $lock->release();}
有時,您可能希望在一個進程中取得鎖定並在另一個進程中釋放它。例如,您可以在 Web 要求期間取得鎖定,並希望在該要求觸發的排隊作業結束時釋放鎖定。在這種情況下,您應該將鎖定的作用域「owner token」傳遞給排隊的作業,以便作業可以使用給定的令牌重新實例化鎖定:
// 在控制器中…$podcast = Podcast::find(1); if (($lock = Cache::lock('foo', 120))->get()) { ProcessPodcast::dispatch($podcast, $lock->owner());}// 在进程广播队列中… Cache::restoreLock('foo', $this->owner)->release();
如果您想在不尊重其目前擁有者的情況下釋放鎖定,您可以使用以下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
方法參數已變更符合where
方法的簽章。如果要重寫此方法,則應更新方法的參數以符合其父級:
/** * 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
方法已經加入到
Illuminate/Contracts/Console/Kernel 契約中。如果你實作了這個接口,則應該將這個方法加入實作類別。
容器
影響可能性:中等
容器的
tagged
方法使用PHP 生成器透過給定的標記惰性地實例化服務。由於這個改變,tagged 方法傳回 iterable
類型,而不是陣列。如果你這個方法使用了類型提示的回傳值,則應確保將類型提示也改為
iterable
另外,不能再透過陣列偏移值直接存取標記服務 ,例如
$container->tagged('foo')[0]
。 resolve
方法影響可能性:非常低
tagged
方法
影響可能性:低tagged
方法現在改為傳回iterable
#類型而不是array
類型。如果你的程式碼參數有型別提示,找到所有 tagged
方法提示 array
類型的地方,將型別提示改為 iterable
型別。
flush
方法
影響可能性:非常低
Illuminate\Contracts\Container\Container
契約增加了flush
方法。如果要實作此接口,則應將此方法加到你的實作中。
資料庫
未被引號包圍的MySQL JSON 值
#影響可能性:低
在使用MySQL 和MariaDB 的時候,Query 建構器傳回的JSON 值將不會使用引號包圍。其他資料庫將會和這裡的行為保持一致:
$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 版本,你應該升級 (推薦升級到 SQLite 3.8.8 )。
Eloquent
模型命名中的不規則複數結尾
#影響可能性:中
從Laravel 5.8 起,含有不規則複數形式結尾的複合名稱模型命名現在可以正確的進行複數化.
// Laravel 5.7... App\Feedback.php -> feedback (正确的复数形式) App\UserFeedback.php -> user_feedbacks (错误的复数形式) // Laravel 5.8 App\Feedback.php -> feedback (正确的复数形式) App\UserFeedback.php -> user_feedback (正确的复数形式)
如果你的模型名稱沒有正確的使用複數名稱,你在模型中定義$table
屬性之後還是可以繼續使用它的:
/** * 与模型关联的数据表名称。 * * @var string */protected $table = 'user_feedbacks';
帶有遞增ID 的自訂中繼模型
如果你用一個自訂的中繼模型定義了多對多的關係,而這個中繼模型擁有一個自增的主鍵,你應該確保這個自訂中繼模型類別中定義了一個incrementing
屬性其值為true
:
/** * 标识 ID 是否自增 * * @var bool */public $incrementing = true;
loadCount
方法
影響可能性:低
基礎類別Illuminate\Database\Eloquent\Model
中添加了loadCount
方法。如果你的應用程式中也定義了 loadCount
方法,可能會和 Eloquent 中的相衝突。
originalIsEquivalent
方法
影響可能性:非常低
Illuminate\Database\Eloquent\Concerns\HasAttributes
trait 中的originalIsEquivalent
成員方法從protected
改變為public
。
deleted_at
屬性的自動軟刪除轉換
#影響可能性:低
當你的 Eloquent 模型使用了 Illuminate\Database\Eloquent\SoftDeletes
trait 時 deleted_at
成員屬性 現將會自動轉換 成為一個 Carbon
實例。你可以重寫這個行為,透過為該成員屬性編寫你的自訂accessor 或手動將它新增到casts
屬性:
protected $casts = ['deleted_at' => 'string'];
BelongsTo
的getForeignKey
方法
影響可能性:低
BelongsTo
關聯關係中的getForeignKey
和getQualifiedForeignKey
方法已分別重新命名為getForeignKeyName
和getQualifiedForeignKeyName
,使得方法名稱和在Laravel 提供的其他關聯關係中保持一致。
事件
fire
##影響可能性:低
#影響可能性:低
# Illuminate/Events/Dispatcher 類別中的
fire
方法(在Larevel 5.4 中不贊成使用) 已經被移除了。 你應該使用它的替代方法 dispatch 。
異常處理器ExceptionHandler
契約
#影響可能性:低
##Illuminate \Contracts\Debug\ExceptionHandler 契約中新增了shouldReport
方法。現在當你實作異常處理器的介面時,你需要同時實作此方法。renderHttpException
方法
影響可能性:低
Illuminate\Foundation\Exceptions\Handler#類別中renderHttpException
方法的簽章有改動。現在如果你在例外處理器中重寫此方法,應當修改方法的簽章以與其父類別保持一致:/** * 将给定的 Http 异常转换为 Http 响应。 * * @参数 \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface $e * @返回 \Symfony\Component\HttpFoundation\Response */protected function renderHttpException(HttpExceptionInterface $e);
Facades
Facade 服務解析getFacadeAccessor 方法現在可以只傳回代表服務容器識別的字串,之前該方法會傳回一個物件實例。
郵件Markdown 檔案路徑變更
影響可能性:高
如果你已經使用
##影響可能性:高
如果你已經使用 vendor:publish
指令發布了Laravel 的Markdown 郵件元件,你需要將
/resources/views/vendor/mail/markdown路徑重新命名為text 。
###並且 ###markdownComponentPaths### 方法 已重新命名 為 ###textComponentPaths### 。如果你要重寫這個方法,你應該更新方法名,使其與其父類別一致。 #########PendingMail### 類別中的方法形參改變##########影響可能性:非常低######Illuminate\Mail\PendingMail
類別中的 send
,sendNow
, queue
,later
和fill
方法已更改為需接收一個Illuminate\Contracts\Mail\Mailable
實例作為參數,而不是Illuminate\Mail\Mailable
實例。如果你要重寫其中的方法,你需要更新其形參,和其父類別保持一致。
佇列
Pheanstalk 4.0
影響可能性:中
Laravel 5.8 提供了支援~4.0
發布版本的Pheanstalk 隊列。如果你正在應用程式中使用 Pheanstalk 函式庫,請透過 Composer 升級你的函式庫到 ~4.0
發佈版本。
Job
契約
影響可能性:非常低
isReleased
#hasFailed
和markAsFailed
方法已加入到Illuminate\Contracts\Queue\Job
契約中。如果你正在實作這個 interface ,你應該加入這些方法到你的實作程式碼。
Job::failed
& FailingJob
類別
影響可能性:非常低
在Laravel 5.7 中,當一個佇列任務失敗後,佇列worker 會執行FailingJob::handle
方法。在 Laravel 5.8 中,FailingJob
類別中的邏輯已被移轉到了 fail
方法中,該方法就定義在這個任務類別中。正因如此, fail
方法被納入了 Illuminate\Contracts\Queue\Job
契約。
Illuminate\Queue\Jobs\Job
基底類別包含了 fail
的實現,在常規的應用程式裡不需要改變任何程式碼。然而,如果你正在搭建自定義的隊列驅動,起了一個任務類,該任務類沒有 繼承由Laravel 提供的任務基類,你應該在你自定義的任務類中手動實現fail
方法。作為實作的參考,你可以查閱 Laravel 的任務基底類別。
這個改變允許自訂佇列驅動,從而在對任務刪除過程中獲得更多的控制。
Redis Blocking Pop
影響可能性:非常低
現在使用 Redis 佇列驅動的 “blocking pop”特性是安全的。在之前,如果 Redis 服務或 worker 斷線的同時取出任務,可能會造成佇列中的任務遺失(小機率事件)。為了讓 blocking pops 變得安全,將為每一個 Laravel 佇列建立一個新的帶有 :notify
字尾的 Redis list 。
請求
TransformsRequest
# 中介軟體
影響可能性:低
現在,當請求輸入是一個陣列時, Illuminate\Foundation\Http\Middleware\TransformsRequest
中間件的transform
方法將接收到「全限定」 請求輸入的key :
'employee' => [ 'name' => 'Taylor Otwell',],/** * 转换给定的值. * * @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
協定
影響可能性:非常低
#previous
方法 已經加入到 Illuminate\Contracts\Routing\UrlGenerator
contract 中。如果要呼叫這個接口,你應該將這個方法加入你的實作中。
Illuminate/Routing/UrlGenerator
中的 cachedSchema
特性
##影響可能性:很低
#Illuminate/Routing/UrlGenerator 中的
$cachedSchema 屬性(在Laravel 5.7 中已被棄用) 已更改為
$cachedScheme。
StartSession 中間件
影響可能性:非常低
Session 的持久性邏輯已從terminate() 方法移至
handle() 方法。如果你要重寫其中的方法, 則應該更新它們以反映這些變更。
#影響可能性:中等##所有的
array_* and str_*
全域輔助函數都被廢棄。你需要直接使用 Illuminate\Support\Arr
和 Illuminate\Support\Str
提供的方法。 這個調整的影響被標記為中等,因為這些輔助函數被轉移到新的 laravel/helpers 擴充包中,以便更好地向後相容。
延遲的服務提供者
影響可能性:中等服務提供者的用於指示是否延遲提供者的
defer 布爾屬性已經被廢棄。現在如果要將服務提供者標記為延遲的需要透過實作 Illuminate\Contracts\Support\DeferrableProvider
契約來完成。 測試
PHPUnit 8
影響可能性:可選預設情況下, Laravel 5.8 使用 PHPUnit 7.。不過, 你可以升級到 PHPUnit 8,但這需要 PHP >= 7.2。更多細節請閱讀 PHPUnit 8 版本聲明。
setUp 和tearDown
方法現在要求傳回void 類型:
驗證protected function setUp(): voidprotected function tearDown(): void
契約
影響可能性:非常低Illuminate\Contracts\Validation\Validator
中新增了validated
方法:
如果你呼叫了這個接口,需要加入此方法的實作。 /**
* 获取已验证的属性和值。
*
* @return array
*/public function validated();
特性
## 影響可能性:非常低
Illuminate\Validation\Concerns\ValidatesAttributes
特性中的parseTable、
getQueryColumn 和
requireParameterCount 方法可見性從
protected 調整為了
public。
DatabasePresenceVerifier
影響可能性:非常低
Illuminate\Validation\DatabasePresenceVerifier
類別的table 方法可見性從
protected 調整為了
public。
Validator
類別
影響可能性:非常低
Illuminate\Validation\Validator
類別的getPresenceVerifierFor
方法可見性從protected
調整為了public
。
郵箱驗證
影響可能性:非常低
郵件程式驗證規則現在回偵測郵箱位址是否相容RFC5630, 使驗證邏輯和SwiftMailer 保持一致。在 Laravel 5.7, email
規則只驗證郵件地址是否相容於 RFC822。
因此 當使用 Laravel 5.8 時,先前認為無效的郵件地址現在將被視為有效,如 (e.g hej@bär.se
)。通常,這被看做一個 bug 修復; 不過, 我們還是將其列到這裡給你一個提醒。如果您遇到有關此變更的任何問題,請通知我們。
視圖
getData
方法
#影響可能性:非常低
Illuminate\Contracts\View \View 契約中新增了getData
方法。如果你呼叫了這個接口, 則需要加入該方法的實作。
通知
Nexmo / Slack 通知頻道
#影響可能性:高
Nexmo 和Slack 通知頻道已經提前到官方擴充中。要在自己的應用程式中使用這些頻道,需要安裝以下擴充包:
composer require laravel/nexmo-notification-channel composer require laravel/slack-notification-channel
其他
#我們也鼓勵你查看 laravel/laravel
程式碼倉庫的更新日誌。儘管其中的許多更新不是必須的,但是你可以將你的應用程式中的這些檔案與程式碼倉庫保持同步。其中一些更新已經在這篇升級指南中提到了,但是還有很多其他的小更新(如對配置文件或註釋的更改)就不會列出。你可以透過 GitHub 比較工具 查看哪些更新對你而言更重要。