استفاده از Doctrine ORM در Laravel به جای Eloqunet

Doctrine ORM از  نسخه دوم معماریشو از نوع ActiveRecord به DataMapper تغییر داد. اگه نمیدونید فرق این دو تا چیه این بلاگ پست رو بخونید. همونطور که میدونید لاراول به صورت پیشفرض از  ORM بسیار خوب و قوی Eloquent که توسط تیم همین فریمورک طراحی شده استفاده میکنه که معماریش ActiveRevordایه ولی اگه شما هم مثل من به سرتون زده که از یه ORM دیگه استفاده کنید، ادامه بدید به خوندن این پست وگرنه فکر نمیکنم فایده‌ای داشته باشه براتون.

من از Doctrine تو فریمورک‌های Yii و Symfony قبلا استفاده کردم و تقریبا بهش مسلطم واسه همین قصدم اینه که به دلایلی مثل کد تمیزتر و جدا بودن لایه Data Persistence از لایه Domain و … از این ORM توی پروژه‌های لاراولیم هم استفاده کنم. خب برای این کار چند راه داریم یکیش و سخت‌ترینش اینه که Doctrine رو با Composer نصب کنیم و خودمون شروع کنیم به integrate کردنش با لاراول. خب وقتی قبلا افرادی بودن که همین قضیه به فکرشون رسیده و این کارو انجام دادن، چرا باید دوباره خودمون  چرخو از اول اختراع کنیم؟ LaravelDoctrine یه پکیجیه که این کارو برامون آسون میکنه و برای داشتن Doctrine روی لاراول به ترتیب زیر عمل میکنیم:

نصب Doctrine

ابتدا پکیج  laravel-doctrine/orm رو با توجه به نسخه لاراولمون نصب میکنیم. من خودم از لاراول نسخه ۵٫۱٫* استفاده میکنم، نسخه‌ای که باید از این پکیج نصب کنم به این ترتیبه:

شما هم میتونید با توجه به نسخه لاراولتون، نسخه مناسب خودتونو نصب کنید:

Screenshot from 2016-07-25 12-57-31

بعد از اینکه نصب شد، Service Provider این پکیج را به آرایه Providerهامون توی فایل config/app.php  اضافه میکنیم:

در مرحله بعدی باید فایل تنظیمات laravel-doctrine/orm  رو با فرمان زیر به دایرکتوری configs  اضافه میکنیم:

بعد اینکه این کارها رو انجام دادیم، تقریبا همه چی آماده س برای شروع، فقط قبلش یه دایرکتوری برای Entity هامون درست میکنیم که همینجوری توی دایرکتوری app  ول نباشن، من دایرکتوری app/Entities  رو دست کردم و بعدش توی فایل config/doctrine.php ، توی خط ۳۲، base_path('app')  رو به base_path('app/Entities')  تغییر دادم.

ایجاد Entity

برای مثال من میخوام Entity کاربر درست کنم، برای این منظور، یه فایل به نام User.php توی دایرکتوری app/Entities درست میکنم و Mappingشو به صورت Annotation بهش میدم. توی داکترین به چند شکل میشه Mapping تعریف کرد، Annotation , XML, YAML , PHP که به صورت پیشفرض من از Annotation استفاده  کردم. هر User من میتونه بینهایت BlogPost داشته باشه که اونو هم داخل کلاس نوشتم. توجه داشته باشید که هر Entity میتونه مستقیم یه  جدول از دیتابیس باشه یا نباشه.

در ادامه کلاس BlogPost رو هم ایجاد میکنم:

تا اینجای کار، ما فقط دو تا کلاس ساده PHP ایجاد کردیم و با دیتابیس کاری نداشتیم حالا برای ایجاد جداول دیتابیسمون یا اعمال تغییرات باید دستور زیر رو توی خط-فرمان اجرا کنیم:

حالا اگه  به دیتابیس سر بزنیم میبینم که دو تا جدول با مشخصاتی که از طریق Annotation توی کلاسمون تعریف کردیم ایجاد شده. به همین راحتی. دیگه نیازی به نوشتن مایگرشن هم نیست براش، اگه توی تیم کار میکنید فقط کافیه بعد از گرفتن تغییرات جدید، دستور بالا رو یه بار اجرا کنید.

 

کار با Entity ها

در Doctrine برای کار با Entity ها ما به طور پیشفرض با چند ابزار مواجه هستیم، Entity Manager, Entity Repository و Query Builder. که به وسیله Entity Manager همه عملیات‌ رو روی Entity  انجام میدیم. Entity Manager ابزارهای لازم برای کوئری گرفتن از دیتابیس و ایجاد و ویرایش بر روی دیتابیس رو بر عهده داره. در ادامه یه مثال میزنم که خوب متوجه بشید:
برای ایجاد یک کاربر و یه سری بلاگ‌پست کد زیر رو مینویسیم:

همونطور که میبینید، تو کد بالا با Entity ها مثل Objectهای معمولی PHP رفتار کردیم و دقیقا هم کار و رفتارشون  همینه و عملیات ارتباط با دیتابیس و ذخیره کردن و تبدیل محتوای آبجکت‌ها توسط EntityManager مدیریت میشه.

حالا برای دریافت اطلاعات از دیتابیس باید از Repository یا Query Builder استفاده کنیم. هر Entity میتونه Repository مخصوص به خودشو داشته باشه یا اینکه از EntityRepository پیشفرض Doctrine استفاده میکنیم. در هر صورت کاری که باید بکنیم اینه:

متغیر $manager رو از Container باید بگیریم که یا باید کلاس EntityManager رو inject کنیم تو متد یا کنترلرمون یا اینکه باید از به وسیله app('em')  یا app(EntityManager::calss)  میتونیم همه جا داشته باشیمش.

توصیه میکنم برای آشنایی بیشتر مستندات Doctrine ORM رو بخونید. در آخر اگه سوالی داشتید و میتونستم جواب بدم، خوشحال میشم کمکتون کنم.