ما هو Doctrine ORM ولماذا تحتاجه؟
Doctrine ORM (Object-Relational Mapping) هي مكتبة قوية للغة PHP تتيح للمطورين التعامل مع قواعد البيانات باستخدام نهج البرمجة الكائنية (OOP) بدلاً من كتابة استعلامات SQL الخام. تُعتبر Doctrine ORM المعيار الفعلي لإطار Symfony، ولكن يمكن استخدامها أيضاً في أي مشروع PHP آخر (Laravel، Yii، أو PHP خالص).
المشكلة الأساسية التي تحلها Doctrine: عدم التوافق بين النموذج العلائقي للبيانات (جداول، صفوف، أعمدة) والنموذج الكائني (كلاسات، كائنات، خصائص). تقوم Doctrine تلقائياً بتحويل كائنات PHP إلى سجلات في قاعدة البيانات والعكس.
الميزات الرئيسية:
- إنشاء تلقائي لهيكل قاعدة البيانات — بناءً على التعليقات التوضيحية (Annotations) أو السمات (Attributes) في الكلاسات
- نمط المستودع (Repository Pattern) — طرق سهلة للبحث وتصفية البيانات
- DQL (Doctrine Query Language) — لغة استعلامات كائنية التوجه
- التحميل البطيء (Lazy Loading) — تحميل البيانات المرتبطة فقط عند الحاجة
- الترحيل (Migrations) — إدارة تغييرات هيكل قاعدة البيانات
- المعاملات (Transactions) — دعم كامل لخصائص ACID
- التخزين المؤقت (Caching) — للبيانات الوصفية والاستعلامات والنتائج
Doctrine ORM مناسبة للمشاريع من أي حجم: من المواقع الصغيرة إلى الأنظمة المؤسسية التي تحتوي على مئات الجداول.
تثبيت Doctrine ORM
يتم التثبيت عبر Composer (مدير حزم PHP). افتح الطرفية (Terminal) في جذر مشروعك ونفّذ الأمر التالي:
composer require doctrine/orm
للعمل مع Symfony، يُنصح بتثبيت حزمة DoctrineBundle:
composer require symfony/orm-pack
composer require --dev symfony/maker-bundle # لتوليد الكود
إذا كنت تستخدم PHP خالصاً بدون إطار عمل، ستحتاج أيضاً إلى تثبيت مشغل (Driver) لقاعدة البيانات الخاصة بك:
composer require doctrine/dbal
composer require doctrine/annotations # للعمل مع التعليقات التوضيحية (PHP 7.4 والإصدارات الأقدم)
للعمل مع سمات PHP 8+ (الطريقة الموصى بها): لست بحاجة إلى التعليقات التوضيحية، حيث تدعم Doctrine السمات الأصلية.
بداية سريعة: مثال كود
لننظر إلى مثال بسيط — إنشاء كيان "Product" وحفظه في قاعدة البيانات.
1. إنشاء كلاس الكيان (Entity)
<?php
// src/Entity/Product.php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[ORM\Table(name: 'products')]
class Product
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private int $id;
#[ORM\Column(type: 'string', length: 255)]
private string $name;
#[ORM\Column(type: 'float')]
private float $price;
// دوال الوصول (Getters) والتعديل (Setters)
public function getId(): int
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getPrice(): float
{
return $this->price;
}
public function setPrice(float $price): self
{
$this->price = $price;
return $this;
}
}
2. إنشاء وحفظ كائن
<?php
// في متحكم Symfony أو أي مكان آخر
use App\Entity\Product;
use Doctrine\ORM\EntityManagerInterface;
class ProductController
{
public function createProduct(EntityManagerInterface $entityManager)
{
$product = new Product();
$product->setName('لابتوب');
$product->setPrice(49999.99);
// نخبر Doctrine بأنه يجب حفظ هذا الكائن
$entityManager->persist($product);
// ننفذ عملية INSERT في قاعدة البيانات
$entityManager->flush();
// الآن $product->getId() يحتوي على ID السجل الجديد
return