iT邦幫忙

2023 iThome 鐵人賽

DAY 17
0

功能需求

前天前後端不分離的畫面,使用者創建完團購(Group)後,會直接轉址到輸入產品資料的空白表單,在這個畫面我一次提供了10筆可供填寫的列,每一列可填入一筆產品資料

https://ithelp.ithome.com.tw/upload/images/20231002/20162893L5UldbaHmb.png

(先不管使用者可能需要填寫超過10項產品的情況…)

假設使用者只填寫四筆,傳入 controller 的資料會像下圖,第四筆開始內容都是 null

https://ithelp.ithome.com.tw/upload/images/20231002/20162893BAlnw8eoCA.png

如果直接將傳入資料新增至資料庫,就會碰觸到有些欄位不可為 null 的限制,我也不想要有資料全部都是 null ,所以就需要「處理」一下這些資料。

原生 PHP:array_filter()

這裡用 tinker 2 這個軟體,可直接當成 php artisan tinker 的視窗,也可以測試 php code,還可以編輯左邊訊息,非常方便(但現在沒有繼續維護了有點可惜,好像也不太能下載了,可以研究看看其他軟體)

array_filter() 功能與測試

array_filter() 是 PHP 中的一個內建函數,array_filter 就像一個過濾器,它可以幫助你過濾掉陣列中不需要的元素,只保留符合特定條件的元素。

  1. 我先寫了個 function,如果給這個 function 一個變數 $variable,這個 function 會去判斷這個變數 $variable 是否為 3 的倍數,是的話回傳變數本身,不是的話就不回傳
  2. 然後利用 array_filter() 函式,引入 $array 中一個個的元素至 function,過濾結果存成新的 $newArray
  3. 結果如右邊, array_filter() 幫我篩選了符合條件的元素,且保留它的 key 值

https://ithelp.ithome.com.tw/upload/images/20231002/20162893W1PqC5Nj10.png

上面的程式碼可用閉包改寫:

$newArray = array_filter($array, function($value) {
    return $value % 3 == 0;
		// 當 ($value % 3 == 0) 這個條件被滿足時才會回傳
});

回頭看我的程式碼

我需要被整理的資料如下,其中有兩個條件:

  1. 當使用者有輸入 product_name 時,price 一定要有值
  2. quantity_limit 和 note 欄位可不輸入 (null)

因此,我需要把所有 product_name = null 的 array 元素整筆刪除,使用 array_filter() 加上閉包

https://ithelp.ithome.com.tw/upload/images/20231002/20162893B8LeT3fu5c.png

$data = [
     1 => [
      "product_name" => "章魚燒披薩",
      "price" => "350",
      "quantity_limit" => null,
      "note" => null,
    ],
    2 => [
      "product_name" => "總匯披薩",
      "price" => "500",
      "quantity_limit" => null,
      "note" => null,
    ],
    3 => [
      "product_name" => "瑪格麗特",
      "price" => "390",
      "quantity_limit" => null,
      "note" => null,
    ],
    4 => [
      "product_name" => null,
      "price" => null,
      "quantity_limit" => null,
      "note" => null,
    ],
    5 => [
      "product_name" => null,
      "price" => null,
      "quantity_limit" => null,
      "note" => null,
    ],
    6 => [ 
      "product_name" => null,
      "price" => null,
      "quantity_limit" => null,
      "note" => null,
    ],
];

Laravel Collection 處理資料的強大工具

溫馨提醒,這裡講的是 Illuminate\Support\Collection,跟處理回傳結果的 Illuminate\Database\Eloquent\Collection 是不同東西!
Eloquent\Collection 是繼承 Illuminate\Support\Collection 的用法。

Laravel 的 Collection 是一個強大的資料集合工具,就像一個超級方便的工具包,它讓你可以更輕鬆地處理數據,就像在一個資料庫中查詢數據一樣。它的主要功能就是幫助你對數據集進行各種操作,比如過濾、排序、轉換、計算等等,而不需要寫很多冗長的程式碼。

以簡單的方式來看,你可以把 Laravel Collection 想像成一個神奇的魔法盒子,你把一堆資料扔進去,然後透過不同的指令(方法)來取出你需要的東西。比如,你可以對一組商品進行篩選,只保留某些特定條件下的商品;或者你可以把數據集按照不同的規則排序;又或者你可以對每一個數據進行轉換,生成新的數據。

  • Collection 類別能讓你將其方法串在一起呼叫,以流暢地在底層的陣列上進行 Map 與 Reduce 處理。
  • 通常來說,Collection 是不可變的(Immutable),這代表每個 Collection 方法都會回傳一個全新的 Collection實體。

舉例:篩選 3 的倍數

以上面相同舉例來看,經過 collect() 之後的 array 會變成 Laravel Collection 物件,就可以用 指向各種方便的方法使用

https://ithelp.ithome.com.tw/upload/images/20231002/20162893zMHAPqFz3m.png

依照需求修改我的程式碼

傳入的資料 $inputData

// 傳入的資料
$inputData = [
    [
        "product_name" => "章魚燒披薩",
        "price" => "350",
        "quantity_limit" => null,
        "note" => null,
    ],
    [
        "product_name" => "總匯披薩",
        "price" => "500",
        "quantity_limit" => null,
        "note" => null,
    ],
    [
        "product_name" => "瑪格麗特",
        "price" => "390",
        "quantity_limit" => null,
        "note" => null,
    ],
    // 這裡省略了其餘商品的資料
];

修改處理資料的邏輯

// 原本的寫法:array_filter()
    $productsData = array_filter($inputData, function ($data) {
        return isset($data['product_name']);
						// 如果 product_name 有值的話才被回傳
    });

// 改用 laravel collection
    $collectArray = collect($inputData);
				// 將 array 轉換為 collection 物件
    $productsData = $collectArray->whereNotNull('product_name');
				// 如果 product_name 不是 null 的話存入 $productsData

上一篇
Laravel 資料驗證:Validation
下一篇
等等,那 Eloquent Collection 是什麼?
系列文
Laravel 後端菜鳥可以知道的流程概念30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言