Passer au contenu principal

Que sont les Support Contracts

Illuminate\Contracts\Support regroupe de petites interfaces essentielles utilisées partout dans Laravel.
En particulier, Arrayable / Jsonable / Htmlable / Responsable sont les patterns de base qui permettent d’insérer naturellement Value Objects, DTO et objets de réponse dans les flux existants de Laravel.
Les signatures présentées ici proviennent des sources officielles de Laravel 13.x (laravel/framework).

1) Arrayable

Définition de l’interface

interface Arrayable
{
    public function toArray();
}

Exemple d’implémentation

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,
        ];
    }
}

Utilisations dans le cœur de Laravel

  • Illuminate\Database\Eloquent\Model implémente Arrayable et fournit toArray().
  • Illuminate\Http\JsonResponse::setData() détecte Arrayable et sérialise via json_encode($data->toArray(), ...).

Intérêt pour le développement de packages

  • Uniformiser le format des DTO et Value Objects dans les contrôleurs, ressources, journaux, etc.
  • Enfermer dans l’objet la responsabilité de conversion en array.

2) Jsonable

Définition de l’interface

interface Jsonable
{
    public function toJson($options = 0);
}

Exemple d’implémentation

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);
    }
}

Utilisations dans le cœur de Laravel

  • Model implémente également Jsonable et fournit toJson($options = 0).
  • JsonResponse::setData() évalue Jsonable en priorité et utilise toJson().

Intérêt pour le développement de packages

  • Fixer strictement la structure JSON pour les journaux d’audit, l’envoi de webhooks, etc.
  • Expliciter la représentation JSON métier, sans dépendre du comportement de json_encode().

3) Htmlable

Définition de l’interface

interface Htmlable
{
    public function toHtml();
}

Exemple d’implémentation

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>";
    }
}

Utilisations dans le cœur de Laravel

  • Illuminate\Support\HtmlString implémente Htmlable.
  • Le helper e() renvoie toHtml() si son argument est un Htmlable (sans ré-échapper).

Intérêt pour le développement de packages

  • Clarifier la frontière de responsabilités lors du passage sûr de fragments HTML dans Blade.
  • Faciliter la gestion de la sortie par objet, y compris là où on utilise {!! $obj !!}.
Dans une classe implémentant Htmlable, ne concaténez pas directement les entrées utilisateur : échappez d’abord les valeurs nécessaires avec e().

4) Responsable

Définition de l’interface

interface Responsable
{
    public function toResponse($request);
}

Exemple d’implémentation

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',
        ]);
    }
}

Utilisations dans le cœur de Laravel

  • Illuminate\Routing\Router::toResponse() évalue d’abord Responsable et appelle $response->toResponse($request).
  • Illuminate\Http\Resources\Json\JsonResource implémente Responsable : vous pouvez faire directement return UserResource::make($user); depuis un contrôleur.

Intérêt pour le développement de packages

  • Éviter d’assembler les tableaux dans le contrôleur en déléguant la génération de la réponse à un objet.
  • Faciliter le style « je retourne le DTO tel quel », en séparant représentation HTTP et représentation métier.

Guide de choix des implémentations

1

Vous voulez transformer en tableau pour réutilisation

Implémentez Arrayable et concentrez la logique de normalisation dans toArray().
2

Vous voulez maîtriser la représentation JSON

Implémentez Jsonable et explicitez le format de sortie dans toJson($options).
3

Vous voulez manipuler des fragments HTML

Implémentez Htmlable et retournez la chaîne de rendu depuis toHtml().
4

Vous voulez retourner directement une réponse HTTP

Implémentez Responsable et concentrez la responsabilité dans toResponse($request).

Pages à lire ensuite

Trait Macroable

Découvrez le pattern d’extension permettant d’ajouter des méthodes personnalisées aux classes existantes.

Trait Conditionable

Découvrez la conception de branchement conditionnel avec when() / unless().

Helper tap() / Tappable

Découvrez le pattern de chaînage renvoyant la valeur tout en glissant un effet de bord.

Trait Dumpable

Découvrez comment intégrer dump() / dd() à vos objets pour le débogage.
Dernière modification le 13 juillet 2026