升級說明


  • 升級指南

從5.7 升級到5.8.0

    高影響的改變
  • 以秒為單位快取TTL
  • 快取鎖定的安全性改進
  • Markdown 檔案路徑改變
Nexmo / Slack 通知頻道改變

    中等影響的改變
  • 容器產生器與標籤服務
  • SQLite 版本限制
  • 在字串和陣列方面用類別取代Helpers
  • 棄用Deferred 服務提供者
  • #符合PSR-16 規範
  • 改進不規則複數的模型名稱結尾
  • 自訂中間表模型增加自增id 屬性
支援Pheanstalk 4.0 函式庫#########

從 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 ,  #remembersetDefaultCacheTime 方法,以及所有快取記憶體的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 類別中的 putputManyadd 方法的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();

RepositoryStore 契約

影響可能性:非常低

為了完全符合PSR-16 的要求,Illuminate\Contracts\Cache\Repository 契約的putforever 方法的傳回值以及Illuminate\Contracts\Cache\Store 契約的put, putManyforever 方法已變更從voidbool

集合

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

方法

影響可能性:非常低

###resolve### 方法接收一個新布爾參數,此參數指示事件在物件實例化期間是否應觸發/ 執行(解析回呼)。如果你重寫了這個方法,你必須更新方法簽章以符合父方法。 #########addContextualBinding### 方法########影響可能性:非常低############Illuminate\Contracts\Container\Container## # 契約增加了###addContextualBinding###  方法。如果要實作此接口,則應將此方法加到你的實作中。 ###

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'];

BelongsTogetForeignKey 方法

影響可能性:低

BelongsTo 關聯關係中的getForeignKeygetQualifiedForeignKey 方法已分別重新命名為getForeignKeyNamegetQualifiedForeignKeyName,使得方法名稱和在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 類別中的 sendsendNowqueuelaterfill 方法已更改為需接收一個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

Sessions

StartSession 中間件

影響可能性:非常低

Session 的持久性邏輯已從

terminate() 方法移至handle() 方法。如果你要重寫其中的方法, 則應該更新它們以反映這些變更。

Support

優先使用字串和陣列類別而不是輔助函數

#影響可能性:中等##所有的

array_*

and str_* 全域輔助函數都被廢棄。你需要直接使用 Illuminate\Support\ArrIlluminate\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
驗證

Validator

契約

影響可能性:非常低

Illuminate\Contracts\Validation\Validator

中新增了validated 方法:

/**
 * 获取已验证的属性和值。
 *
 * @return array
 */public function validated();
如果你呼叫了這個接口,需要加入此方法的實作。

ValidatesAttributes

特性## 影響可能性:非常低

Illuminate\Validation\Concerns\ValidatesAttributes

特性中的

parseTablegetQueryColumnrequireParameterCount 方法可見性從protected 調整為了publicDatabasePresenceVerifier

類別

影響可能性:非常低

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 比較工具 查看哪些更新對你而言更重要。

本篇首刊在 LearnKu.com 網站上。