2011-12-10 17 views
12

मैं वस्तुओं की एक सरणी बना रहा हूं। मुझे इस सरणी की आवश्यकता होती है जिसमें केवल एक ऑब्जेक्ट का एक बार उदाहरण होता है, जिसमें एक ही ऑब्जेक्ट के कई संदर्भों को अपवाद फेंकना चाहिए। मैं इस लक्ष्य को हासिल करने के लिए निम्न कोड का उपयोग कर रहा:परिपत्र संदर्भों के साथ वस्तुओं पर in_array

public function addField ($name, iface\Node $field) 
{ 
    // Prevent the same field being added multiple times 
    if (!in_array ($field, $this -> fields)) 
    { 
     $this -> fields [$name] = $field; 
     $field -> setParent ($this); 
    } 
    else 
    { 
     throw new \InvalidArgumentException ('This field cannot be added to this group'); 
    } 
    return ($this); 
} 

इस समस्याओं के प्रमुख जब मैं वस्तुओं है कि नोड इंटरफ़ेस को लागू कार्यान्वयन शुरू कर दिया शुरू कर दिया है, क्योंकि वे वृत्तीय संदर्भ शामिल कर सकते हैं (वे अपने बच्चे नोड्स का एक संग्रह पकड़ , प्रत्येक बच्चे के माता-पिता के संदर्भ में)। एक क्षेत्र निम्न त्रुटि में परिणाम कर सकते जोड़ने की कोशिश कर उत्पन्न किया जा रहा:

PHP Fatal error: Nesting level too deep - recursive dependency?

मुझे लगता है कि पीएचपी, बजाय सिर्फ देखने के लिए अगर वे एक ही मूल्य पकड़ वस्तु संदर्भ की तुलना संपूर्ण वस्तु सरणी पार करने की कोशिश कर रहा है और है इसलिए एक ही वस्तु को इंगित करें।

मुझे क्या करने की आवश्यकता है I_rayray केवल उस ऑब्जेक्ट संदर्भों की तुलना करें जो इसे फ़ील्ड के ऑब्जेक्ट संदर्भ के साथ संग्रहीत करता है। यह पूरे ऑब्जेक्ट पेड़ को पार करने और रिकर्सन समस्या में चलने की कोशिश कर रहा है।

क्या ऐसा करने का कोई तरीका है?

+0

समानता जांचने की विधि को लागू करने के लिए अपने उद्देश्य पर '__equals' को ओवरराइड करने का प्रयास करें। –

उत्तर

16

जवाब बदलता है असाधारण सरल है। ऐसा लगता है कि सुई के लिए घास का परीक्षण करते समय डिफ़ॉल्ट in_array गैर-सख्त तुलना (एक == ऑपरेशन के बराबर) करता है। इसका अर्थ यह है कि यह जांचता है कि सभी गुण बराबर हैं, जिसका अर्थ यह है कि यह ऑब्जेक्ट ग्राफ़ को घुमाने में शुरू होता है, और यदि आपके पास उस ग्राफ में परिपत्र संदर्भ हैं तो इससे आपको परेशानी हो सकती है।

in_array फ़ंक्शन में सख्त मोड है, हालांकि, जहां तक ​​मैं कह सकता हूं कि एक === ऑपरेशन के बराबर है। ऐसा लगता है कि यह संदर्भ देखने के लिए संदर्भित करता है कि वे सभी गुणों की तुलना करने के बजाय एक ही वस्तु पर इंगित करते हैं या नहीं।

सीधे शब्दों में करने के लिए कोड को बदलने:

if (!in_array ($field, $this -> fields, true)) 

व्यवहार के रूप में मैं इसे प्रत्यावर्तन त्रुटि ट्रिगर किए बिना व्यवहार करने के लिए चाहता था विधि बनाता है।

मुझे यह कहना है कि मैं थोड़ा आश्चर्यचकित हूं कि PHP डिफ़ॉल्ट रूप से इस मोड को नहीं करता है। दूसरी तरफ मुझे लगता है कि मुझे आश्चर्यचकित नहीं होना चाहिए कि PHP की कमज़ोर टाइपिंग ने मुझे फिर से एक मुद्दा बना दिया है। :)

1

मैं या तो SplObjectStorage या spl_object_hash का उपयोग करूंगा।

और आप सही हैं, जब php चीजों की तुलना करता है तो यह संरचनाओं को बार-बार घुमाता है (सरणी भी)।

+0

क्या सिर्फ पॉइंटर्स की तुलना करने का कोई तरीका नहीं है? – mifki

+1

@ मिफ्की आप सख्त === तुलना कर सकते हैं। यह वस्तुओं के लिए अंक की तुलना करेगा। – NikiC

+0

प्रतिक्रिया के लिए धन्यवाद, लेकिन मुझे लगता है कि मुझे एक समाधान मिला है। – GordonM

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