पहलू-उन्मुख प्रोग्रामिंग (एओपी) प्रतिमान, जावा दुनिया में काफी लोकप्रिय है, किसी कारण से पीएचपी विकास में खराब कवर किया गया है। इस लेख में मैं एक छोटे ढांचे और मॉड्यूल का उपयोग करके एओपी एप्लिकेशन लिखने के लिए अपना दृष्टिकोण प्रस्तुत करना चाहता हूं।
संक्षेप में पहलू-उन्मुख प्रोग्रामिंग के बारे में
मॉड्यूल में प्रोग्राम के विभाजन को बेहतर बनाने के लिए
पहलू-उन्मुख प्रोग्रामिंग एक प्रतिमान विभाजित करने के विचार पर आधारित है।
संक्षेप में, दृष्टिकोण का सार ऐसे कार्यों का निर्माण करना है जो एक निश्चित घटना होने पर शुरू होता है (उदाहरण के लिए, एक विधि कॉल)। परिभाषा के आधार पर, फ़ंक्शन या तो घटना के निष्पादित होने से पहले या उसके बाद (या दोनों से पहले और बाद में) लॉन्च किए जाते हैं, इसलिए वे डेटाबेस के साथ वस्तु के बारे में जानकारी को सिंक्रनाइज़ करने के लिए लॉगिंग से - (दृढ़ता) तक कई तरह के ऑपरेशन कर सकते हैं।
जिन शर्तों के तहत ऐसे कार्य किए जाते हैं, उन्हें "जॉइन पॉइंट्स" कहा जाता है, हालत समूह "कट" (प्वाइंट कट) होते हैं, और फ़ंक्शंस को "सलाह" कहा जाता है।
अक्सर, युक्तियों को पहलुओं में वर्गीकृत किया जाता है (बस कक्षाओं में तरीकों की तरह), इसलिए एक पहलू सुझावों का एक समूह है जो कुछ कार्यक्षमता को लागू करता है।
PHP कार्यान्वयन
कार्यान्वयन के दो स्पष्ट तरीके हैं:
1) सभी संभावित कनेक्शन बिंदुओं के लिए आवश्यक कार्यों को कॉल करने के लिए आवरण कार्य बनाएं;
2) अपने कोड को लॉन्च करने के तरीकों की प्रक्रिया में एम्बेड करें, जो कि आवश्यक टिप्स चलाएगा या यदि कोई संगत कनेक्शन बिंदु नहीं है तो चलाएगा।
पहली विधि का मुख्य दोष अतिरेक है। मौजूदा प्रणाली में AOP को लागू करने का निर्णय लेने के दौरान कार्य और भी जटिल हो जाता है जिसमें आवरण कार्य नहीं होते हैं।
दूसरी विधि प्रीटियर दिखती है, लेकिन PHP में एक अतिरिक्त एक्सटेंशन कनेक्ट करने की आवश्यकता है। उसके बारे में (विधि) और हम आगे बढ़ेंगे।
MethodIntercept मॉड्यूल
अजीब तरह से पर्याप्त है, लेकिन PHP5 + के लिए ऑब्जेक्ट्स के तरीकों की कॉल को इंटरसेप्ट करने की अनुमति नहीं है। सभी जो पता चला कि
इंटरसेप्ट था, जिसका विकास 2005 में अल्फा रिलीज पर केंद्रित था। एक एक्सटेंशन दूसरे फ़ंक्शन से पहले और / या बाद में कुछ फ़ंक्शन कर सकता है। बेशक, यह PHP5 में OOP के साथ काम नहीं करता है।
इसके आधार पर, मैंने MethodIntercept लिखा, जो विधि कॉल को इंटरसेप्ट करने के अलावा, किसी ऑब्जेक्ट को पास करने में भी सक्षम है, जिसका तरीका कहा जाता है, और तर्कों को विधि में, इंटरसेप्ट फंक्शन में पास कर दिया जाता है।
विस्तार को संकलित करना काफी सरल है (लिनक्स उदाहरण):
git clone git@github.com:kooler/PAF.git cd PAF/MethodIntercept phpize ./configure make
परिणामस्वरूप, मॉड्यूल फ़ोल्डर में इंटरसेप्ट.सो फ़ाइल दिखाई देती है, जिसे आपको PHP एक्सटेंशन के साथ फ़ोल्डर में कॉपी करने की आवश्यकता होती है (आप इसे php -i | grep extension_dir चलाकर पहचान सकते हैं) और जोड़ना: extension = intercept। Php.ini।
यदि ऊपर वर्णित सब कुछ सफल था, तो इंटरसेप्ट_एड फ़ंक्शन का उपयोग करना संभव होगा, जो 3 पैरामीटर लेता है: क्लास-> विधि को इंटरसेप्ट किया जाना, फ़ंक्शन को कॉल करना, इंटरसेप्ट विधि - पहले या बाद में।
PHP एस्पेक्ट फ्रेमवर्क (PAF)
इस तथ्य के बावजूद कि MethodIntercept आपको लॉन्चिंग विधियों की प्रक्रिया में अपना कोड एम्बेड करने की अनुमति देता है, यह कई कारणों से AOP के साथ पूरी तरह से काम करने के लिए पर्याप्त नहीं है:
1. विस्तार कतार का समर्थन नहीं करता है - आप केवल एक इंटरसेप्टर फ़ंक्शन निर्दिष्ट कर सकते हैं।
2. एक इंटरसेप्टर केवल एक फ़ंक्शन हो सकता है और एक विधि नहीं हो सकता है; तदनुसार, पहलुओं में सलाह को समूहबद्ध करना असंभव है।
3. एक फ़ंक्शन (इंटरसेप्ट_एड) कॉल करके एक इंटरसेप्टर को निर्दिष्ट करना बहुत सुविधाजनक नहीं है।
उपरोक्त सभी के कार्यान्वयन को MethodIntercept में जोड़ना उचित नहीं है, क्योंकि इसका कार्य विधि कॉल को रोकना है, और AOP के लिए आवश्यक सभी बन्स प्रदान नहीं करना है (शायद यह एक अलग एक्सटेंशन लिखने के लायक है)।
इसलिए, मैंने अपनी खुद की मिनी-रूपरेखा लिखने का फैसला किया, जो AOP के उपयोग को सरल बनाता है, अर्थात्:
1. आपको एनोटेशन का उपयोग करके कनेक्शन बिंदुओं को परिभाषित करने की अनुमति देता है
2. यह कॉल कतार के गठन और इंटरसेप्ट_एड के निष्पादन को मानता है
3. आपको पहलू बनाने की अनुमति देता है
4. ज्वाइन पॉइंट्स को परिभाषित करते समय नियमित अभिव्यक्ति के उपयोग की अनुमति देता है
फ्रेमवर्क को PHP पहलू फ्रेमवर्क (या संक्षेप में PAF) कहा जाता है:
github.com/kooler/PAFएओपी का एक क्लासिक उदाहरण - लॉगिंग
एओपी के उपयोग के क्लासिक उदाहरण पर रूपरेखा के आवेदन पर विचार करें - लॉगिंग।
मान लीजिए कि हमारे पास एक वर्ग है:
class Backet { public function order() {
मान लीजिए कि हम हर बार उपयोगकर्ता को एक टोकरी खींचने या बनाने के लिए एक संदेश प्रदर्शित करना चाहते हैं (या लॉग को लिखें)। चलो लकड़हारा पहलू बनाते हैं, जिसमें दो युक्तियां शामिल होंगी: पहली टोकरी बनाने के बाद कॉल की जानी चाहिए, और दूसरी रचना के बाद:
class Logger extends Aspect { public function backetOrderMessage($params) { echo 'Backed has been ordered'; } public function backetCreatedMessage($params) { echo 'Backet has been created'; } }
हम पहलू को पंजीकृत करते हैं और कार्यान्वयन फ़ंक्शन करते हैं:
AspectRegistry::getInstance()->addAspect(new Logger); AspectRegistry::getInstance()->interceptAll();
उत्तरार्द्ध को केवल एक बार बुलाया जाना चाहिए, सभी पहलुओं को पंजीकृत करने के बाद, यह वह है जो कतार के निर्माण और इंटरसेप्ट_एड फ़ंक्शन को निष्पादित करने के लिए जिम्मेदार है।
प्रत्येक तर्क को एक तर्क से पारित किया जाता है - एक सरणी, जिसमें से पहला तत्व उस वस्तु को शामिल करता है जिसकी विधि को अवरोधन किया गया था, और दूसरा तर्क अवरोधन विधि को पारित किया गया था। इस प्रकार, यदि उदाहरण के लिए आपको एक आदेश देते समय उपयोगकर्ता नाम प्रदर्शित करने की आवश्यकता है, तो परिषद इस तरह दिखाई देगी:
class Backet { public $username; … } class Logger extends Aspect { public function backetOrderMessage($params) { echo 'Backed has been ordered by user: '.$params[0]->username; } ... }
समान उदाहरण के लिए पूर्ण कोड:
github.com/kooler/PAF/blob/master/Framework/expl.ppनिष्कर्ष
अब रूपरेखा काफी प्रारंभिक चरण में है - बढ़ने के लिए जगह है। मैं प्लगइन्स को जोड़ने की क्षमता जोड़ने की योजना बना रहा हूं, आधार (दृढ़ता) के साथ वस्तुओं के सिंक्रनाइज़ेशन को लागू करना, और बहुत कुछ। जावा में लोकप्रियता को देखते हुए, प्रतिमान काफी दिलचस्प है और PHP में रहने का अधिकार है।
मैं किसी भी सलाह और विचारों के लिए आभारी हूं, साथ ही पीएचपी में सामान्य एओपी की आवश्यकता है या नहीं।