2012-10-25 11 views
13

नोट: इस quesiton लिखने के आधार पर, मुझे पहले ही पता चला है कि मैं एक नई भाषा सुविधा का उपयोग करने के बारे में अत्यधिक उत्साही था। दूर क्लीनर समाधान इसके बजाय एक रणनीति पैटर्न का उपयोग कर रहा था ... फिर भी, अगर इस समस्या के बारे में जाने का कोई उचित तरीका है तो मैं उत्सुक हूं।रन-टाइम निर्धारित कॉल करने योग्य के पैरामीटर की संख्या कैसे प्राप्त करें?

टीएल; डीआर: क्या आप सभी प्रकार के कॉल करने योग्य मैन्युअल रूप से टाइप करने के बिना PHP में जेनेरिक कॉल करने योग्य पर प्रतिबिंबित कर सकते हैं?

PHP 5.4 में हमें एक नया टाइपिंट मिला है: कॉल करने योग्य। यह बहुत मजेदार लगता है। मैंने सोचा कि मैं निम्नलिखित के माध्यम से इस का उपयोग करने के चाहते हैं:

<?php 
    public function setCredentialTreatment(callable $credentialTreatment) { 
     // Verify $credentialTreatment can be used (ie: accepts 2 params) 
     ... magic here ... 
    } 
?> 

अब तक सोचा था की मेरी लाइन प्रतिदेय पर टाइप-जांच की एक श्रृंखला करने के लिए किया गया है, और कहा कि जो परावर्तन से निष्कर्ष निकालते * वर्ग का उपयोग करने के :

<?php 
if(is_array($callable)) { 
    $reflector = new ReflectionMethod($callable[0], $callable[1]); 
} elseif(is_string($callable)) { 
    $reflector = new ReflectionFunction($callable); 
} elseif(is_a($callable, 'Closure') || is_callable($callable, '__invoke')) { 
    $objReflector = new ReflectionObject($callable); 
    $reflector = $objReflector->getMethod('__invoke'); 
} 

// Array of ReflectionParameters. Yay! 
$parameters = $reflector->getParameters(); 
// Inspect parameters. Throw invalidArgumentException if not valid. 
?> 

अब, मेरे लिए, यह अत्यधिक जटिल लगता है। क्या मैं यहां क्या करने की कोशिश कर रहा हूं, इसे प्राप्त करने के लिए किसी प्रकार का शॉर्टकट तरीका खो रहा हूं? किसी भी अंतर्दृष्टि का स्वागत किया जाएगा :)

+0

मैं एक ऐसी ही समस्या में पड़ गए, और किसी भी कॉल करने योग्य के लिए एक प्रतिबिंब वस्तु प्राप्त करने के लिए एक सहायक समारोह बनाने समाप्त हो गया। इस फ़ंक्शन के लिए कोड आपके जैसा ही है। – Benjamin

+0

मुझे पता नहीं है कि आपने इसके साथ जारी रखा है, लेकिन क्या आपने अपना खुद का कॉल करने योग्य प्रतिबिंब बनाने के लिए विचार किया है जो अंतरों को संभवतः अधिक आसान पैकेज में मदद करता है? – hakre

+0

अंत में मैंने इस पथ को और आगे नहीं बढ़ाया है, लेकिन एक पुन: प्रयोज्य कॉलबल रिफ्लेक्शन बनाना सही दिशा में एक कदम की तरह प्रतीत होता है। कुछ बिंदु पर मैं उम्मीद करता हूं कि PHP के प्रतिबिंब मॉड्यूल को उन पंक्तियों के साथ कुछ के साथ शिप करने की उम्मीद है। – kander

उत्तर

2

मैंने एक छोटा संस्करण बनाया जो कॉल_user_func() की तरह काम करता है और इसे कॉलबैक/कॉलबेल के लिए PHP मैनुअल में सभी अलग-अलग प्रकारों पर परीक्षण करता है। इस तरह आप इसे लगभग कहीं भी इस्तेमाल कर सकते हैं। call_user_func() केवल ऑब्जेक्ट नहीं लेता है, और यह मुझे समझ में नहीं आया कि यह फ़ंक्शन या तो होना चाहिए, क्योंकि यह केवल कॉलबैक को संभालने वाला है।

टेस्ट और यह कैसे उपयोग करने के लिए पर सुझाव नीचे दिये जाते हैं और मुझे उम्मीद है कि इस मदद करता है:

function getNrOfParams($callable) 
{ 
    $CReflection = is_array($callable) ? 
    new ReflectionMethod($callable[0], $callable[1]) : 
    new ReflectionFunction($callable); 
    return $CReflection->getNumberOfParameters(); 
} 

परीक्षण और अपनी संपूर्णता में अपने परिणाम:

<?php 
class Smart 
{ 
    public function __invoke($name) 
    { 

    } 

    public function my_callable($one, $two, $three) 
    { 

    } 

    public static function myCallableMethod($one, $two) 
    { 

    } 

    public static function who() 
    { 
      echo "smart the parent class"; 
    } 
} 

class Smarter extends Smart 
{ 
    public static function who() 
    { 
     echo "smarter"; 
    } 
} 

function my_ca($one) 
{ 

} 

function getNrOfParams($callable) 
{ 
    $CReflection = is_array($callable) ? new ReflectionMethod($callable[0], $callable[1]) : new ReflectionFunction($callable); 
    return $CReflection->getNumberOfParameters(); 
} 
// Test 1 Callable Function 
echo "Test 1 - Callable function:" . getNrOfParams('my_ca'); 

// Test 2 Static method 
echo " Test 2 - Static class method:" . getNrOfParams(array('Smart', 'myCallableMethod')); 

// Test 3 Object method 
$smart = new Smart(); 
echo " Test 3 - Object method:" . getNrOfParams(array($smart, 'my_callable')); 

// Test 4 Static method call (As of PHP 5.2.3) 
//echo " Test 4 - Static class method call:" . getNrOfParams('Smart::myCallableMethod'); 
// Calling a static method this way does not work in ReflectionFunction. 
// However, Test 2 provides a solution. 

// Test 5 Relative static method (As of PHP 5.3.0) 
//echo " Test 5 - Relative static class method:" . getNrOfParams(array('Smarter', 'parent::who')); 
// Calling a relative static method doesn't work either. ReflectionMethod lacks support. 
// All other tests work. 

// Tesy 6 __invoke 
echo " Test 6 - __invoke:" . getNrOfParams(array($smart, '__invoke')); 

// Test 7 Closure 
$closure = function($one, $two, $three) 
{ 
    // Magic 
}; 
echo " Test 7 - Closure:" . getNrOfParams($closure); 
+0

बहुत बढ़िया! इस जवाब को स्वीकार किया क्योंकि इसमें जो कुछ भी मैं ढूंढ रहा था उसे शामिल करता हूं ... अच्छा काम :) – kander

0

आप तर्क के साथ सरणी पारित कर सकते हैं और कॉलबैक फ़ंक्शन में दिए गए तर्क को जानने के लिए सरणी मानों को गिन सकते हैं।

संबंधित मुद्दे