> ## 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.

# استخدام Laravel مع ClickHouse Managed Postgres

> اربط تطبيق Laravel بخدمة ClickHouse Managed Postgres عبر PgBouncer، وشغّل عمليات الترحيل، ونفّذ الاستعلامات باستخدام Eloquent عبر اتصال TLS مُتحقَّق منه

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>ميزة Beta</span>
        </a>;
};

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

[Laravel](https://laravel.com/) هو إطار عمل ويب بلغة PHP يتضمن أداة مدمجة لربط الكائنات بقواعد البيانات (Eloquent)، ونظامًا لعمليات الترحيل (migrations)، وأداة سطر الأوامر `artisan`. في هذا الدليل، ستربط تطبيق Laravel جديدًا بخدمة ClickHouse Managed Postgres، وتنشئ جدول `tasks` عبر عملية ترحيل، ثم تعرض صفوفه من خلال مسار (route). تستخدم جميع الاتصالات بروتوكول TLS مع تحقق كامل من الشهادة.

<h2 id="prerequisites">
  المتطلبات الأساسية
</h2>

* PHP 8.3 أو إصدار أحدث، وهو ما يتطلبه Laravel 13، مع تثبيت الامتداد `pdo_pgsql`. شغّل الأمر `php -m` وتحقّق من ظهور `pdo_pgsql` في القائمة.
* [Composer](https://getcomposer.org/)
* حساب على ClickHouse Cloud
* [`psql`](https://www.postgresql.org/download/)، لإنشاء قاعدة البيانات. ويمكنك بدلًا من ذلك تشغيل عبارة `CREATE DATABASE` في [SQL console](/ar/integrations/connectors/sql-clients/sql-console).

<h2 id="create-service">
  إنشاء خدمة ClickHouse Managed Postgres
</h2>

في وحدة تحكم ClickHouse Cloud، انقر على **New service** ثم اختر **Postgres**. سيصبح المثيل جاهزًا في غضون دقائق قليلة. للاطلاع على شرح تفصيلي للخطوات، راجع [دليل البدء السريع](/ar/products/managed-postgres/quickstart).

<h2 id="connection-details">
  الحصول على بيانات الاتصال
</h2>

انقر على **Connect** في الشريط الجانبي الأيسر لخدمتك. تعرض النافذة المنبثقة اسم المستخدم وكلمة المرور والخادم والمنفذ، وتتضمن مفتاح تبديل بين **Directly** و**via PgBouncer**.

لا يحتفظ تطبيق PHP بمجمّع اتصالات بين الطلبات، إذ يفتح كل طلب افتراضيًا اتصالًا جديدًا بـ Postgres ويغلقه عند انتهائه. يربط هذا الدليل التطبيق عبر [PgBouncer](/ar/products/managed-postgres/connection#pgbouncer) المضمَّن على المنفذ `6432`، لكي تتشارك هذه الاتصالات قصيرة العمر عددًا محدودًا من عمليات Postgres الخلفية. أما عمليات الترحيل فتتصل بـ Postgres مباشرةً على المنفذ `5432`، لأنها تنفّذ أوامر DDL وقد تُبقي معاملات طويلة مفتوحة.

اختر **via PgBouncer** لعرض بيانات الاتصال عبر المجمّع. سيتغير المنفذ إلى `6432`، وستتضمن سلاسل الاتصال `sslmode=verify-full`.

في النافذة المنبثقة نفسها، انقر على **Download CA certificate**. ويمكنك أيضًا تنزيلها من **Settings → CA Certificate**. هذه الشهادة فريدة لمثيلك، ما يتيح للمشغّل استخدامها للتحقق من أنه يتصل بخادمك فعلًا.

<h2 id="project-setup">
  إعداد المشروع
</h2>

أنشئ مشروع Laravel:

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

<Tip>
  **هل تضيف إلى تطبيق موجود؟**

  تخطَّ `composer create-project`. في مشروعك، تحقّق من أن `pdo_pgsql` يظهر ضمن مخرجات `php -m`، ثم اتبع بقية هذا القسم وانتقل بعدها إلى [تهيئة الاتصال](#configure)، إذ تنقل هذه الخطوة التطبيق من SQLite إلى Postgres. بعد ذلك، ينشئ الأمر `php artisan migrate` جداولك الحالية في Postgres، لكنه لا ينسخ البيانات من SQLite.
</Tip>

انقل شهادة CA التي نزّلتها إلى دليل المشروع، وأعد تسميتها إلى `ca-certificate.pem`.

أنشئ قاعدة بيانات للتطبيق. استبدل `<PASSWORD>` والمضيف بالقيم الظاهرة في نافذة **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">
  تهيئة الاتصال
</h2>

يستخدم Laravel قاعدة بيانات SQLite افتراضيًا. افتح الملف `.env` واستبدل السطر `DB_CONNECTION=sqlite` وأسطر `DB_` المعطَّلة بعلامة التعليق أسفله بما يلي:

```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
```

استخدم المسار المطلق للملف `ca-certificate.pem`، إذ تحلّ `libpq` المسار النسبي انطلاقًا من دليل العمل الخاص بعملية PHP، وهذا الدليل يتوقف على طريقة تشغيل PHP لتطبيقك. إذا كانت كلمة المرور تحتوي على مسافات أو على الرمز `#`، فضعها بين علامتي اقتباس مزدوجتين. واحرص على إبقاء الملف `.env` خارج نظام التحكم في الإصدارات.

يقرأ اتصال `pgsql` الافتراضي في `config/database.php` القيمة `DB_SSLMODE`، لكنه لا يقرأ مسار شهادة CA. لذا افتح `config/database.php` وأضف العنصرين `sslrootcert` و`options` إلى الاتصال `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 المعاملين `sslmode` و`sslrootcert` بسلسلة DSN الخاصة بـ PDO، ثم يمرّرهما الامتداد `pdo_pgsql` إلى `libpq`، الذي يتحقق بدوره من سلسلة الشهادات ومن اسم المضيف.

يجعل الخيار `PDO::ATTR_EMULATE_PREPARES` مكتبة PDO ترسل كل استعلام وقيمه مربوطة به مسبقًا، بدلًا من إنشاء عبارة مُعدّة مسبقًا على جانب الخادم. فعّل هذا الخيار عند الاتصال عبر PgBouncer؛ إذ عندما يكون `pdo_pgsql` مبنيًا على الإصدار 16 من `libpq` أو ما قبله، كما هو الحال في Debian 12، تحرّر PHP كل عبارة مُعدّة مسبقًا باستخدام عبارة SQL `DEALLOCATE`. ولأن PgBouncer يعيد تسمية العبارات المُعدّة مسبقًا على الخادم، تفشل عبارة `DEALLOCATE`. وإذا وقع ذلك داخل معاملة، أُلغيت المعاملة، وفشل الاستعلام التالي مع الخطأ `current transaction is aborted`. أما مع الإصدار 17 من `libpq` أو ما بعده، فتعمل الإعدادات الافتراضية كذلك. نفّذ الأمر `php -i | grep libpq` لمعرفة الإصدار المثبّت لديك.

تحقّق من الاتصال:

```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>
  في غياب السطر `sslrootcert`، يفشل الوضع `verify-full` بالرسالة `root certificate file ".../.postgresql/root.crt" does not exist`، لأن `libpq` يلجأ إلى موقع CA الافتراضي الخاص به. أما عند استخدام CA غير صحيحة، فيفشل الاتصال بالرسالة `SSL error: certificate verify failed`.
</Note>

<h2 id="migrations">
  إنشاء نموذج وملف ترحيل
</h2>

أنشئ نموذج Eloquent وملف ترحيل للجدول `tasks`:

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

افتح ملف الترحيل الجديد في `database/migrations/` (ينتهي اسمه بـ `_create_tasks_table.php`)، ثم أضف العمودين `title` و`done` إلى الدالة `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();
        });
    }
```

استبدل محتوى الملف `app/Models/Task.php` بما يلي، بحيث يمكن تعيين قيم الأعمدة دفعةً واحدة (mass assignment) وتُعاد قيمة `done` كقيمة منطقية (boolean):

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

شغّل عمليات الترحيل عبر الاتصال المباشر. تُقدَّم قيمة متغير البيئة على القيمة الموجودة في `.env`، لذا يكفي أن تغيّر المنفذ فقط:

```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
```

إلى جانب `tasks`، يُنشئ هذا الأمر جداول `users` و`sessions` و`cache` و`jobs` التي يستخدمها أي تطبيق Laravel جديد افتراضيًا. ويسجّل Laravel عمليات الترحيل المُطبَّقة في الجدول `migrations`، فلا يشغّل في الاستدعاءات اللاحقة إلا عمليات الترحيل الجديدة.

<h2 id="query">
  الاستعلام من قاعدة البيانات
</h2>

أضف بضعة صفوف باستخدام Eloquent من خلال `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
```

أضف في نهاية الملف `routes/web.php` مسارًا يُعيد جميع المهام بتنسيق JSON:

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

<Note>
  يطبّق Laravel خيارات الاتصال `search_path` و`timezone` و`isolation_level` عند الاتصال باستخدام عبارات `SET` على مستوى الـ session، ولا تُحفَظ هذه الإعدادات بين المعاملات عند المرور عبر PgBouncer. لذا أبقِ هذه الخيارات على قيمها الافتراضية، أو اتصل مباشرةً عبر المنفذ `5432` إذا كنت بحاجة إليها. كذلك لا تعمل عبر PgBouncer الميزاتُ المعتمدة على الـ session، مثل `LISTEN` والأقفال الاستشارية (advisory locks) على مستوى الـ session. راجع [الأسئلة الشائعة](/ar/products/managed-postgres/faq#prepared-statement-errors).
</Note>

<h2 id="verify">
  التشغيل والتحقق
</h2>

شغّل خادم التطوير:

```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
```

افتح `http://localhost:3104/tasks` في متصفحك، وستظهر لك استجابة مشابهة لما يلي:

```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"
  }
]
```

لعرض البيانات في وحدة التحكم، افتح **SQL console** من الشريط الجانبي الأيسر لخدمتك، ثم وسّع `guide_laravel` ثم `public`، وانقر على الجدول `tasks`. يتضمن المخطط `public` أيضًا جداول Laravel الافتراضية، مثل `users` و`sessions` و`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">
  الخطوات التالية
</h2>

* [الاتصال](/ar/products/managed-postgres/connection): سلاسل الاتصال وPgBouncer وTLS
* [الإعدادات](/ar/products/managed-postgres/settings): معلمات Postgres وPgBouncer، مثل `max_connections`
* [النسخ المتماثلة للقراءة](/ar/products/managed-postgres/read-replicas): توجيه عمليات القراءة إلى نسخة متماثلة باستخدام [اتصالات القراءة والكتابة](https://laravel.com/docs/database#read-and-write-connections) في Laravel
* [الأمان](/ar/products/managed-postgres/security): قوائم التحكم في الوصول بعناوين IP والشبكات الخاصة
