這篇文章主要介紹了關於利用Laravel Collections類別如何寫程式碼,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下
Laravel 提供了一些超讚的組件,在我看來,它是目前所有Web 框架中提供元件支援最好的一個。它不僅提供了開箱即用的視圖(views)、身份認證(authentication)、會話(sessions)、快取(caching)、Eloquent、佇列(queues)、資料校驗(data validation)等元件。甚至還提供了開發工具(Valet 和 Homestead)。
但是,這個框架功能中最強大的一個特性常常被萌新們視而不見 - Collection(集合) 類別。在這篇文章,我們將探討如何使用集合提升編碼效率、程式碼的易讀行,並寫出更精簡的編碼。
預覽
最初接觸到使用集合的場景來自於研發人員使用 Eloquent 執行資料庫查詢,並從返回資料中使用 foreach 語句遍歷取得模型集合。
不過,初學者可能並沒有註意到,集合提供了超過 90 個以上的方法來操作底層資料。更棒的是幾乎所有的方法都支援鍊式操作,能夠讓你的程式碼讀起來就像一篇散文一樣。這使得你的程式碼更容易閱讀,無論是你還是其他使用者都是如此。
還沒進入正題?好吧,讓我們回顧一個簡單的程式碼片段,來看看我們如何使用集合編寫粗、快、猛的程式碼。
程式碼範例
讓我們建立一個真實的世界。假設我們查詢某些 API 介面並取得到如下以陣列保存的結果集:
<?php // API 请求返回的结果 $data = [ ['first_name' => 'John', 'last_name' => 'Doe', 'age' => 'twenties'], ['first_name' => 'Fred', 'last_name' => 'Ali', 'age' => 'thirties'], ['first_name' => 'Alex', 'last_name' => 'Cho', 'age' => 'thirties'], ];
我們看到陣列包含名字(first name)、姓氏(last name) 和年齡(age)範圍。現在,我們假設從記錄中獲取一名年齡(age) 為30 歲(thirties) 的用戶,然後依據姓氏(last name) 進行排序(sort)。最後,我們也希望傳回的結果為 一個字串(single string),這樣每個使用者獨佔 一行(new line)。最後,我們也希望返回的結果為
這個需求看起來不難實現,現在讓我們看看使用PHP 如何實現這一功能:
// 依据姓氏排序 usort($data, function ($item1, $item2) { return $item1['last_name'] $item2['last_name']; }); // 依据年龄范围分组 $new_data = []; foreach ($data as $key => $item) { $new_data[$item['age']][$key] = $item; } ksort($new_data, SORT_NUMERIC); // 从年龄为 30 岁组里获取用户全名 $result = array_map(function($item) { return $item['first_name'].' '.$item['last_name']; }, $new_data['thirties']); // 将数组转换为字符串并以行分隔符分隔 $final = implode("\n", $result); // 译注:原文是 $final = implode($results, "\n"); implode函数接收两种顺序的参数,为了保持与文档一致所以我这边做了调整。
我們的實作程式碼超過20 行,並且很不優雅。移除掉註解及換行相關程式碼,這段程式碼會變得難以閱讀。再者,我們還需要藉助臨時變數以及 PHP 內建的不友善的 sort 方法。
現在,讓我們看下借助 Collection 類別實作是多麼簡單:
collection($data)->where('age', 'thirties') ->sortBy('last_name') ->map(function($item){ return $item['first_name'].' '.$item['last_name']; }) ->implode("\n");
哇!我們的程式碼從 20 行變成了 6 行。現在的程式碼不僅順暢不少,而且在方法實作時無需借助註解告訴我們它們在處理什麼問題。
不過,還有一個問題阻止我們的程式碼不如完美階段... 就是用來比較 first name 和 last name 的 map 方法。坦白說,這真的不是什麼大問題,但是它為我們探索 macro(宏) 概念提供了動力。
擴展集合(Extending Collections)
Collection 類,同其它 Laravel 組件一樣,支援巨集(macroable),就是說你可以給它添加方法隨後使用。
提示: 如果你希望新方法隨處可用,你應該將它們加入服務提供。我喜歡創建一個 MacroServiceProvider 實先這個功能,對於你來說隨你喜歡就好。
讓我們新增一個方法它會連接由陣列提供的任意數量的欄位並傳回字串結果:
Collection::macro('toConcatenatedString', function ($fields = [], $separator = ' ') { return $this->map(function($item) use ($fields, $separator) { return implode($separator, array_map(function ($el) use ($item) { return $item[$el]; }, $fields) ); })->implode("\n"); });
加入這個方法後,我們的程式碼基本上就完美了:
collect($data)->where('age', 'thirties') ->sortBy('last_name') ->toConcatenatedString(['first_name', 'last_name']);
我們的程式碼從混亂的20 多行精簡到了3 行,程式碼乾淨整潔功能清晰任何人都可以立刻理解。
又一個範例
現在讓我們看下第二個範例,假設我們一個使用者列表,我們需要基於角色(role)過濾出來,然後進一步如果他們的註冊時間為5年或以上且last name 以字母A-M 開始的僅取得第一個使用者。
資料類似如下:
<?php // API 请求返回的结果 $users = [ ['name' => 'John Doe', 'role' => 'vip', 'years' => 7], ['name' => 'Fred Ali', 'role' => 'vip', 'years' => 3], ['name' => 'Alex Cho', 'role' => 'user', 'years' => 9], ];
如果我們使用的是PHP 實現,我們的程式碼看下來如下:
$subset = []; foreach ($users as $user) { if ($user['role'] === 'vip' && $user['years'] >= 5) { if (preg_match('/\s[A-Z]/', $user['name'])) { $subset[] = $user; } } } return reset($subset)
注意: 你可以將第二個if 語句移至第一個裡面,但是我個人喜歡在單一if 語句中使用不超過兩個條件語句,因為我認為超過2 個條件語句回事程式碼難以閱讀。
這段程式碼不至於太糟糕,但是我們仍然需要使用臨時變量,我們還需要使用 reset 函數將指標重置到第一個使用者。我們的程式碼還有四層縮排,這使得程式碼解析變得更有挑戰性。
相反,我們來看看集合是如何處理這個問題的:
collect($users)->where('role', 'vip') ->map(function($user) { return preg_match('/\s[A-Z]/', $user['name']); }) ->firstWhere('years', '>=', '5');
我们将代码简化到了之前的一般左右,每一步过滤处理清晰明了,并且我们不需要引入临时变量。
遗憾的是目前集合还不支持正则匹配,所以我们使用 map 方法,不过我们可以为这个功能创建一个宏:
Collection::macro('whereRegex', function($expression, $field) { return $this->map(function ($item) use ($expression, $field) { return preg_match($expression, $item[$field]); }) });
得益于宏方法,我们的代码现在看起来如下:
collect($users) -> where('role', 'vip') -> whereRegex('/\s[A-Z]/', 'name') -> firstWhere('years', '>=', 5);
注意: 为了简单起见,我们的红仅仅适用于数组集合。如果你计划让它们可以在 Eloquent 集合上使用,你需要在此场景下做相应的代码处理才行。
不同的视角
我们可以继续列出无数的示例,但仍然无法涵盖所有可用的集合方法,并且这从来都不是本文的真正目的。
需要注意的是,通过使用 Collection 类,您不仅可以获得一个方法库来简化编程工作,还可以选择一种从根本上改善代码的方法。
你会情不自禁的将你的代码结构从代码块重构简化成一行,同时减少代码的缩进,临时变量的使用和技巧性方法,另外你还可以使用链式编程方法,这让你的代码更加便于阅读和解析,此外最重要的是减少了编码工作!
查看官方文档获取更多这个迷人的类库的使用细节:https://laravel.com/docs/coll...
提示: 你还可以获取这个 Collection 类独立安装包,在使用非 laravel 项目是会非常有帮助。感谢 Tighten Co 团队做出的努力 https://github.com/tightenco/...。
感谢阅读,快乐编码!
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
以上是利用Laravel Collections類別如何寫程式碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本篇文章给大家带来了关于laravel的相关知识,其中主要介绍了关于单点登录的相关问题,单点登录是指在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于laravel的相关知识,其中主要介绍了关于Laravel的生命周期相关问题,Laravel 的生命周期从public\index.php开始,从public\index.php结束,希望对大家有帮助。

在laravel中,guard是一个用于用户认证的插件;guard的作用就是处理认证判断每一个请求,从数据库中读取数据和用户输入的对比,调用是否登录过或者允许通过的,并且Guard能非常灵活的构建一套自己的认证体系。

laravel中asset()方法的用法:1、用于引入静态文件,语法为“src="{{asset(‘需要引入的文件路径’)}}"”;2、用于给当前请求的scheme前端资源生成一个url,语法为“$url = asset('前端资源')”。

本篇文章给大家带来了关于laravel的相关知识,其中主要介绍了关于使用中间件记录用户请求日志的相关问题,包括了创建中间件、注册中间件、记录用户访问等等内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于laravel的相关知识,其中主要介绍了关于中间件的相关问题,包括了什么是中间件、自定义中间件等等,中间件为过滤进入应用的 HTTP 请求提供了一套便利的机制,下面一起来看一下,希望对大家有帮助。

在laravel中,fill方法是一个给Eloquent实例赋值属性的方法,该方法可以理解为用于过滤前端传输过来的与模型中对应的多余字段;当调用该方法时,会先去检测当前Model的状态,根据fillable数组的设置,Model会处于不同的状态。

laravel路由文件在“routes”目录里。Laravel中所有的路由文件定义在routes目录下,它里面的内容会自动被框架加载;该目录下默认有四个路由文件用于给不同的入口使用:web.php、api.php、console.php等。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Dreamweaver CS6
視覺化網頁開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),