PHP में सज्जाकार

छवि
मैंने PHP में अजगर-शैली सज्जाकारों को लागू करने के लिए अपनी दृष्टि और सर्वोत्तम प्रथाओं को साझा करने का निर्णय लिया।
एक लालच के रूप में, दाईं ओर की छवि में उपयोग का एक छोटा सा उदाहरण। आउटपुट (सज्जाकार के तर्क को स्वयं लागू करने के बाद):
 लॉग: कॉलिंग बी ()
 इंट (42)

कार्यान्वयन सी एक्सटेंशन के रूप में किया गया है और पीएचपी के पुनर्निर्माण की आवश्यकता नहीं है। लेकिन यह उन साइटों को होस्ट करना शुरू नहीं करता है जहाँ आप अपने so'shku को डाउनलोड नहीं कर सकते हैं।
फिलहाल, कोड बीटा में है (सभी आवश्यक कार्यक्षमता लिखी गई है, लेकिन संभवतः बग और मेमोरी लीक हैं :))। तो जैसा है। खैर, अगर विकास में मदद करने की इच्छा है, तो मुझे जीथब पर कमिट स्वीकार करने में खुशी होगी।


एक साधारण उपयोग मामला:
<?php function double($func) { return function() use($func) { return 2*call_user_func_array($func, func_get_args()); }; } @double function a() { return 21; } var_dump(a()); /* : int(42) */ 


सज्जाकार हमेशा फ़ंक्शंस होते हैं जो फ़ंक्शंस लौटाते हैं। एक बाहरी फ़ंक्शन पहले पैरामीटर के रूप में एक विकल्प फ़ंक्शन को स्वीकार करता है। अजगर के विपरीत, मापदंडों के साथ एक डेकोरेटर को एक फ़ंक्शन के रूप में वर्णित नहीं किया जाता है जो एक फ़ंक्शन देता है जो एक फ़ंक्शन देता है ... अतिरिक्त पैरामीटर बस बदले गए फ़ंक्शन के बाद पास किए जाते हैं:
 <?php function add($func, $v=0) { return function() use($func, $v) { return $v+call_user_func_array($func, func_get_args()); }; } @add(1) function a() { return 1; } var_dump(a()); /* : int(2) */ 


डेकोरेटर्स को जोड़ा जा सकता है:
 <?php function dec($func, $p='[]') { return function() use($func, $p) { $s = call_user_func_array($func, func_get_args()); return $p[0].$s.$p[1]; }; } @dec function a() { return 'I'; } var_dump(a()); @dec('{}') function b() { return 'am'; } var_dump(b()); @dec @dec('()') @dec('{}') function c() { return 'here'; } var_dump(c()); /* : string(3) "[I]" string(4) "{am}" string(10) "[({here})]" */ 


इसके अलावा, वे रिवर्स ऑर्डर में किए जाते हैं:
@A
@B
@C
समारोह एक्स

में बदल जाता है
A (B (C (X (...)))


मापदंडों और उनके प्रकारों की संख्या मनमानी है, और गणनाओं का आलस्य आमतौर पर हाथों को खोल देता है:
 <?php class Logger { const INFO = 'INFO'; public static function log($func, $text='', $level=self::INFO, $prefix='') { return function() use($func, $text, $level, $prefix) { printf("%s%s: %s\n", $prefix, $level, $text); return call_user_func_array($func, func_get_args()); }; } } @Logger::log('calling a()', Logger::INFO, date('Ymd H:i:s').': ') function a() { return 'Hello'; } var_dump(a()); /* : 2013-05-24 14:22:23: INFO: calling a() string(5) "Hello" */ 

डेकोरेटर के नाम फ़ंक्शंस और स्टेटिक तरीके होने चाहिए, इसके अलावा, कॉल के समय घोषित किए जाने चाहिए, और डेकोरेटर का वर्णन करते समय नहीं। और सामान्य तौर पर, आप प्रयोग कर सकते हैं:
 <?php class Arr { public static function map($func, $cb) { return function() use($func, $cb) { $v = call_user_func_array($func, func_get_args()); return array_map($cb, $v); }; } } class Foo { /*      */ @Arr::map(function($i){return -$i;}) /** *        *     * * @return array */ public function bar() { return range(1, 3); } } $foo = new Foo(); print_r($foo->bar()); /* : Array ( [0] => -1 [1] => -2 [2] => -3 ) */ 

खैर, मुझे यकीन है कि हर कोई अपने कार्यों के संदर्भ में कुछ और दिलचस्प बात कर सकता है।

तकनीकी मुद्दे


फिलहाल, मैंने डेकोरेटर के साथ कोड निष्पादित करते समय समर्थन की जांच की:

शायद कुछ और याद आ रहा है।

ज्ञात बग / सुविधाओं (सुविधाओं पर चर्चा की जा सकती है; मैं जल्द ही कीड़े ठीक करूंगा):


पुनश्च यदि सर्वेक्षण में "महान विवरणों की आवश्यकता" के पर्याप्त विकल्प हैं, तो मैं इस विस्तार के कार्यान्वयन के बारे में विस्तृत विवरण के साथ एक पोस्ट लिख सकता हूं।

Source: https://habr.com/ru/post/In180827/


All Articles