Doctrine ORM للPHP: دليل شامل مع أمثلة
1. ما هي Doctrine ORM ولماذا نستخدمها؟
Doctrine ORM (Object-Relational Mapper) هي مكتبة قوية للغة PHP، تطبق نمط Data Mapper. على عكس Active Record (المستخدم في Laravel Eloquent)، تفصل Doctrine تمامًا منطق الأعمال (الكيانات) عن منطق التعامل مع قاعدة البيانات. الكيانات هي كائنات PHP عادية (Plain Old PHP Objects - POPO) لا تعلم بوجود قاعدة البيانات. يتم كل التعامل مع قاعدة البيانات من خلال مستودع مركزي يُسمى EntityManager.
لماذا نحتاج إليها؟ تحل Doctrine المشكلة الأساسية للتباين بين النموذج الكائني للبيانات والنموذج العلائقي لقاعدة البيانات (Object-Relational Impedance Mismatch). أنت تتعامل مع الكائنات والمجموعات، بينما تقوم Doctrine تلقائيًا بترجمة أفعالك إلى استعلامات SQL. هذا يتيح لك كتابة كود أنظف، وأسهل للاختبار والصيانة، خاصة في المشاريع المؤسسية الكبيرة.
المزايا الرئيسية: تحكم كامل في SQL (عبر DQL - Doctrine Query Language)، التحميل البطيء (Lazy Loading)، نظام أحداث مرن (Lifecycle Events)، دعم الوراثة (Mapped Superclass, Single Table Inheritance, Joined Table Inheritance)، منشئ استعلامات مدمج (Query Builder)، وأنماط التهيئة (Hydration Modes). تُعتبر Doctrine المعيار الفعلي لتطبيقات PHP المعقدة (مثل Symfony, Drupal, Magento).
2. التثبيت
يتم التثبيت عبر Composer (المكافئ لـ pip في PHP). للاستخدام الأساسي، يكفي حزمتان:
composer require doctrine/orm
composer require doctrine/dbal
composer require symfony/cache # موصى به لتخزين البيانات الوصفية مؤقتًا
للعمل مع التعليقات التوضيحية (طريقة قديمة ولكنها شائعة)، تحتاج إلى حزمة إضافية:
composer require doctrine/annotations
للعمل مع تهيئة YAML أو XML:
composer require symfony/yaml # لـ YAML
بعد التثبيت، تأكد من تضمين أداة التحميل التلقائي لـ Composer في مشروعك:
require_once __DIR__ . '/vendor/autoload.php';
3. بداية سريعة - مثال عملي بسيط
لننشئ كيانًا بسيطًا User ونحفظه في قاعدة بيانات SQLite.
الخطوة 1: تهيئة EntityManager (bootstrap.php)
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\ORMSetup;
use Doctrine\DBAL\DriverManager;
require_once __DIR__ . '/vendor/autoload.php';
// تحديد مسارات الكيانات ووضع التطوير
$paths = [__DIR__ . '/src/Entity'];
$isDevMode = true;
// إنشاء تهيئة ORM
$config = ORMSetup::createAttributeMetadataConfiguration($paths, $isDevMode);
// إعداد الاتصال بقاعدة البيانات (SQLite)
$connectionParams = [
'driver' => 'pdo_sqlite',
'path' => __DIR__ . '/data/database.sqlite',
];
$connection = DriverManager::getConnection($connectionParams, $config);
// إنشاء EntityManager
$entityManager = new EntityManager($connection, $config);
الخطوة 2: إنشاء الكيان (src/Entity/User.php)
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[ORM\Table(name: 'users')]
class User
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private int|null $id = null;
#[ORM\Column(type: 'string', length: 100)]
private string $name;
#[ORM\Column(type: 'string', length: 255, unique: true)]
private string $email;
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 getEmail(): string
{
return $this->email;
}
public function setEmail(string $email): self