मुख्य कंटेंट तक स्किप करें

Weaver ORM क्या है?

Weaver ORM एक PHP 8.4+ ऑब्जेक्ट-रिलेशनल मैपर (object-relational mapper) है जो Symfony अनुप्रयोगों के लिए एक मूल सिद्धांत पर बना है: आपके डोमेन ऑब्जेक्ट्स को डेटाबेस की कोई जानकारी नहीं होनी चाहिए। एंटिटी क्लास पर कोई एनोटेशन नहीं, कोई प्रॉक्सी जनरेशन नहीं, कोई रनटाइम रिफ्लेक्शन नहीं — बस सामान्य PHP ऑब्जेक्ट्स और स्पष्ट मैपर क्लासेज जो उन्हें SQL में अनुवादित करती हैं।

Weaver जो समस्याएं हल करता है

Doctrine प्रॉक्सी ऑब्जेक्ट्स (Doctrine proxy objects)

Doctrine हर संबंधित एंटिटी को एक प्रॉक्सी क्लास में लपेटता है जो प्रॉपर्टी एक्सेस को इंटरसेप्ट करती है और पहली बार टच होने पर SQL क्वेरी ट्रिगर करती है। पारंपरिक request/response चक्रों में यह अदृश्य होता है, लेकिन यह चुपके से N+1 क्वेरी पैटर्न को सक्षम करता है और डीबगिंग को भ्रमित करता है (var_dump($post->getAuthor()) एक प्रॉक्सी प्रिंट करता है, User नहीं)।

लंबे समय तक चलने वाले PHP वर्कर्स (RoadRunner, FrankenPHP, Swoole, Symfony Messenger) में EntityManager अनुरोधों के बीच पुरानी स्थिति जमा करता है और हर अनुरोध सीमा पर मैन्युअल रूप से रीसेट किया जाना चाहिए — यह एक आसान गलती है जिसे करना और डीबग करना कठिन है।

रिफ्लेक्शन-आधारित हाइड्रेशन (Reflection-based hydration)

Doctrine एंटिटी ऑब्जेक्ट्स पर private/protected प्रॉपर्टीज़ को सीधे सेट करने के लिए ReflectionProperty का उपयोग करता है, जो आपके डोमेन लॉजिक को बायपास करता है। हर अनुरोध को PHP एट्रिब्यूट्स को फिर से पार्स करना होगा या वार्म कैश से हिट करना होगा; प्रॉक्सी क्लासेज को डिस्क पर मौजूद होना चाहिए।

असीमित आइडेंटिटी मैप (Unbounded identity map)

Doctrine का EntityManager अनुरोध की अवधि के लिए हर लोड की गई एंटिटी को मेमोरी में रखता है। बड़े रिजल्ट सेट लोड करने से असीमित मेमोरी ग्रोथ होती है। वर्कअराउंड — $em->clear() — सब कुछ अलग कर देता है, जिसमें वे एंटिटीज़ भी शामिल हैं जिन्हें आप पुनः persist करना भूल गए।

Weaver क्या अलग करता है

Weaver चार सिद्धांतों पर बना है:

  1. एंटिटीज़ के रूप में सामान्य PHP ऑब्जेक्ट्स। आपकी User क्लास में ORM की कोई निर्भरता नहीं है। कोई एट्रिब्यूट्स नहीं, कोई बेस क्लास नहीं, कोई इंटरफेस नहीं। यह एक शुद्ध वैल्यू ऑब्जेक्ट या डोमेन ऑब्जेक्ट है जिसे आप Symfony बूट किए बिना यूनिट-टेस्ट कर सकते हैं।

  2. स्पष्ट मैपर क्लासेज (Explicit mapper classes)। एक अलग UserMapper क्लास बताती है कि User users टेबल से कैसे मैप होती है। कॉलम टाइप्स, रिलेशन्स, प्राइमरी कीज़ — सब एक जगह, सब सामान्य PHP में, पूरी तरह से grep-योग्य और स्टेटिकली विश्लेषणीय।

  3. कोई प्रॉक्सी नहीं, कोई अंतर्निहित लेजी लोडिंग नहीं। रिलेशन्स हमेशा ->with(['relation']) के माध्यम से स्पष्ट रूप से लोड किए जाते हैं। आप हमेशा जानते हैं कि कौन सा SQL कब निष्पादित होता है।

  4. डिज़ाइन द्वारा वर्कर-सुरक्षित (Worker-safe by design)। मैपर्स स्टेटलेस हैं और प्रति वर्कर प्रक्रिया एक बार लोड होते हैं। प्रत्येक HTTP अनुरोध या Messenger जॉब को अपना EntityWorkspace (कार्य की इकाई) मिलता है, इसलिए अनुरोधों के बीच कोई साझा म्यूटेबल स्थिति नहीं होती।

एक नज़र में मुख्य विभेदक

फीचरDoctrine ORMWeaver ORM
प्रॉक्सी क्लास जनरेशनआवश्यकआवश्यक नहीं
रनटाइम रिफ्लेक्शनहाँकभी नहीं
लेजी लोडिंगअंतर्निहित (प्रॉक्सी)केवल स्पष्ट
एंटिटी एनोटेशन/एट्रिब्यूटएंटिटी क्लास परअलग मैपर क्लास
रीसेट पर वर्कर प्रक्रिया पुनरारंभहाँनहीं
N+1 रोकथाममैन्युअल JOIN FETCHwith() द्वारा प्रवर्तित
10k पंक्तियों पर मेमोरी~48 MB~11 MB
10k पंक्तियों के लिए हाइड्रेशन समय~420 ms~95 ms
PHPStan / स्टेटिक विश्लेषणआंशिक (magic proxies)पूर्ण (स्पष्ट mappers)

बेंचमार्क: PHP 8.4, PostgreSQL 16, Ubuntu 22.04, Profile रिलेशन के साथ 10,000 User पंक्तियाँ। परिणाम हार्डवेयर और क्वेरी जटिलता के अनुसार भिन्न होते हैं।

आर्किटेक्चर अवलोकन

Entity (सामान्य PHP क्लास — ORM कपलिंग शून्य)

└── Mapper (टेबल नाम, कॉलम, रिलेशन, hydrate/extract)

└── EntityWorkspace → QueryBuilder → PDO/DBAL

EntityWorkspace Doctrine के EntityManager की जगह लेता है। यह एक request-scoped कार्य की इकाई है जो ट्रैक करती है कि flush() कॉल होने पर किन एंटिटीज़ को INSERT, UPDATE, या DELETE करना है। चूंकि यह request-scoped है, इसलिए अनुरोधों के बीच कोई आइडेंटिटी मैप लीक नहीं होती।

PyroSQL समर्थन

Weaver PyroSQL के लिए वैकल्पिक समर्थन के साथ आता है, जो एक उच्च-प्रदर्शन इन-प्रक्रिया विश्लेषणात्मक SQL इंजन है। PyroSQL को प्राथमिक रिलेशनल डेटाबेस को छुए बिना एग्रीगेट क्वेरीज़, रिपोर्टिंग और बड़े डेटासेट ऑपरेशन के लिए रीड रेप्लिका के रूप में उपयोग किया जा सकता है। विवरण के लिए PyroSQL अनुभाग देखें।

आवश्यकताएं

निर्भरतान्यूनतम संस्करण
PHP8.4
Symfony7.0
doctrine/dbal4.0 (केवल कनेक्शन लेयर)
MySQL8.0
PostgreSQL14
SQLite3.35

वैकल्पिक:

  • symfony/messenger — असिंक्रोनस इवेंट पब्लिशिंग और आउटबॉक्स पैटर्न
  • symfony/cache — क्वेरी परिणाम कैशिंग
  • mongodb/mongodb + ext-mongodb — MongoDB दस्तावेज़ मैपर समर्थन

Weaver क्या नहीं है

Weaver, Doctrine का ड्रॉप-इन रिप्लेसमेंट नहीं है। यदि आप Doctrine के DQL, criteria API, या attribute-based माइग्रेशन पर बहुत अधिक निर्भर करते हैं, तो आपको उस लेयर को फिर से लिखना होगा। Weaver नए Symfony 7+ प्रोजेक्ट्स या Doctrine से दूर माइग्रेट हो रहे अनुप्रयोगों के लिए सबसे उपयुक्त है जो स्पष्ट, अनुमानित SQL और वर्कर-सुरक्षित persistence चाहते हैं।