2017-09-29 11 views
5

PHP कैसे &$this की व्याख्या करता है? इसकी अनुमति क्यों है?

मैं निम्नलिखित प्रश्नों के साथ इस प्रश्न पर आया, जो PHP 7.1 और 7.2 में एक बग की तरह दिखता है। यह &$this संदर्भ और क्रॉस-नेमस्पेस कॉल और call_user_func_array के साथ होता है। मुझे लगता है कि &$this बहुत अजीब है और इसकी अनुमति नहीं दी जानी चाहिए, लेकिन वर्डप्रेस उदाहरण के लिए इसका उपयोग करता है।

<?php 
namespace N { 
    function callNeedRef($a) { 
     var_dump($a); 
     call_user_func_array('needRef', $a); 
    } 
} 

namespace { 
    function needRef(&$r) { } 
    function callNeedRef($a) { 
     var_dump($a); 
     call_user_func_array('needRef', $a); 
    } 

    class C { 
     function f() { 
      $a = $this; 
      callNeedRef(array(&$a));  // no warning (expected), OK! 
      N\callNeedRef(array(&$a));  // no warning (expected), OK! 
      callNeedRef(array(&$this)); // no warning (expected), but 7.1,7.2: var_dump prints no '&'   
      N\callNeedRef(array(&$this)); // 7.1,7.2: warn and var_dump prints no '&'   
     } 
    } 

    echo "<pre>"; 
    echo phpversion() . PHP_EOL; 
    $o = new C(); 
    $o->f(); 
} 

और इसके उत्पादन:

7.2.0RC2 
array(1) { 
    [0]=> 
    &object(C)#1 (0) { 
    } 
} 
array(1) { 
    [0]=> 
    &object(C)#1 (0) { 
    } 
} 
array(1) { 
    [0]=> 
    object(C)#1 (0) { 
    } 
} 
array(1) { 
    [0]=> 
    object(C)#1 (0) { 
    } 
} 


Warning: Parameter 1 to needRef() expected to be a reference, value given in reftest.php on line 6 

जैसा कि पहले ही कोड में कहा गया है, दो पिछले var_dump रों न संदर्भ के रूप में वस्तु को चिह्नित

इस कोड पर विचार करें। और अंतिम कॉल भी चेतावनी के रूप में पैदा करता है।

+0

पीएचपी स्रोत कोड पर गौर करने के लिए। यहां सभी PHP संस्करणों में क्या होता है: https://3v4l.org/8Ftbh#output –

उत्तर

1

वैल ($this) वैश्विक नहीं है, दायरा बदलता है, इसलिए यह ZCAL_STR_COPY ied मिलता है।

case EXTR_OVERWRITE: 
     /* GLOBALS protection */ 
     if (var_exists && ZSTR_LEN(var_name) == sizeof("GLOBALS")-1 && !strcmp(ZSTR_VAL(var_name), "GLOBALS")) { 
       break; 
     } 
     if (var_exists && ZSTR_LEN(var_name) == sizeof("this")-1 && !strcmp(ZSTR_VAL(var_name), "this")) { 
       zend_class_entry *scope = zend_get_executed_scope(); 
       if (scope && ZSTR_LEN(scope->name) != 0) { 
         break; 
       } 
     } 
     ZVAL_STR_COPY(&final_name, var_name); 
     break; 

धन्यवाद मुझे सिर्फ एक अद्यतन के रूप में के लिए array.c :)

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