> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-vortex-format.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Utiliser Laravel avec ClickHouse Managed Postgres

> Connectez une application Laravel à ClickHouse Managed Postgres via PgBouncer, exécutez des migrations et interrogez vos données avec Eloquent sur une connexion TLS vérifiée

export const BetaBadge = ({link, galaxyTrack, galaxyEvent}) => {
  if (link) {
    return <a href={link} target="_blank" rel="noopener noreferrer" className="betaBadge" onClick={galaxyTrack && galaxyEvent ? galaxyOnClick(galaxyEvent) : undefined}>
                <span>Beta</span>
            </a>;
  }
  return <a href="https://clickhouse.com/docs/reference/settings/beta-and-experimental-features#beta-features" className="betaBadge">
            <span>Fonctionnalité en bêta</span>
        </a>;
};

<BetaBadge link="https://clickhouse.com/cloud/postgres" galaxyTrack={true} galaxyEvent="docs.managed-postgres.guides-laravel-beta" />

[Laravel](https://laravel.com/) est un framework web PHP doté d'un ORM intégré (Eloquent), d'un système de migrations et de l'outil en ligne de commande `artisan`. Dans ce guide, vous connectez une nouvelle application Laravel à ClickHouse Managed Postgres, créez une table `tasks` au moyen d'une migration, puis exposez ses lignes via une route. Toutes les connexions utilisent TLS avec une vérification complète des certificats.

<h2 id="prerequisites">
  Prérequis
</h2>

* PHP 8.3 ou une version ultérieure, requis par Laravel 13, avec l'extension `pdo_pgsql`. Exécutez `php -m` et vérifiez que `pdo_pgsql` figure dans la liste.
* [Composer](https://getcomposer.org/)
* Un compte ClickHouse Cloud
* [`psql`](https://www.postgresql.org/download/), pour créer la base de données. Vous pouvez également exécuter le statement `CREATE DATABASE` dans la [console SQL](/fr/integrations/connectors/sql-clients/sql-console).

<h2 id="create-service">
  Créer un service ClickHouse Managed Postgres
</h2>

Dans la console ClickHouse Cloud, cliquez sur **New service** et sélectionnez **Postgres**. L'instance est prête en quelques minutes. Pour une présentation pas à pas, consultez le [guide de démarrage rapide](/fr/products/managed-postgres/quickstart).

<h2 id="connection-details">
  Obtenir vos informations de connexion
</h2>

Cliquez sur **Connect** dans la barre latérale gauche de votre service. La fenêtre modale affiche votre nom d'utilisateur, votre mot de passe, le serveur et le port, ainsi qu'un sélecteur **Directly** / **via PgBouncer**.

Une application PHP ne conserve pas de pool de connexions d'une requête à l'autre. Par défaut, chaque requête ouvre une nouvelle connexion Postgres, puis la ferme une fois terminée. Dans ce guide, l'application se connecte via le [PgBouncer](/fr/products/managed-postgres/connection#pgbouncer) intégré sur le port `6432`, afin que ces connexions éphémères se partagent un petit nombre de processus backend Postgres. Les migrations, elles, se connectent directement à Postgres sur le port `5432`, car elles exécutent du DDL et peuvent maintenir des transactions longues.

Sélectionnez **via PgBouncer** pour afficher les informations de connexion mutualisée. Le port passe à `6432` et les chaînes de connexion incluent `sslmode=verify-full`.

Dans la même fenêtre modale, cliquez sur **Download CA certificate**. Vous pouvez également le télécharger depuis **Settings → CA Certificate**. Ce certificat étant propre à votre instance, le driver peut l'utiliser pour vérifier qu'il communique bien avec votre serveur.

<h2 id="project-setup">
  Configurer le projet
</h2>

Créez un projet Laravel :

```bash theme={null}
composer create-project laravel/laravel laravel-managed-postgres
cd laravel-managed-postgres
```

<Tip>
  **Vous l'intégrez à une application existante ?**

  Ignorez `composer create-project`. Dans votre projet, vérifiez que `pdo_pgsql` figure dans la sortie de `php -m`, puis suivez le reste de cette section avant de passer à [Configurer la connexion](#configure), qui fait basculer l'application de SQLite vers Postgres. `php artisan migrate` crée ensuite vos tables existantes dans Postgres, mais ne copie pas les données depuis SQLite.
</Tip>

Déplacez le certificat de CA que vous avez téléchargé dans le répertoire du projet et renommez-le en `ca-certificate.pem`.

Créez une base de données pour l'application. Remplacez `<PASSWORD>` et l'hôte par les valeurs indiquées dans la fenêtre modale **Connect** :

```bash theme={null}
psql "postgresql://postgres:<PASSWORD>@your-instance.pg.clickhouse.cloud:5432/postgres?sslmode=verify-full&sslrootcert=ca-certificate.pem" -c "CREATE DATABASE guide_laravel;"
```

```text theme={null}
CREATE DATABASE
```

<h2 id="configure">
  Configurer la connexion
</h2>

Laravel utilise SQLite par défaut. Ouvrez `.env` et remplacez la ligne `DB_CONNECTION=sqlite`, ainsi que les lignes `DB_` commentées qui la suivent, par :

```bash title=".env" theme={null}
DB_CONNECTION=pgsql
DB_HOST=your-instance.pg.clickhouse.cloud
DB_PORT=6432
DB_DATABASE=guide_laravel
DB_USERNAME=postgres
DB_PASSWORD=<PASSWORD>
DB_SSLMODE=verify-full
DB_SSLROOTCERT=/absolute/path/to/your-project/ca-certificate.pem
```

Utilisez le chemin absolu vers `ca-certificate.pem`. `libpq` résout un chemin relatif par rapport au répertoire de travail du processus PHP, lequel dépend de la manière dont PHP exécute votre application. Si votre mot de passe contient des espaces ou le caractère `#`, placez-le entre guillemets doubles. Excluez `.env` du contrôle de version.

La connexion `pgsql` par défaut définie dans `config/database.php` lit `DB_SSLMODE`, mais pas le chemin du certificat de CA. Ouvrez `config/database.php` et ajoutez les entrées `sslrootcert` et `options` à la connexion `pgsql` :

```php title="config/database.php" theme={null}
        'pgsql' => [
            'driver' => 'pgsql',
            'url' => env('DB_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '5432'),
            'database' => env('DB_DATABASE', 'laravel'),
            'username' => env('DB_USERNAME', 'root'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => env('DB_CHARSET', 'utf8'),
            'prefix' => '',
            'prefix_indexes' => true,
            'search_path' => 'public',
            'sslmode' => env('DB_SSLMODE', 'prefer'),
            'sslrootcert' => env('DB_SSLROOTCERT'),
            'options' => [
                PDO::ATTR_EMULATE_PREPARES => true,
            ],
        ],
```

Laravel ajoute `sslmode` et `sslrootcert` au DSN PDO, et l’extension `pdo_pgsql` les transmet à `libpq`, qui vérifie la chaîne de certificats et le nom d’hôte.

`PDO::ATTR_EMULATE_PREPARES` indique à PDO d’envoyer chaque requête avec ses valeurs déjà liées, au lieu de créer un prepared statement côté serveur. Activez cette option lorsque vous vous connectez via PgBouncer. Lorsque `pdo_pgsql` est compilé avec `libpq` 16 ou une version antérieure, par exemple sous Debian 12, PHP libère chaque prepared statement à l’aide d’un statement SQL `DEALLOCATE`. Comme PgBouncer renomme les prepared statements sur le serveur, le `DEALLOCATE` échoue. Au sein d’une transaction, cet échec interrompt la transaction, et la requête suivante échoue avec l’erreur `current transaction is aborted`. Avec `libpq` 17 ou une version ultérieure, les paramètres par défaut fonctionnent également. Exécutez `php -i | grep libpq` pour connaître votre version.

Vérifiez la connexion :

```bash theme={null}
php artisan db:show
```

```text theme={null}
  PostgreSQL ................................ 18.6 (Ubuntu 18.6-1.pgdg22.04+2)  
  Connection ........................................................... pgsql  
  Database ..................................................... guide_laravel  
  Host ..................................... your-instance.pg.clickhouse.cloud  
  Port .................................................................. 6432  
  Username .......................................................... postgres  
  URL ........................................................................  
  Open Connections ........................................................ 44  
  Tables ................................................................... 0  
```

<Note>
  Sans la ligne `sslrootcert`, `verify-full` échoue avec l'erreur `root certificate file ".../.postgresql/root.crt" does not exist`, car `libpq` utilise alors l'emplacement par défaut de son autorité de certification (CA). Si la CA est incorrecte, la connexion échoue avec l'erreur `SSL error: certificate verify failed`.
</Note>

<h2 id="migrations">
  Créer un modèle et une migration
</h2>

Générez un modèle Eloquent et une migration pour une table `tasks` :

```bash theme={null}
php artisan make:model Task -m
```

Ouvrez la nouvelle migration dans `database/migrations/` (son nom se termine par `_create_tasks_table.php`) et ajoutez les colonnes `title` et `done` dans la méthode `up` :

```php title="database/migrations/xxxx_xx_xx_xxxxxx_create_tasks_table.php" theme={null}
    public function up(): void
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->boolean('done')->default(false);
            $table->timestamps();
        });
    }
```

Remplacez le contenu de `app/Models/Task.php` afin que les colonnes puissent être affectées en masse et que `done` soit renvoyé sous forme de booléen :

```php title="app/Models/Task.php" theme={null}
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Model;

#[Fillable(['title', 'done'])]
class Task extends Model
{
    protected function casts(): array
    {
        return [
            'done' => 'boolean',
        ];
    }
}
```

Exécutez les migrations via la connexion directe. Une variable d'environnement a priorité sur la valeur définie dans `.env` : il vous suffit donc de modifier le port :

```bash theme={null}
DB_PORT=5432 php artisan migrate
```

```text theme={null}
   INFO  Preparing database.  

  Creating migration table ..................................... 289.95ms DONE

   INFO  Running migrations.  

  0001_01_01_000000_create_users_table ............................... 1s DONE
  0001_01_01_000001_create_cache_table ......................... 949.69ms DONE
  0001_01_01_000002_create_jobs_table ................................ 1s DONE
  2026_09_30_165735_create_tasks_table ......................... 240.59ms DONE
```

Outre `tasks`, cette commande crée les tables `users`, `sessions`, `cache` et `jobs` qu'une nouvelle application Laravel utilise par défaut. Laravel consigne les migrations déjà appliquées dans la table `migrations` et, lors des exécutions suivantes, n'exécute que les nouvelles.

<h2 id="query">
  Interroger la base de données
</h2>

Ajoutez quelques lignes avec Eloquent depuis `artisan tinker` :

```bash theme={null}
php artisan tinker --execute="App\Models\Task::create(['title' => 'Create a Managed Postgres service', 'done' => true]); App\Models\Task::create(['title' => 'Connect Laravel with verify-full TLS', 'done' => true]); App\Models\Task::create(['title' => 'Ship the app']); echo App\Models\Task::count();"
```

```text theme={null}
3
```

Ajoutez à la fin de `routes/web.php` une route qui renvoie toutes les tâches au format JSON :

```php title="routes/web.php" theme={null}
Route::get('/tasks', function () {
    return App\Models\Task::orderBy('id')->get();
});
```

<Note>
  Laravel applique les options de connexion `search_path`, `timezone` et `isolation_level` au moyen de statements `SET` de niveau session lors de la connexion, et celles-ci ne sont pas conservées d'une transaction à l'autre via PgBouncer. Conservez les valeurs par défaut de ces options, ou connectez-vous directement sur le port `5432` si vous en avez besoin. Les fonctionnalités liées à la session, telles que `LISTEN` et les verrous consultatifs (advisory locks) de session, ne fonctionnent pas non plus via PgBouncer. Consultez la [FAQ](/fr/products/managed-postgres/faq#prepared-statement-errors).
</Note>

<h2 id="verify">
  Exécuter et vérifier
</h2>

Démarrez le serveur de développement :

```bash theme={null}
php artisan serve --port=3104
```

```text theme={null}
   INFO  Server running on [http://127.0.0.1:3104].  

  Press Ctrl+C to stop the server
```

Ouvrez `http://localhost:3104/tasks` dans votre navigateur. Vous devriez obtenir une réponse semblable à celle-ci :

```json theme={null}
[
  {
    "id": 1,
    "title": "Create a Managed Postgres service",
    "done": true,
    "created_at": "2026-09-30T17:10:28.000000Z",
    "updated_at": "2026-09-30T17:10:28.000000Z"
  },
  {
    "id": 2,
    "title": "Connect Laravel with verify-full TLS",
    "done": true,
    "created_at": "2026-09-30T17:10:29.000000Z",
    "updated_at": "2026-09-30T17:10:29.000000Z"
  },
  {
    "id": 3,
    "title": "Ship the app",
    "done": false,
    "created_at": "2026-09-30T17:10:29.000000Z",
    "updated_at": "2026-09-30T17:10:29.000000Z"
  }
]
```

Pour afficher les données dans la console, ouvrez **console SQL** dans la barre latérale gauche de votre service, développez `guide_laravel` puis `public`, et cliquez sur la table `tasks`. Le schéma `public` contient également les tables Laravel par défaut, comme `users`, `sessions` et `migrations` :

| id | title | done | created\_at | updated\_at |
| - | - | - | - | - |
| 1 | Create a Managed Postgres service | true | 2026-09-30 17:10:28 | 2026-09-30 17:10:28 |
| 2 | Connect Laravel with verify-full TLS | true | 2026-09-30 17:10:29 | 2026-09-30 17:10:29 |
| 3 | Ship the app | false | 2026-09-30 17:10:29 | 2026-09-30 17:10:29 |

<h2 id="next-steps">
  Étapes suivantes
</h2>

* [Connexion](/fr/products/managed-postgres/connection) : chaînes de connexion, PgBouncer et TLS
* [Paramètres](/fr/products/managed-postgres/settings) : paramètres de Postgres et de PgBouncer, tels que `max_connections`
* [Répliques en lecture](/fr/products/managed-postgres/read-replicas) : redirigez les lectures vers une réplique à l'aide des [connexions en lecture et en écriture](https://laravel.com/docs/database#read-and-write-connections) de Laravel
* [Sécurité](/fr/products/managed-postgres/security) : listes d'accès IP et réseau privé
