> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# 輔助函式

> 以實務範例說明 Laravel 提供的全域輔助函式，以及 Arr、Number 類別。

## 輔助函式是什麼

Laravel 提供了大量的全域 PHP 函式（輔助函式）。它們大多是框架自身內部所使用，但你也可以在應用程式中自由運用。

輔助函式大致分為以下幾類：

* **陣列 / 物件**：`Arr::` 類別與 `data_get()` 等函式
* **數字**：`Number::` 類別
* **路徑**：`app_path()`、`storage_path()` 等取得路徑的函式
* **URL**：`route()`、`url()`、`asset()` 等 URL 產生函式
* **其他**：`config()`、`collect()`、`auth()` 等常用工具

<Info>
  輔助函式無須 `use` 宣告即可從任何地方呼叫。若要使用 `Arr` 或 `Number` 類別，則需 `use Illuminate\Support\Arr;` 等 import。
</Info>

## 陣列輔助（Arr 類別）

### `Arr::get()` — 以點記法讀取巢狀值

安全地以點記法（`foo.bar.baz`）從多維陣列讀取巢狀值。鍵不存在時可回傳預設值。

```php theme={null}
use Illuminate\Support\Arr;

$config = [
    'database' => [
        'connections' => [
            'mysql' => ['host' => '127.0.0.1', 'port' => 3306],
        ],
    ],
];

$host = Arr::get($config, 'database.connections.mysql.host');
// '127.0.0.1'

// 鍵不存在時的預設值
$charset = Arr::get($config, 'database.connections.mysql.charset', 'utf8mb4');
// 'utf8mb4'
```

<Tip>
  全域函式 `data_get()` 有同樣的功能，還支援 `Arrayable` 物件（如 Eloquent 關聯），適用範圍更廣。
</Tip>

### `Arr::set()` — 對巢狀陣列設定值

```php theme={null}
use Illuminate\Support\Arr;

$array = ['products' => ['desk' => ['price' => 100]]];

Arr::set($array, 'products.desk.price', 200);

// ['products' => ['desk' => ['price' => 200]]]
```

### `Arr::has()` — 檢查鍵是否存在

```php theme={null}
use Illuminate\Support\Arr;

$array = ['product' => ['name' => 'Desk', 'price' => 100]];

$hasName = Arr::has($array, 'product.name');
// true

// 檢查多個鍵是否全部存在
$hasAll = Arr::has($array, ['product.name', 'product.price']);
// true
```

### `Arr::only()` / `Arr::except()` — 篩選或排除鍵

適合從請求資料或設定陣列中只取出必要的鍵，或排除不必要的鍵。

```php theme={null}
use Illuminate\Support\Arr;

$user = [
    'id' => 1,
    'name' => '山田太郎',
    'email' => 'yamada@example.com',
    'password' => 'secret',
    'role' => 'admin',
];

// 只取出必要的鍵
$safe = Arr::only($user, ['id', 'name', 'email']);
// ['id' => 1, 'name' => '山田太郎', 'email' => 'yamada@example.com']

// 只排除 password
$public = Arr::except($user, ['password']);
// ['id' => 1, 'name' => '山田太郎', 'email' => '...', 'role' => 'admin']
```

### `Arr::pluck()` — 從巢狀陣列擷取特定鍵

```php theme={null}
use Illuminate\Support\Arr;

$records = [
    ['user' => ['id' => 1, 'name' => '山田太郎']],
    ['user' => ['id' => 2, 'name' => '鈴木花子']],
];

$names = Arr::pluck($records, 'user.name');
// ['山田太郎', '鈴木花子']

// 第 3 個參數指定 key
$nameById = Arr::pluck($records, 'user.name', 'user.id');
// [1 => '山田太郎', 2 => '鈴木花子']
```

### `Arr::first()` / `Arr::last()` — 符合條件的第一個 / 最後一個

```php theme={null}
use Illuminate\Support\Arr;

$prices = [150, 80, 200, 50, 120];

// 100 以上的第一個價格
$first = Arr::first($prices, fn ($price) => $price >= 100);
// 150

// 若無符合條件的預設值
$first = Arr::first($prices, fn ($price) => $price >= 500, 0);
// 0

// 最後一個元素（不加條件）
$last = Arr::last($prices);
// 120
```

### `Arr::flatten()` — 將多維陣列扁平化

```php theme={null}
use Illuminate\Support\Arr;

$tags = [
    'frontend' => ['html', 'css', 'javascript'],
    'backend'  => ['php', 'laravel', 'mysql'],
];

$allTags = Arr::flatten($tags);
// ['html', 'css', 'javascript', 'php', 'laravel', 'mysql']
```

### `Arr::wrap()` — 確保值為陣列

若值非陣列則包裝為陣列。`null` 會變成空陣列。適合讓函式參數更彈性。

```php theme={null}
use Illuminate\Support\Arr;

Arr::wrap('Laravel');
// ['Laravel']

Arr::wrap(['Laravel', 'PHP']);
// ['Laravel', 'PHP']

Arr::wrap(null);
// []
```

### `Arr::sort()` — 依值排序

```php theme={null}
use Illuminate\Support\Arr;

$fruits = ['banana', 'apple', 'cherry'];
$sorted = Arr::sort($fruits);
// ['apple', 'banana', 'cherry']

// 以閉包指定排序 key
$products = [
    ['name' => '筆電', 'price' => 120000],
    ['name' => '滑鼠', 'price' => 3500],
    ['name' => '鍵盤', 'price' => 8000],
];

$byPrice = Arr::sort($products, fn ($product) => $product['price']);
// 滑鼠、鍵盤、筆電 的順序
```

### `Arr::dot()` / `Arr::undot()` — 點記法轉換 / 復原

```php theme={null}
use Illuminate\Support\Arr;

$nested = [
    'user' => [
        'profile' => ['name' => '山田太郎', 'age' => 28],
    ],
];

$dotted = Arr::dot($nested);
// ['user.profile.name' => '山田太郎', 'user.profile.age' => 28]

// 還原成原結構
$restored = Arr::undot($dotted);
// ['user' => ['profile' => ['name' => '山田太郎', 'age' => 28]]]
```

### `Arr::join()` — 將陣列結合為字串

```php theme={null}
use Illuminate\Support\Arr;

$items = ['PHP', 'Laravel', 'MySQL'];

Arr::join($items, ', ');
// 'PHP, Laravel, MySQL'

// 只在最後一個元素前用不同字串
Arr::join($items, ', ', ' 與 ');
// 'PHP, Laravel 與 MySQL'
```

## `data_get()` — 存取巢狀資料

`Arr::get()` 的通用版本。除了陣列，也支援物件、Eloquent 模型、集合。

```php theme={null}
$users = [
    ['name' => '山田太郎', 'address' => ['city' => '東京']],
    ['name' => '鈴木花子', 'address' => ['city' => '大阪']],
];

// 用點記法存取
$city = data_get($users, '0.address.city');
// '東京'

// 用萬用字元一次取所有元素
$cities = data_get($users, '*.address.city');
// ['東京', '大阪']
```

## 數字輔助（Number 類別）

### `Number::format()` — 將數字轉為易讀的格式

```php theme={null}
use Illuminate\Support\Number;

Number::format(1234567.89);
// '1,234,567.89'

Number::format(1234567.89, precision: 0, locale: 'ja');
// '1,234,568'
```

### `Number::currency()` — 幣別格式

```php theme={null}
use Illuminate\Support\Number;

Number::currency(10000, 'JPY', locale: 'ja');
// '￥10,000'

Number::currency(29.99, 'USD');
// '$29.99'
```

### `Number::fileSize()` — 將檔案大小轉為易讀格式

```php theme={null}
use Illuminate\Support\Number;

Number::fileSize(1024);
// '1 KB'

Number::fileSize(1024 * 1024 * 2.5);
// '2.5 MB'
```

### `Number::abbreviate()` — 將大數字縮寫

```php theme={null}
use Illuminate\Support\Number;

Number::abbreviate(1000);
// '1K'

Number::abbreviate(1500000);
// '1.5M'
```

### `Number::percentage()` — 百分比顯示

```php theme={null}
use Illuminate\Support\Number;

Number::percentage(75.5, precision: 1);
// '75.5%'
```

## 路徑輔助

取得應用程式的目錄路徑。即使環境或部署目的地不同，也能回傳正確路徑。

```php theme={null}
// app 目錄的絕對路徑
app_path();
// /var/www/html/app

// app/Http/Controllers/UserController.php 的路徑
app_path('Http/Controllers/UserController.php');

// 專案根目錄的相對路徑
base_path('composer.json');

// config 目錄
config_path('database.php');

// database 目錄
database_path('migrations');

// storage 目錄
storage_path('app/uploads');

// public 目錄
public_path('css/app.css');

// resources 目錄
resource_path('views/welcome.blade.php');
```

## URL 輔助

### `route()` — 產生命名路由的 URL

```php theme={null}
// 路由定義
// Route::get('/users/{user}', [UserController::class, 'show'])->name('users.show');

// 絕對 URL（預設）
$url = route('users.show', ['user' => 1]);
// 'https://example.com/users/1'

// 相對 URL
$url = route('users.show', ['user' => 1], false);
// '/users/1'
```

### `url()` — 產生任意路徑的絕對 URL

```php theme={null}
$url = url('user/profile');
// 'https://example.com/user/profile'

// 取得 URL Generator 實例
$current  = url()->current();   // 目前 URL
$full     = url()->full();      // 含查詢字串的目前 URL
$previous = url()->previous();  // 前一個 URL
```

### `asset()` — 產生靜態資產的 URL

```php theme={null}
$url = asset('img/logo.png');
// 'https://example.com/img/logo.png'
```

### `to_route()` — 重新導向至命名路由

```php theme={null}
return to_route('users.show', ['user' => 1]);

// 可指定 HTTP 狀態與標頭
return to_route('users.show', ['user' => 1], 302, ['X-Custom' => 'value']);
```

## 其他常用輔助函式

### `config()` — 讀寫設定值

```php theme={null}
// 以點記法讀取設定
$timezone = config('app.timezone');
// 'Asia/Tokyo'

// 附預設值
$debug = config('app.debug', false);

// 執行期變更設定（僅該次處理內生效）
config(['app.locale' => 'ja']);
```

### `collect()` — 建立集合

```php theme={null}
$collection = collect([1, 2, 3, 4, 5]);

$sum = collect([1, 2, 3])->sum(); // 6
```

<Tip>
  `collect()` 是進入集合世界的最重要輔助函式。詳細請見[集合](/zh-TW/collections)。
</Tip>

### `auth()` — 取得已認證使用者

```php theme={null}
// 取得目前使用者
$user = auth()->user();

// 檢查是否登入
if (auth()->check()) {
    // 已登入處理
}

// 使用特定 guard
$admin = auth('admin')->user();
```

### `blank()` / `filled()` — 空值檢查

`blank()` 會把 `null`、空字串、只有空白、空集合 / 陣列視為 `true`。`filled()` 為其相反。

```php theme={null}
blank('');         // true
blank('   ');      // true
blank(null);       // true
blank(collect()); // true

blank(0);      // false（0 不是「空」）
blank(false);  // false

filled('hello'); // true
filled(0);       // true
```

### `abort()` / `abort_if()` / `abort_unless()` — HTTP 例外

```php theme={null}
// 直接拋出 HTTP 錯誤
abort(404);
abort(403, '你沒有存取此頁面的權限。');

// 條件為 true 時錯誤
abort_if(! auth()->user()->isAdmin(), 403);

// 條件為 false 時錯誤
abort_unless(auth()->check(), 401);
```

### `dd()` / `dump()` — 除錯

```php theme={null}
// 輸出變數並結束腳本
dd($user);
dd($user, $orders, $config);

// 只輸出，不結束腳本
dump($query);
```

### `dispatch()` — 派發 Job 至佇列

```php theme={null}
dispatch(new App\Jobs\SendWelcomeEmail($user));

// 立即執行（同步）
dispatch_sync(new App\Jobs\GenerateReport($data));
```

### `encrypt()` / `decrypt()` — 加解密

```php theme={null}
$encrypted = encrypt('sensitive-value');
$decrypted = decrypt($encrypted);
```

### `env()` — 取得環境變數

```php theme={null}
$debug = env('APP_DEBUG', false);
$dbHost = env('DB_HOST', '127.0.0.1');
```

<Warning>
  `env()` 建議只在 `config/` 檔案中呼叫，於其他地方請透過 `config()` 存取，這是最佳實踐。當設定快取（`php artisan config:cache`）啟用時，`env()` 可能不會回傳你預期的值。
</Warning>

## 與 collect() 的取捨

`Arr::` 類別以純 PHP 陣列為操作對象；`collect()` 則會回傳集合物件。

```php theme={null}
use Illuminate\Support\Arr;

// 想維持陣列 → 用 Arr 類別
$filtered = Arr::where($items, fn ($v) => $v > 0);
// 結果仍是陣列

// 想以方法鏈串接多個操作 → 用 collect()
$result = collect($items)
    ->filter(fn ($v) => $v > 0)
    ->map(fn ($v) => $v * 2)
    ->values()
    ->all();
// 結果是陣列（用 all() 取出）
```

<Info>
  Eloquent 查詢結果本身就是集合，不需要再 `collect()`。若只是簡單的陣列操作，用 `Arr::` 會更簡潔。
</Info>

## 總結

<AccordionGroup>
  <Accordion title="常用輔助函式一覽">
    | 輔助                                    | 用途         |
    | ------------------------------------- | ---------- |
    | `Arr::get($array, 'a.b.c', $default)` | 安全讀取巢狀陣列   |
    | `Arr::only($array, $keys)`            | 只保留指定鍵     |
    | `Arr::except($array, $keys)`          | 排除指定鍵      |
    | `Arr::pluck($array, 'key')`           | 取得特定鍵的值清單  |
    | `Arr::flatten($array)`                | 將多維陣列扁平化   |
    | `Arr::wrap($value)`                   | 確保為陣列      |
    | `data_get($target, 'a.*.b')`          | 支援萬用字元     |
    | `Number::format($n)`                  | 將數字格式化     |
    | `Number::currency($n, 'JPY')`         | 幣別顯示       |
    | `Number::fileSize($bytes)`            | 檔案大小顯示     |
    | `route('name', $params)`              | 命名路由 URL   |
    | `url('path')`                         | 產生絕對 URL   |
    | `asset('path')`                       | 靜態資產 URL   |
    | `config('key', $default)`             | 取得設定值      |
    | `collect($array)`                     | 建立集合       |
    | `auth()->user()`                      | 取得目前使用者    |
    | `blank($value)`                       | 空值檢查       |
    | `filled($value)`                      | 檢查是否非空     |
    | `abort(403)`                          | 拋出 HTTP 例外 |
    | `dispatch($job)`                      | 派發 Job 到佇列 |
    | `env('KEY', $default)`                | 取得環境變數     |
  </Accordion>

  <Accordion title="Arr 類別 vs collect()">
    **使用 `Arr::` 類別的情境**：

    * 單純的陣列操作（存取巢狀鍵、鍵的篩選等）
    * 不需要集合物件的額外開銷
    * 結果要直接以陣列處理

    **使用 `collect()` 的情境**：

    * 想以方法鏈串接多個操作
    * 對 Eloquent 結果再加工（本身就是集合）
    * 想使用 `map`、`filter`、`groupBy` 等集合專屬方法
  </Accordion>
</AccordionGroup>


## Related topics

- [在地化](/zh-TW/localization.md)
- [Facade](/zh-TW/facades.md)
- [日誌](/zh-TW/logging.md)
- [錯誤處理](/zh-TW/error-handling.md)
- [集合](/zh-TW/collections.md)
