2013-02-04 16 views
5

कोड शब्दों से बेहतर बोलती है:सापेक्ष नामस्थान और call_user_func()

namespaces.php:

<?php 

namespace foo; 

use foo\models; 

class factory 
{ 
    public static function create($name) 
    { 
     /* 
     * Note 1: FQN works! 
     * return call_user_func("\\foo\\models\\$name::getInstance"); 
     * 
     * Note 2: direct instantiation of relative namespaces works! 
     * return models\test::getInstance(); 
     */ 

     // Dynamic instantiation of relative namespaces fails: class 'models\test' not found 
     return call_user_func("models\\$name::getInstance"); 
    } 
} 

namespace foo\models; 

class test 
{ 
    public static $instance; 

    public static function getInstance() 
    { 
     if (!self::$instance) { 
      self::$instance = new self; 
     } 

     return self::$instance; 
    } 

    public function __construct() 
    { 
     var_dump($this); 
    } 
} 

namespace_test.php:

<?php 

require_once 'namespaces.php'; 

foo\factory::create('test'); 

टिप्पणी की के रूप में, अगर मैं call_user_func() के अंदर पूर्ण-योग्य नाम का उपयोग करें, यह अपेक्षा के अनुसार काम करता है, लेकिन यदि मैं सापेक्ष नेमपैक का उपयोग करता हूं es यह कहता है कि कक्षा – नहीं मिली लेकिन प्रत्यक्ष तत्काल कार्य करता है। क्या मुझे कुछ या उसके अजीब डिज़ाइन से याद आ रहा है?

+1

मेरा मानना ​​है कि यह डिज़ाइन द्वारा है। वही नियम 'परिभाषित()', 'निरंतर()', आदि जैसे कार्यों के लिए लागू होता है। [यह टिप्पणी] देखें (http://www.php.net/manual/en/function.defined.php#110530) । – Passerby

उत्तर

7

आपको कॉलबैक में पूरी तरह से योग्य क्लासनाम का उपयोग करना होगा।

Example #3 call_user_func() using namespace name

<?php 

namespace Foobar; 

class Foo { 
    static public function test() { 
     print "Hello world!\n"; 
    } 
} 

call_user_func(__NAMESPACE__ .'\Foo::test'); // As of PHP 5.3.0 
call_user_func(array(__NAMESPACE__ .'\Foo', 'test')); // As of PHP 5.3.0 

मेरा मानना ​​है कि इस वजह से call_user_func, वैश्विक क्षेत्र से एक समारोह है वैश्विक क्षेत्र के कॉलबैक को क्रियान्वित करने के साथ-साथ देखें। किसी भी मामले में, पहली वाक्य देखें।

इसके अलावा Example #2 Dynamically accessing namespaced elements ऊपर टिप्पणी जिसमें कहा गया है

एक पूरी तरह से योग्य नाम (नामस्थान उपसर्ग के साथ वर्ग के नाम) का उपयोग करना चाहिए देखें।

+2

मैंने यह मैन्युअल प्रविष्टि पूछने से पहले देखा था, लेकिन मैंने सोचा कि यह सिर्फ एक उदाहरण था, अब यह स्पष्ट है कि यह एक नियम है ... कभी-कभी उन्हें बेहतर प्रलेखन टिप्पणियों की कमी होती है। धन्यवाद! :) –

+1

मुझे यह स्वीकार करना है कि मैनुअल से मैंने पूरी तरह से अनुभाग ["नेमस्पेस और गतिशील भाषा विशेषताओं"] (http://php.net/namespaces.dynamic) को याद किया है ... इसे फिर से इंगित करने के लिए धन्यवाद जब मैं मैनुअल पढ़ता हूं तो मैं अधिक ध्यान दूंगा! :) –

1

PHP के वर्तमान संस्करणों में, जिस तरह से आपके पास यह है, क्लासनाम को संदर्भित करने के लिए स्ट्रिंग का उपयोग करते समय, इसे पूर्ण नामस्थान के साथ पूरी तरह से योग्यता प्राप्त करने की आवश्यकता है। यह बहुत अच्छा नहीं है, लेकिन यह वही तरीका है।

आने वाले PHP v5.5 में, इसमें एक नया Classname::class सिंटैक्स प्रदान करके इसे संबोधित करने के लिए एक सुविधा शामिल होगी, जिसे आप स्ट्रिंग में FQN क्लासनाम डालने के बजाय उपयोग कर सकते हैं।

इस बारे में अधिक जानकारी के लिए, कृपया यहाँ प्रासंगिक पीएचपी आरएफसी पृष्ठ देखें: https://wiki.php.net/rfc/class_name_scalars

आपका कोड कुछ इस तरह दिखेगा:

return call_user_func([models\$name::class,"getInstance"]); 

कि सटीक नहीं हो सकता है; पुष्टि करने के लिए मेरे पास परीक्षण करने के लिए 5.5 की एक प्रति नहीं है। लेकिन किसी भी तरह से, नया वाक्यविन्यास आपके जैसे उपयोग मामलों के लिए चीजों को बेहतर बना देगा।

+0

यह जानना बहुत अच्छा है कि वे जानते हैं कि चीजें हमें बेहतर बनाती हैं, उस जानकारी के लिए धन्यवाद! :) –

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