2008-09-15 8 views
21

मैं एक PHP वर्ग लिखने में सक्षम होना चाहता हूं जो एक सरणी की तरह व्यवहार करता है और & सेटिंग प्राप्त करने के लिए सामान्य सरणी वाक्यविन्यास का उपयोग करता है।एक PHP ऑब्जेक्ट बनाना एक सरणी की तरह व्यवहार करता है?

उदाहरण के लिए

(जहां फू मेरी बनाने की एक PHP वर्ग है):

$foo = new Foo(); 

$foo['fooKey'] = 'foo value'; 

echo $foo['fooKey']; 

मैं जानता हूँ कि पीएचपी _GET और _set जादू तरीकों है कि लेकिन उन आप आइटम का उपयोग करने की सरणी संकेतन का उपयोग न दें। पायथन इसे __getitem__ और __setitem__ ओवरलोडिंग द्वारा संभालता है।

क्या PHP में ऐसा करने का कोई तरीका है? अगर इससे कोई फर्क पड़ता है, तो मैं PHP 5.2 चला रहा हूं।

उत्तर

35

यदि आप ArrayObject बढ़ाते हैं या ArrayAccess लागू करते हैं तो आप जो भी चाहते हैं वह कर सकते हैं।

+0

बहुत अच्छा। ऐसा लगता है कि उनमें से किसी एक का उपयोग सरणी कार्यों जैसे array_key_exists, आदि के साथ किया जा सकता है क्या यह सही है? –

+0

सही, इसके बजाय offsetExist() विधि का उपयोग करें। –

+0

क्या मैं इसे तुरंत ऑब्जेक्ट पर करूँगा? अगर ($ foo-> ऑफसेट एक्स्टिस्ट्स ('fooKey')) {} –

2

नहीं, कास्टिंग सिर्फ एक सामान्य पीएचपी सरणी में परिणाम - खोने जो कुछ कार्यक्षमता आपके ArrayObject व्युत्पन्न वर्ग था। इसे देखें:

class CaseInsensitiveArray extends ArrayObject { 
    public function __construct($input = array(), $flags = 0, $iterator_class =  'ArrayIterator') { 
     if (isset($input) && is_array($input)) { 
      $tmpargs = func_get_args(); 
      $tmpargs[0] = array_change_key_case($tmpargs[0], CASE_LOWER); 
      return call_user_func_array(array('parent', __FUNCTION__), $tmp args); 
     } 
     return call_user_func_array(array('parent', __FUNCTION__), func_get_args()); 
    } 

    public function offsetExists($index) { 
     if (is_string($index)) return parent::offsetExists(strtolower($index)); 
     return parent::offsetExists($index); 
    } 

    public function offsetGet($index) { 
     if (is_string($index)) return parent::offsetGet(strtolower($index)); 
     return parent::offsetGet($index); 
    } 

    public function offsetSet($index, $value) { 
     if (is_string($index)) return parent::offsetSet(strtolower($index, $value)); 
     return parent::offsetSet($index, $value); 
    } 

    public function offsetUnset($index) { 
     if (is_string($index)) return parent::offsetUnset(strtolower($index)); 
     return parent::offsetUnset($index); 
    } 
} 

$blah = new CaseInsensitiveArray(array(
    'A'=>'hello', 
    'bcD'=>'goodbye', 
    'efg'=>'Aloha', 
)); 

echo "is array: ".is_array($blah)."\n"; 

print_r($blah); 
print_r(array_keys($blah)); 

echo $blah['a']."\n"; 
echo $blah['BCD']."\n"; 
echo $blah['eFg']."\n"; 
echo $blah['A']."\n"; 

जैसा कि अपेक्षित है, array_keys() कॉल विफल हो जाती है। इसके अलावा, is_array ($ blah) झूठी वापसी करता है। लेकिन अगर आप को निर्माता लाइन बदलने के लिए:

$blah = (array)new CaseInsensitiveArray(array(

तो आप सिर्फ एक सामान्य पीएचपी सरणी (is_array ($ blah) सच देता है, और array_keys ($ blah) काम करता है) मिलता है, लेकिन ArrayObject की कार्यक्षमता के सभी -साइड सबक्लास खो गया है (इस मामले में, केस-असंवेदनशील कुंजी अब काम नहीं करती हैं)। उपरोक्त कोड को दोनों तरीकों से चलाने का प्रयास करें, और आप देखेंगे कि मेरा क्या मतलब है।

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

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