في نوفمبر 2024، أصدرت PHP نسختها 8.4 — تحديث رئيسي يُدخل property hooks، الرؤية اللامتماثلة، دوالّ مصفوفات جديدة، وواجهة BCMath موجَّهة كائنيًّا. قبل بضعة أشهر، في مارس 2024، أعاد Laravel 11 رسم معماريّته الداخلية: ملفّ bootstrap/app.php مُعَاد تصميمه كمركز إعدادات، AppServiceProvider وحيد، وروابط API صارت اختيارية. لمطوّر يكتشف أو يُعَمِّق هذه الثنائية في 2025، فهم هذين التطوّرين بعمق هو الفرق بين تحمّل framework وإتقان كلّ طبقاته.
يُعطيك هذا الدليل الأسس المتينة للعمل مع Laravel 11 وPHP 8.4: كيف تُثَبِّت البيئة على Ubuntu أو Debian أو Windows، لماذا بنية المشروع خُفِّفت، وكيف تتمحور كلّ لبنة من الـ framework حول ملفّ الإعداد المركزي الجديد. كلّ قسم يُوَثِّق ليس فقط الأوامر الدقيقة، بل أيضًا المخرجات المتوقّعة، إشارات النجاح، والاستدلال خلف كلّ خيار معماري.
الدلائل الستّة لهذه السلسلة تُغَطّي طيفًا أوسع: إنشاء API REST، Eloquent ORM متقدّم، استيثاق Sanctum، queues غير متزامنة، واختبارات بـ Pest. هذا الدليل هو نقطة انطلاقك ومرجعك الدائم.
لماذا تُغَيِّر PHP 8.4 قواعد التطوير الحديث
PHP تحتفل في 2024 بـ 30 سنة من الوجود — والنسخة 8.4 بلا شكّ من أكثرها هيكلية في العقد. لا تجلب فقط أداءً مرتفعًا (نحو 5 إلى 10% مكسب على benchmarks ويب واقعية)، بل تُدخل تراكيب لغوية تُقَرِّب PHP من الأنماط الحديثة في Kotlin أو C# أو TypeScript.
أبرز ميزة بلا منازع property hooks. قبل PHP 8.4، كائن بمنطق قراءة/كتابة على خاصية كان يتطلّب دوالّ getX()/setX() صريحة، ممّا يُثَقِّل الكود والواجهة العامّة. property hooks تُتيح الآن دمج هذا المنطق مباشرة في إعلان الخاصية، دون كسر التوافق العكسي. لـ Laravel، هذا يفتح الطريق لنماذج Eloquent أكثر تعبيرًا، DTOs أكثر اختزالًا، وValue Objects بلا سباكة.
الرؤية اللامتماثلة تحلّ مشكلة كلاسيكية: جعل خاصية للقراءة العامّة لكن للكتابة الخاصّة كان يتطلّب getters. PHP 8.4 يُدخل صياغة public private(set). الدوالّ الجديدة (array_find()، array_find_key()، array_any()، array_all()) تسدّ نقصًا. الصياغة المُخَفَّفة لإنشاء الكائنات (new Foo()->method() دون أقواس) تُحسِّن قراءة سلاسل النداءات.
1. Property Hooks — خصائص ذكية
<?php
class UserProfile
{
// Hook set: تطبيع البريد إلى أحرف صغيرة تلقائيًّا
public string $email {
set(string $value) {
$this->email = strtolower(trim($value));
}
}
// Hook get: حساب الاسم الكامل على الطلب
public string $fullName {
get => trim("{$this->firstName} {$this->lastName}");
}
public function __construct(
public string $firstName,
public string $lastName,
) {}
}
$profile = new UserProfile('Mohamed', 'Al-Saidi');
$profile->email = ' Mohamed@Example.Com ';
echo $profile->email; // mohamed@example.com (مُطَبَّع تلقائيًّا)
echo $profile->fullName; // Mohamed Al-Saidi (محسوب على الطلب)
ما يفعله الكود فعلًا: عند الإسناد $profile->email = '...'، يستدعي PHP تلقائيًّا hook set الذي يُطَبِّق strtolower(trim()) قبل تخزين القيمة. لـ $fullName، hook get يُشَغَّل مع كلّ قراءة ويبني الاسم الكامل دون تخزين بيانات زائدة.
2. الرؤية اللامتماثلة — تغليف دقيق
<?php
class InvoiceStatus
{
// قابل للقراءة من كلّ مكان، قابل للتعديل فقط من نفس الـ class
public private(set) string $status = 'draft';
public private(set) DateTimeImmutable $updatedAt;
public function __construct()
{
$this->updatedAt = new DateTimeImmutable();
}
public function submit(): void
{
$this->status = 'submitted'; // مسموح — نفس class
$this->updatedAt = new DateTimeImmutable(); // مسموح — نفس class
}
}
$invoice = new InvoiceStatus();
echo $invoice->status; // 'draft' — قراءة عامّة OK
$invoice->status = 'paid'; // ⚠️ Error: Cannot modify private(set) property
3. دوالّ مصفوفات جديدة
<?php
$users = [
['name' => 'Alice', 'role' => 'admin', 'active' => true],
['name' => 'Bob', 'role' => 'user', 'active' => false],
['name' => 'Carol', 'role' => 'admin', 'active' => true],
];
$firstAdmin = array_find($users, fn($u) => $u['role'] === 'admin' && $u['active']);
$adminKey = array_find_key($users, fn($u) => $u['role'] === 'admin' && $u['active']);
$hasActiveAdmin = array_any($users, fn($u) => $u['role'] === 'admin' && $u['active']);
$allActive = array_all($users, fn($u) => $u['active']);
4. إنشاء كائن مُبَسَّط
// قبل PHP 8.4
$result = (new QueryBuilder())->from('users')->where('active', true)->get();
// PHP 8.4+
$result = new QueryBuilder()->from('users')->where('active', true)->get();
المعمارية الجديدة لـ Laravel 11: ما يتغيّر فعلًا
Laravel 11، الصادر في 12 مارس 2024، نتيجة جهد لتخفيف البنية الافتراضية لمشروع Laravel. الفلسفة: توليد فقط الكود الذي تحتاجه فعلًا، ومركزة الإعداد في أقلّ ما يمكن من الملفّات.
bootstrap/app.php يصير مركز الإعداد
<?php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
$middleware->append(EnsureJsonResponse::class);
$middleware->validateCsrfTokens(except: ['stripe/*']);
})
->withExceptions(function (Exceptions $exceptions) {
$exceptions->render(function (ModelNotFoundException $e) {
return response()->json(['error' => 'Resource not found'], 404);
});
})->create();
هذا الملفّ يحلّ وحده محلّ Kernel.php HTTP القديم ومعظم إعداد service providers. مكسب القراءة فوري: كلّ ما يضبط السلوك الأساسي في ملفّ واحد.
AppServiceProvider واحد
Laravel 10 كان يُنشئ خمسة service providers (AuthServiceProvider، BroadcastServiceProvider، EventServiceProvider، RouteServiceProvider، AppServiceProvider). في Laravel 11، يُولَّد AppServiceProvider وحده. كلّ تسجيلات policies وevents وroutes تمرّ به أو بـ bootstrap/app.php.
routes API بـ opt-in
إحدى الحذوفات الأبرز: routes/api.php لم يعد يُنشَأ افتراضيًّا. Laravel 11 ينطلق من أنّ كلّ التطبيقات ليست APIs. لإنشاء routes API وتثبيت Sanctum في الوقت ذاته:
php artisan install:api
هذا الأمر يُنشئ routes/api.php، يُثَبِّت Laravel Sanctum، ينشر هجراته وينفّذها.
scheduling في routes/console.php
<?php
use Illuminate\Support\Facades\Schedule;
Schedule::command('emails:send')->dailyAt('08:00');
Schedule::command('sanctum:prune-expired --hours=24')->hourly();
Schedule::call(function () {
App\Models\Report::generateDailyStats();
})->everyFiveMinutes();
تثبيت PHP 8.4 على Ubuntu وDebian
Ubuntu 22.04 LTS (Jammy) و24.04 LTS (Noble) لا تُسَلِّم PHP 8.4 في مستودعاتها الرسمية افتراضيًّا. الطريقة الموصى بها PPA Ondřej Surý.
# 1. إضافة PPA Ondřej Surý (المصدر الرسمي لـ PHP على Debian/Ubuntu)
sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
# 2. تثبيت PHP 8.4 مع الامتدادات اللازمة لـ Laravel
sudo apt-get install -y php8.4-cli php8.4-fpm php8.4-common php8.4-mbstring \
php8.4-xml php8.4-curl php8.4-zip php8.4-mysql php8.4-pgsql php8.4-sqlite3 \
php8.4-redis php8.4-bcmath php8.4-intl php8.4-gd
# 3. تحقّق
php -v
الأمر php -v يجب أن يُرجع PHP 8.4.x (cli). إن كانت لديك عدّة نسخ مثبَّتة:
sudo update-alternatives --set php /usr/bin/php8.4
php --version
لـ Nginx + PHP-FPM، تأكّد من توجيه socket: fastcgi_pass unix:/run/php/php8.4-fpm.sock;. ثم sudo systemctl restart php8.4-fpm.
تثبيت PHP 8.4 على Windows
# الخيار 1: تفعيل WSL2 (موصى به — افتح PowerShell كمدير)
wsl --install
# أعد تشغيل Windows، ثم اختر Ubuntu من Microsoft Store
# الخيار 2: تثبيت أصلي عبر Chocolatey
choco install php --version=8.4.0
php -v
لحلّ شامل، Laravel Herd (herd.laravel.com) هو البيئة الرسمية الموصى بها من فريق Laravel. يُثَبِّت PHP 8.4 تلقائيًّا، يُنشئ مواقع .test محلّية، ويُدير نسخ PHP لكلّ مشروع ببضع نقرات.
تثبيت Composer 2.x
# تنزيل سكريبت التثبيت الرسمي
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
# التحقّق من سلامة السكريبت
HASH=$(curl -sS https://composer.github.io/installer.sig)
php -r "
if (hash_file('sha384', 'composer-setup.php') === '$HASH') {
echo 'Installer verified' . PHP_EOL;
} else {
echo 'Installer CORRUPT' . PHP_EOL;
unlink('composer-setup.php');
exit(1);
}
"
# تنفيذ التثبيت
php composer-setup.php
php -r "unlink('composer-setup.php');"
sudo mv composer.phar /usr/local/bin/composer
composer --version
إنشاء أوّل مشروع Laravel 11
# الطريقة 1: عبر Composer
composer create-project laravel/laravel mon-projet "11.*"
cd mon-projet
# الطريقة 2: عبر installer Laravel (موصى بها، wizard تفاعلي)
composer global require laravel/installer
laravel new mon-projet
cd mon-projet
# انسخ ملفّ البيئة المثال
cp .env.example .env
# ولِّد مفتاح التطبيق
php artisan key:generate
# تحقّق من إقلاع التطبيق
php artisan serve
# المخرج المتوقّع: INFO Server running on [http://127.0.0.1:8000]
افتح http://127.0.0.1:8000. إن رأيت صفحة ترحيب Laravel، بيئتك تعمل.
بنية مشروع Laravel 11 مشروحة
مشروع Laravel 11 حديث الإنشاء يحوي ملفّات أقلّ من سابقيه، لكن لكلّ مجلّد دور دقيق.
مجلّد app/ يحوي كودك التطبيقي. خلافًا لـ Laravel 10، مجلّدات Policies وRules وJobs وMail وNotifications وEvents لم تعد تُنشَأ افتراضيًّا — تظهر فقط عند توليدها عبر Artisan.
bootstrap/app.php هو الملفّ المهمّ الوحيد في هذا المجلّد. config/ يضمّ كلّ ملفّات الإعداد لكنّها لا تُنشَر في مشروعك إلّا إن عدّلتها. database/ يحوي migrations وfactories وseeders. routes/ يحوي web.php وconsole.php — api.php لا يُنشَأ إلّا بعد php artisan install:api.
أوامر Artisan الأساسية
# توليد الكود
php artisan make:model Article -m # نموذج + migration
php artisan make:model Article -mfsc # نموذج + migration + factory + seeder + controller
php artisan make:controller ArticleController --api
php artisan make:request StoreArticleRequest
php artisan make:job ProcessEmail
php artisan make:middleware EnsureIsAdmin
# قاعدة البيانات
php artisan migrate
php artisan migrate:fresh --seed # ⚠️ يمسح كلّ شيء
php artisan db:seed
php artisan migrate:rollback
# أدوات
php artisan route:list
php artisan model:show Article # جديد L11: فحص نموذج
php artisan config:cache # إنتاج
php artisan route:cache # إنتاج
php artisan cache:clear
php artisan tinker # REPL تفاعلي
الدلائل الستّة لهذه السلسلة
- إنشاء API REST بـ Laravel 11 — routes API، controllers ressource، تحقّق، JSON منظَّم، versioning.
- إتقان Eloquent ORM في Laravel 11 — العلاقات، scopes، casts، HasUuids، N+1.
- الاستيثاق بـ Laravel Sanctum — tokens API، حماية routes، SPA، token abilities.
- Queues وjobs Laravel 11 — drivers، إنشاء jobs، dispatch، retry، Supervisor وHorizon.
- اختبار تطبيقك بـ Pest — Pest 3، اختبارات وحدوية ووظيفية، Sanctum::actingAs.
أخطاء شائعة
| الخطأ | السبب | الحلّ |
|---|---|---|
| APP_KEY فارغ ← خطأ تشفير | نسيان php artisan key:generate |
شَغِّل دائمًا key:generate عند الإنشاء أو الـ clone |
| routes API لا تُوجَد (404) | نسيان php artisan install:api |
شَغِّل install:api ثم عَرِّف routes في routes/api.php |
| امتدادات PHP مفقودة | تثبيت PHP بحدّ أدنى | ثبِّت كلّ الامتدادات المُدرَجة أعلاه |
| Composer قديم ← تعارضات | تثبيت قديم | composer self-update |
| الخلط L11 vs L10 | هجرة دون قراءة مذكّرة الترقية | اقرأ laravel.com/docs/11.x/upgrade |
| scheduling لا يعمل | نسيان cron | أضف: * * * * * cd /var/www && php artisan schedule:run >> /dev/null 2>&1 |
FAQ
هل Laravel 11 يتطلّب PHP 8.4 قطعًا؟ لا. Laravel 11 يتطلّب PHP 8.2 كحدّ أدنى ويدعم 8.3 و8.4. PHP 8.4 ليس إلزاميًّا لكنّه يجلب property hooks والرؤية اللامتماثلة.
أيمكنني هجرة مشروع Laravel 10 إلى 11؟ نعم، لكنّ الهجرة ليست تلقائية. اقرأ laravel.com/docs/11.x/upgrade.
مدّة دعم Laravel 11؟ إصلاحات الأخطاء حتى 3 سبتمبر 2025 وإصلاحات الأمن حتى 12 مارس 2026.
PHP 8.4 متاح على كلّ المضيفين المشتركين؟ ليس عالميًّا بعد. VPS (DigitalOcean، Hetzner، OVH) تُتيح التثبيت عبر PPA Ondřej.
Composer 2.x متوافق عكسيًّا مع 1.x؟ Composer 2.x أسرع محسوسًا ويُدير صحيحًا كلّ حزم 1.x. الهجرة شفّافة.
كيف نُدير عدّة نسخ PHP على نفس الخادم؟ مع PPA Ondřej، النسخ قابلة للتعايش. استعمل php8.2 artisan serve أو php8.4 artisan serve.
مراجع
- إعلان PHP 8.4 الرسمي — php.net
- ملاحظات إصدار Laravel 11 — laravel.com
- دليل الهجرة Laravel 10 ← 11 — laravel.com
- تثبيت Composer — getcomposer.org
- PPA PHP Ondřej Surý — launchpad.net
- Laravel Herd — البيئة المحلّية الرسمية