2013-01-31 12 views
5

मैं सी का उपयोग कर एक PHP विस्तार विकसित कर रहा हूं, अब तक मैं तर्कों के उचित सत्यापन पर काम कर रहा हूं, PHP उपयोगकर्ता स्थान से एक्सटेंशन के फ़ंक्शन पर पास कर चुका हूं।जेड END_BEGIN_ARG_INFO_EX तर्कों की नियंत्रण संख्या को कैसे PHP एक्सटेंशन में पास किया गया है?

मैक्रो ZEND_BEGIN_ARG_INFO_EX का उपयोग ज़ेंड इंजन को फ़ंक्शन के तर्कों के बारे में जानकारी प्रदान करने के लिए किया जा सकता है। required_num_args नामक मैक्रो का चौथा पैरामीटर, इंजन को मेरे द्वारा इस परेशानी को दूर करने, तर्कों की संख्या को स्वचालित रूप से नियंत्रित करने दें। हालांकि, मुझे इसे काम करने का तरीका नहीं मिला: इंजन हमेशा किसी भी चेतावनी के बिना एक्सटेंशन के फ़ंक्शन को चलाता है, भले ही कोई PHP स्क्रिप्ट पर्याप्त तर्क न दे।

ZEND_BEGIN_ARG_INFO_EX(test_func_swt_arginfo, 0, 0, 3) 
    ZEND_ARG_INFO(1, firstArg) 
    ZEND_ARG_ARRAY_INFO(0, secondArg, true) 
    ZEND_ARG_OBJ_INFO(1, thirdArg, SomeClass, false) 
ZEND_END_ARG_INFO() 

यहाँ कार्यों की मेरी परिभाषा, PHP एक्सटेंशन द्वारा निर्यात है:

यहाँ समारोह तर्क की मेरी परिभाषा है

PHP_FUNCTION(sample_with_types) 
{ 
    RETURN_TRUE; 
} 
:

static const zend_function_entry test_func_functions[] = { 
    PHP_FE(sample_with_types, test_func_swt_arginfo) 
    PHP_FE_END 
}; 

यहाँ मेरी समारोह है

यहां PHP स्क्रिप्ट I चलाया गया है:

<?php 
sample_with_types(); 

अपेक्षित परिणाम: PHP त्रुटि/चेतावनी/अपवाद दिखाता है, जैसे कुछ "फ़ंक्शन पर पर्याप्त तर्क पास नहीं किए जाते हैं"; समारोह निष्पादित नहीं करता है।

वास्तविक परिणाम: फ़ंक्शन निष्पादित करता है और true देता है।

मैं फ़ंक्शन तर्क संरचना को सही तरीके से कॉन्फ़िगर कैसे कर सकता हूं, ताकि ज़ेंड इंजन स्वचालित रूप से तर्कों की संख्या जांच सके? या क्या मैं ZEND_BEGIN_ARG_INFO_EX मैक्रो में required_num_args तर्क का उद्देश्य गलती करता हूं?

उत्तर

8

जहाँ तक मुझे पता है, यह ZEND_BEGIN_ARG_INFO_EX नहीं है।

ZEND_BEGIN_ARG_INFO_EX एक PHP 5 अतिरिक्त क्लीनर कोड बनाने के लिए उपयोग किया जाता है, प्रकार संकेत, पास-दर-संदर्भ और प्रतिबिंब सक्षम करता है। अपने वास्तविक समारोह है कि सिर्फ सच रिटर्न के लिए निम्नलिखित arginfo घोषणाओं पर विचार करें:

ZEND_BEGIN_ARG_INFO_EX(arginfo_test, 0, 0, 3) 
    ZEND_ARG_INFO(0, firstArg) 
    ZEND_ARG_OBJ_INFO(0, objNonNull, stdClass, 0) 
    ZEND_ARG_OBJ_INFO(0, obj, stdClass, 1) 
    ZEND_ARG_OBJ_INFO(1, objByRef, stdClass, 1) 
ZEND_END_ARG_INFO() 

यह निम्न प्रभाव पड़ता है:

$ref = new ReflectionFunction('sample_with_types'); 
var_dump($ref->getParameters()); 
:

sample_with_types();       // ok 
sample_with_types(1, null);     // error: arg #2 should be stdClass 
sample_with_types(1, new stdClass, null);  // ok 
sample_with_types(1, new stdClass, 1);  // error: arg #3 should be stdClass 
sample_with_types(1, new stdClass, null, 2); // error: arg #4 must be reference 

इसके अतिरिक्त, यह अपने कार्य करने के लिए प्रतिबिंब क्षमता प्रदान करता है

... आउटपुट देने के समान:

array(4) { 
    [0]=> 
    &object(ReflectionParameter)#2 (1) { 
    ["name"]=> 
    string(8) "firstArg" 
    } 
    [1]=> 
    &object(ReflectionParameter)#3 (1) { 
    ["name"]=> 
    string(10) "objNonNull" 
    } 
    [2]=> 
    &object(ReflectionParameter)#4 (1) { 
    ["name"]=> 
    string(3) "obj" 
    } 
    [3]=> 
    &object(ReflectionParameter)#5 (1) { 
    ["name"]=> 
    string(8) "objByRef" 
    } 
} 

यदि आप arginfo को छोड़ देते हैं, तो ReflectionFunction::getParameters() इसके बजाय एक खाली सरणी देता है।

required_num_args मैक्रो पैरामीटर विशेष रूप से प्रतिबिंब के लिए उपयोग किया जाता है, और यह दर्शाता है कि फ़ंक्शन को प्रतिबिंबित करते समय कितने पैरामीटर चिह्नित किए जाएंगे।

आप तर्क की आवश्यकता है और नहीं करने की जरूरत है सिर्फ उन्हें के रूप में आवश्यक जब प्रतिबिंब का उपयोग कर, आप अभी भी zend_parse_parameters है, जो ज्यादातर मामलों में, आप अभी भी बहस के वास्तविक मूल्यों को प्राप्त करने की आवश्यकता होगी का उपयोग करने के निशान:

PHP_FUNCTION(sample_with_types) 
{ 
    long arg1; 
    zval *arg2 = NULL, *arg3 = NULL, *arg4 = NULL; 
    zend_class_entry ce2, ce3, ce4; 

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "looo", &arg1, 
           &arg2, &ce2, &arg3, &ce3, &arg4, &ce4) == FAILURE) 
    { 
     return; 
    } 

    RETURN_TRUE; 
} 

नोट करें कि मैंने उपरोक्त में "looo" (जेनेरिक ऑब्जेक्ट प्रकार) और "lOO!O!" (शून्य विनिर्देशों के साथ विशिष्ट ऑब्जेक्ट प्रकार) का उपयोग कैसे किया। टाइपिंग संकेत पहले ही arginfo के साथ निर्दिष्ट किया गया है, इसलिए इसे दो बार करने की आवश्यकता नहीं है।

तो, arginfo बिना:

  • आप टाइप करने के लिए अपने ऑब्जेक्ट तर्क संकेत zend_fetch_class कॉल और वर्ग प्रविष्टियों में से एक मुट्ठी का उपयोग करना होगा।
  • यह प्रतिबिंब सक्षम नहीं करेगा।
  • आप संदर्भ द्वारा पारित तर्क घोषित करने में सक्षम नहीं होंगे।
  • यह स्पष्ट रूप से कम साफ कोड उत्पन्न करेगा।

स्पष्ट कारणों से, आप यह सुनिश्चित करना चाहते हैं कि आपकी arginfo घोषणा और आपके zend_parse_parameters कॉल मैचों।

+0

उस मैक्रो के उद्देश्य को स्पष्ट करने के लिए जानकारी और प्रयासों के लिए @netcoder धन्यवाद। यह बहुत अधिक समझ में आता है, और असल में मुझे पता चला कि सवाल पूछने से पहले। मुख्य, चीज, हालांकि, जिसने मेरी पहेली को जन्म दिया और मुझे एसओ में जाना पड़ा, 'required_num_args' पैरामीटर था। यह तर्क संख्या के स्वत: सत्यापन की तरह लग रहा था, लेकिन व्यवहार में यह कुछ भी नहीं करता है। क्या यह हो सकता है कि आप इसका उद्देश्य जानते हैं? –

+0

@AndreyTserkus: 'required_num_args' का उपयोग प्रतिबिंब के लिए किया जाता है और आवश्यकतानुसार गिनती पैरामीटर को रोकने के लिए इंगित करता है (यानी, 'isOptional()' को कॉल करते समय)। इसके अलावा इसका कोई प्रभाव नहीं है। (मैंने इस जानकारी के साथ उत्तर भी अपडेट किया है।) – netcoder

+0

बढ़िया, धन्यवाद! –

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

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