باختصار حول المواصفات:
المواصفات هي نمط تصميم يمكنك بواسطته أن يعكس قواعد منطق العمل في شكل سلسلة من الكائنات المتصلة بعمليات منطقية منطقية. تسمح لك المواصفات بالتخلص من الأساليب المكررة والمماثلة في مستودع وتكرار منطق العمل.
يوجد اليوم مشروعان (إذا كنت تعرف مشاريع أخرى ، يرجى كتابة التعليقات) ، مشاريع PHP ناجحة وشائعة تتيح لك وصف قواعد العمل في المواصفات ومجموعات بيانات التصفية. هذه هي مواصفات RulerZ و Happyr . كلا المشروعين أدوات قوية مع مزاياها وعيوبها. مقارنة هذه المشاريع سوف ترسم مقالا كاملا. أريد هنا أن أخبركم بما جاء به الإصدار الجديد في مواصفات العقيدة.
باختصار حول مواصفات العقيدة
أولئك الذين هم أكثر أو أقل دراية بالمشروع ، يمكنهم تخطي هذا القسم بأمان.
بمساعدة هذا المشروع ، يمكنك وصف المواصفات في شكل كائنات ، وتأليفها من التكوين ، وبالتالي وضع قواعد عمل معقدة. يمكن إعادة استخدام التركيبات الناتجة بحرية ، ودمجها في تركيبات أكثر تعقيدًا يسهل اختبارها. يتم استخدام مواصفات العقيدة لبناء استعلامات العقيدة. في جوهرها ، مواصفات Doctrine هي مستوى التجريد على Doctrine ORM QueryBuilder و Doctrine ORM Query.
تنطبق المواصفات من خلال مستودع العقيدة:
$result = $em->getRepository(MyEntity::class)->match($spec);
يمكن تطبيق المواصفات يدويًا ، لكنها ليست ملائمة بشكل خاص ، وفي المدى الطويل ، لا طائل من ورائها. $spec = ... $alias = 'e'; $qb = $em->getRepository(MyEntity::class)->createQueryBuilder($alias); $spec->modify($qb, $alias); $filter = (string) $spec->getFilter($qb, $alias); $qb->andWhere($filter); $result = $qb->getQuery()->execute();
هناك عدة طرق في المستودع:
match
- الحصول على جميع النتائج المقابلة للمواصفات ؛matchSingleResult
- مكافئ Query::getSingleResult()
؛matchOneOrNullResult
- المكافئ لـ matchSingleResult
، لكنه يسمح matchSingleResult
؛getQuery
- يقوم بإنشاء QueryBuilder عن طريق تطبيق مواصفات عليه وإرجاع كائن Query منه.
في الآونة الأخيرة ، تمت إضافة طريقة getQueryBuilder
إليهم ، مما يؤدي إلى إنشاء QueryBuilder ، وتطبيق المواصفات عليها ، ويعيدها.
يحدد المشروع عدة أنواع من المواصفات:
المواصفات المنطقية
orX
و orX
أيضًا كمجموعة من المواصفات.
Spec::andX()
Spec::orX()
Spec::not()
من المعتاد تثبيت كائنات مواصفات المكتبة من خلال واجهة Spec
، لكن هذا ليس ضروريًا. يمكنك إنشاء مثيل واضح لعنصر المواصفات:
new AndX(); new OrX(): new Not();
مواصفات مرشح
تصفية المواصفات ، في الواقع ، تشكل قواعد منطق الأعمال وتستخدم في طلب WHERE
. وتشمل هذه عمليات المقارنة:
isNull
- SQL IS NULL
المكافئisNotNull
- SQL IS NOT NULL
مكافئin
- ما يعادل IN ()
NOT IN ()
- NOT IN ()
ما يعادلهاeq
- اختبار المساواة =
neq
- التحقق من عدم المساواة !=
lt
- أقل من <
lte
- أقل من أو يساوي <=
gt
- أكثر من >
gte
- أكبر من أو يساوي >=
like
- like
SQL يعادل- exampleOfX - ما يعادل DQL
INSTANCE OF
مثال على استخدام مواصفات التصفية:
$spec = Spec::andX( Spec::eq('ended', 0), Spec::orX( Spec::lt('endDate', new \DateTime()), Spec::andX( Spec::isNull('endDate'), Spec::lt('startDate', new \DateTime('-4 weeks')) ) ) );
معدّلات الاستعلام
لا علاقة لمعدلات الاستعلامات بقواعد العمل وقواعد العمل. كما يوحي الاسم ، فإنها فقط تعديل QueryBuilder. اسم وغرض المعدلات المعرفة مسبقا يتوافق مع أساليب مماثلة في QueryBuilder.
join
leftJoin
innerJoin
limit
offset
orderBy
groupBy
having
أريد أن أشير بشكل منفصل إلى معدل slice
. فهو يجمع بين وظائف limit
offset
وحساب الإزاحة على أساس حجم الشريحة ورقمها التسلسلي. في تنفيذ هذا التعديل ، لم نوافق على مؤلف المشروع. إنشاء مُعدِّل ، تابعت هدف تبسيط تكوين المواصفات أثناء ترقيم الصفحات. في هذا السياق ، يجب أن تكون الصفحة الأولى ذات الرقم التسلسلي 1 مكافئة للشريحة الأولى ذات الرقم التسلسلي 1. لكن مؤلف المشروع اعتبر أنه من الصواب البدء في بدء العد التنازلي بأسلوب برمجة ، أي من 0. لذلك ، تجدر الإشارة إلى أنك إذا كنت بحاجة إلى الشريحة الأولى ، فيجب عليك تحديد 0 كرقم مسلسل.
نتيجة المعدلات
توجد معدّلات النتائج متباعدة قليلاً عن المواصفات. أنها تنطبق على عقيدة الاستعلام. تتحكم المعدلات التالية في ترطيب البيانات ( Query::setHydrationMode()
):
asArray
asSingleScalar
asScalar
يتحكم معدّل cache
التخزين المؤقت في التخزين المؤقت لنتائج الاستعلام.
يجب أن نذكر أيضًا معدل roundDateTimeParams
. يساعد في حل مشاكل التخزين المؤقت عندما تحتاج إلى العمل مع قواعد العمل التي تتطلب مقارنة بعض القيم مع الوقت الحالي. هذه قواعد أعمال عادية ، ولكن نظرًا لحقيقة أن الوقت ليس ثابتًا ، فلن يعمل التخزين المؤقت لأكثر من ثانية واحدة من أجلك. تم roundDateTimeParams
معدل roundDateTimeParams
لحل هذه المشكلة. يمر عبر جميع معلمات الطلب ، ويبحث عن التاريخ فيها ويقربها إلى القيمة المحددة ، والتي تعطينا قيم التاريخ التي تكون دائمًا مضاعفات بقيمة واحدة ولن نحصل على التاريخ في المستقبل. أي إذا أردنا تخزين الطلب مؤقتًا لمدة 10 دقائق ، فإننا نستخدم Spec::cache(600)
و Spec::roundDateTimeParams(600)
. في البداية ، تم اقتراح دمج هذين المعدلين للراحة ، ولكن تقرر فصلهما عن SRP.
المواصفات المضمنة
يحتوي Happyr Doctrine-Specification على واجهة منفصلة للمواصفات التي تجمع بين مرشح ومعدل طلب. المواصفات المحددة مسبقًا هي countOf
والتي تتيح لك الحصول على عدد الكيانات المطابقة للمواصفات. لإنشاء مواصفات خاصة بك ، من المعتاد تمديد فئة BaseSpecification
المجردة.
الابتكارات
تمت إضافة طرق جديدة إلى المستودع:
matchSingleScalarResult
- المكافئ من Query::getSingleScalarResult()
؛matchScalarResult
- المكافئ Query::getScalarResult()
؛iterate
هو المكافئ Query::iterate()
.
تتم MemberOfX
مواصفات MemberOfX
- MemberOfX
المكافئ indexBy
الخاص بـ MEMBER OF
indexBy
استعلام indexBy
- المكافئ QueryBuilder::indexBy()
.
المعاملات
الإصدار الجديد يقدم مفهوم Operand . تتكون كل الشروط الموجودة في المرشحات من المعاملات اليمنى واليسرى ومشغل بينهما.
<left_operand> <operator> <right_operand>
في الإصدارات السابقة ، يمكن أن يكون المعامل الأيسر مجرد حقل كيان ، والمعامل الأيمن يمكن أن يكون قيمة فقط. هذه آلية بسيطة وفعالة تكفي لمعظم المهام. في الوقت نفسه ، يفرض قيودًا معينة:
- غير قادر على استخدام الوظائف ؛
- لا يمكن استخدام الأسماء المستعارة للحقول ؛
- من المستحيل مقارنة حقلين ؛
- من المستحيل مقارنة قيمتين ؛
- غير قادر على استخدام العمليات الحسابية ؛
- لا يمكن تحديد نوع البيانات للقيمة.
في الإصدار الجديد ، يتم تمرير كائنات المعامل إلى المرشحات في الوسائط ويتم تفويض تحولها في DQL إلى المعاملات نفسها. هذا يفتح العديد من الاحتمالات ويجعل المرشحات أسهل.
الحقل والقيمة
للحفاظ على التوافق مع الإصدارات السابقة ، يتم تحويل الوسيطة الأولى في عوامل التصفية إلى معامل حقل ، إذا لم تكن معاملًا ، ويتم تحويل الوسيطة الأخيرة إلى معامل قيمة. لذلك ، يجب أن لا تواجه مشكلات في التحديث.
يمكنك مقارنة حقلين:
يمكنك مقارنة حقلين لكيانات مختلفة:
العمليات الحسابية
إضافة دعم للعمليات الحسابية القياسية -
، +
، *
، /
، %
. على سبيل المثال ، ضع في اعتبارك حساب نقاط المستخدم:
يمكن أن تتداخل العمليات الحسابية مع بعضها البعض:
وظائف
الإصدار الجديد وأضاف المعاملات مع وظائف. يمكن استخدامها كطرق ثابتة لفئة Spec
، أو من خلال الأسلوب Spec::fun()
.
وظائف يمكن أن تتداخل واحدة في أخرى:
يمكن تمرير وسيطات الوظائف كوسائط منفصلة ، أو بتمريرها في صفيف:
إدارة العينات
في بعض الأحيان تحتاج إلى إدارة قائمة قيم الإرجاع. على سبيل المثال:
- أضف كيانًا آخر إلى النتيجة حتى لا تنشئ استعلامات فرعية للحصول على الارتباطات ؛
- لإرجاع ليس الكيان بأكمله ، ولكن فقط مجموعة من الحقول المنفصلة ؛
- استخدام الأسماء المستعارة ؛
- استخدم الأسماء المستعارة المخفية بشروط للفرز (يتطلب ذلك مبدأ ، ولكنه يعد بإصلاحه ).
قبل الإصدار 0.8.0 ، كانت هذه المهام تتطلب إنشاء مواصفات لهذه الاحتياجات. بدءًا من الإصدار 0.8.0 ، يمكنك استخدام الأسلوب getQueryBuilder()
وإدارة التحديد من خلال واجهة QueryBuilder.
الإصدار الجديد 1.0.0 يضيف select
و addSelect
الطلب. select
تمامًا يحل محل قائمة القيم addSelect
للاختيار ، ويضيف addSelect
قيمًا جديدة إلى القائمة. كقيمة ، يمكنك استخدام كائن يقوم بتنفيذ واجهة Selection
أو مرشح. وبالتالي ، يمكنك توسيع قدرات المكتبة لتناسب احتياجاتك. النظر في الفرص المتاحة بالفعل.
يمكنك اختيار حقل واحد:
يمكنك إضافة حقل واحد إلى التحديد:
يمكنك اختيار عدة مجالات:
يمكنك إضافة كيان إلى القيم التي يتم إرجاعها:
يمكنك استخدام الأسماء المستعارة للحقول القابلة للتحديد:
يمكنك إضافة الحقول المخفية إلى التحديد:
يمكنك استخدام التعبيرات ، على سبيل المثال ، للحصول على خصم على منتج:
يمكنك استخدام الأسماء المستعارة في المواصفات:
هذا كل شيء في الأساس. هذا هو المكان الذي تنتهي فيه الابتكارات. الإصدار الجديد قد جلب العديد من الميزات المثيرة للاهتمام ومفيدة. آمل أن يكونوا مهتمين بك.
ملاحظة: يمكنني استخدام مثال لتحليل استخدام المواصفات وإظهار مزايا وعيوب استخدامها. إذا كان هذا مثيرًا لك ، فاكتب في التعليقات أو في PM.