2010-08-27 4 views
5

मैं SplObjectStorage का उपयोग कर, ऊपर के उदाहरण की तरह एक साधारण समग्र पैटर्न को लागू किया है के साथ एक वस्तु पेड़ serializing त्रुटि:SplObjectStorage

class Node 
{ 
    private $parent = null; 

    public function setParent(Composite $parent) 
    { 
     $this->parent = $parent; 
    } 
} 

class Composite extends Node 
{ 
    private $children; 

    public function __construct() 
    { 
     $this->children = new SplObjectStorage; 
    } 

    public function add(Node $node) 
    { 
     $this->children->attach($node); 
     $node->setParent($this); 
    } 
} 

जब भी मैं एक समग्र वस्तु क्रमानुसार करने की कोशिश, पीएचपी 5.3.2 मुझे एक Segmentation Fault फेंकता है। यह तब होता है जब मैं ऑब्जेक्ट में किसी भी प्रकार के नोड्स जोड़ता हूं। अगर मैं ठीक भी SplObjectStorage के बजाय सरणी के साथ समग्र पैटर्न(), सभी रन लागू,

$node = new Node; 
$composite = new Composite; 
echo serialize($composite); 

भी: हालांकि यह एक काम करता है

$node = new Node; 
$composite = new Composite; 
$composite->add($node); 
echo serialize($composite); 

:

यह अपमानजनक कोड नहीं है।

मैं क्या गलत कर रहा हूं?

उत्तर

8

अभिभावक को सेट करके, आपके पास एक परिपत्र संदर्भ है। PHP समग्र को क्रमबद्ध करने का प्रयास करेगा, इसके सभी नोड्स और बदले में नोड्स समग्र को क्रमबद्ध करने का प्रयास करेंगे .. बूम!

सीरियलाइजिंग करते समय आप पैरेंट संदर्भ को हटाने (या जो कुछ भी करने के लिए) जादू __sleep and __wakeup() विधियों का उपयोग कर सकते हैं।

संपादित करें:

अगर इन Composite फिक्स करने के लिए इस मुद्दे को जोड़ने देखें:

public function __sleep() 
{ 
    $this->children = iterator_to_array($this->children); 
    return array('parent', 'children'); 
} 
public function __wakeup() 
{ 
    $storage = new SplObjectStorage; 
    array_map(array($storage, 'attach'), $this->children); 
    $this->children = $storage; 
} 
+1

... और समग्र में __wakeup विधि setParent (यह $) पर कॉल करके माता-पिता संदर्भ बहाल करने के लिए पर प्रत्येक बच्चे तत्व। – VolkerK

+1

धन्यवाद! मैंने सोचा कि serialize() संदर्भों से निपटने के लिए पर्याप्त स्मार्ट होगा, लेकिन यह नहीं बदलता है। मैंने इसे दोनों वर्गों में सीरियलज़ेबल इंटरफेस को कार्यान्वित करके हल किया है। – xPheRe