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

# Support Contracts（Arrayable / Jsonable / Htmlable / Responsable）

> 基於 Laravel 13 官方原始碼，說明 Illuminate\Contracts\Support 中的 4 種主要 Contract。

## 什麼是 Support Contracts

`Illuminate\Contracts\Support` 彙集了於整個 Laravel 中使用的小巧但重要的介面。
特別是 `Arrayable` / `Jsonable` / `Htmlable` / `Responsable`，是將 Value Object、DTO、Response 物件自然融入 Laravel 既有流程的基本模式。

```mermaid theme={null}
flowchart TD
    A["Value Object / DTO"] --> B["Arrayable<br>toArray()"]
    A --> C["Jsonable<br>toJson($options = 0)"]
    A --> D["Htmlable<br>toHtml()"]
    A --> E["Responsable<br>toResponse($request)"]
    B --> F["JsonResponse / Eloquent / Collection"]
    C --> F
    D --> G["e() helper / Blade output"]
    E --> H["Controller return / Router::toResponse()"]
```

<Info>
  此處使用的簽章參照 Laravel 13.x 的官方原始碼（`laravel/framework`）。
</Info>

## 1) Arrayable

### 介面定義

```php theme={null}
interface Arrayable
{
    public function toArray();
}
```

### 實作範例

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

final class Money implements Arrayable
{
    public function __construct(
        public readonly int $amount,
        public readonly string $currency,
    ) {}

    public function toArray(): array
    {
        return [
            'amount' => $this->amount,
            'currency' => $this->currency,
        ];
    }
}
```

### Laravel Core 的使用範例

* `Illuminate\Database\Eloquent\Model` 實作 `Arrayable`，提供 `toArray()`
* `Illuminate\Http\JsonResponse::setData()` 偵測到 `Arrayable` 時，以 `json_encode($data->toArray(), ...)` 序列化

### 套件開發的活用要點

* 可將 DTO 或 Value Object 於 Controller、Resource、Log 輸出中共同格式化
* 可將轉換為 `array` 的職責收斂於物件端

## 2) Jsonable

### 介面定義

```php theme={null}
interface Jsonable
{
    public function toJson($options = 0);
}
```

### 實作範例

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

final class ApiPayload implements Jsonable
{
    public function __construct(
        private array $data,
    ) {}

    public function toJson($options = 0): string
    {
        return json_encode([
            'data' => $this->data,
            'generated_at' => now()->toIso8601String(),
        ], $options | JSON_THROW_ON_ERROR);
    }
}
```

### Laravel Core 的使用範例

* `Model` 也實作了 `Jsonable`，提供 `toJson($options = 0)`
* `JsonResponse::setData()` 會最優先判定 `Jsonable` 並使用 `toJson()`

### 套件開發的活用要點

* 於稽核日誌、Webhook 傳送等場合可嚴格固定 JSON 結構
* 不交由 `json_encode()`，可明確表達領域面的 JSON 表現

## 3) Htmlable

### 介面定義

```php theme={null}
interface Htmlable
{
    public function toHtml();
}
```

### 實作範例

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

final class BadgeHtml implements Htmlable
{
    public function __construct(
        private string $label,
    ) {}

    public function toHtml(): string
    {
        $escaped = e($this->label);

        return "<span class=\"badge\">{$escaped}</span>";
    }
}
```

### Laravel Core 的使用範例

* `Illuminate\Support\HtmlString` 實作了 `Htmlable`
* `e()` helper 若引數為 `Htmlable`，會回傳 `toHtml()`（不重新 escape）

### 套件開發的活用要點

* 於 Blade 中安全傳遞 HTML 片段的職責邊界更清晰
* 即便於使用 `{!! $obj !!}` 的場合，也易於以物件管理輸出

<Tip>
  於實作 `Htmlable` 的類別內，勿直接串接使用者輸入，需將必要值以 `e()` escape 後再嵌入。
</Tip>

## 4) Responsable

### 介面定義

```php theme={null}
interface Responsable
{
    public function toResponse($request);
}
```

### 實作範例

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

final class ExportCsvResponse implements Responsable
{
    public function __construct(
        private array $rows,
        private string $filename = 'export.csv',
    ) {}

    /**
     * @param \Illuminate\Http\Request $request
     */
    public function toResponse($request)
    {
        return response()->streamDownload(function () {
            $stream = fopen('php://output', 'w');

            foreach ($this->rows as $row) {
                fputcsv($stream, $row);
            }

            fclose($stream);
        }, $this->filename, [
            'Content-Type' => 'text/csv',
        ]);
    }
}
```

### Laravel Core 的使用範例

* `Illuminate\Routing\Router::toResponse()` 會先判定 `Responsable`，呼叫 `$response->toResponse($request)`
* `Illuminate\Http\Resources\Json\JsonResource` 實作了 `Responsable`，因此可從 Controller 直接 `return UserResource::make($user);`

### 套件開發的活用要點

* 於 Controller 中不需自行組陣列，可將 Response 的生成委派給物件
* 便於「直接 return DTO」的設計，容易分離 HTTP 表現與領域表現

## 實作選擇指南

<Steps>
  <Step title="希望將資料陣列化並重複利用">
    實作 `Arrayable`，將正規化邏輯集中於 `toArray()`。
  </Step>

  <Step title="希望控制 JSON 表現">
    實作 `Jsonable`，於 `toJson($options)` 明確輸出格式。
  </Step>

  <Step title="希望作為 HTML 片段處理">
    實作 `Htmlable`，於 `toHtml()` 回傳渲染字串。
  </Step>

  <Step title="希望直接回傳 HTTP Response">
    實作 `Responsable`，將職責集中於 `toResponse($request)`。
  </Step>
</Steps>

## 下一步閱讀

<Columns cols={2}>
  <Card title="Macroable trait" icon="puzzle-piece" href="/zh-TW/advanced/macroable">
    學習為既有類別加入自訂方法的擴充模式。
  </Card>

  <Card title="Conditionable trait" icon="git-branch" href="/zh-TW/advanced/conditionable">
    學習以 `when()` / `unless()` 組入條件分支的設計。
  </Card>

  <Card title="tap() helper / Tappable" icon="hand-point-up" href="/zh-TW/advanced/tap">
    學習於插入副作用同時回傳值的鏈式設計。
  </Card>

  <Card title="Dumpable trait" icon="bug" href="/zh-TW/advanced/dumpable">
    學習將 `dump()` / `dd()` 組入物件的除錯方法。
  </Card>
</Columns>


## Related topics

- [Laravel Boost](/zh-TW/boost.md)
- [Contracts（契約）](/zh-TW/contracts.md)
- [延遲服務提供者](/zh-TW/advanced/deferred-provider.md)
- [輔助函式](/zh-TW/helpers.md)
- [圖片加工](/zh-TW/images.md)
