2009-12-08 30 views
12

मैं कास्टिंग तंत्र PHPs चारों ओर poking था के रूप में संख्यात्मक कुंजियों के साथ किसी सरणी कास्टिंग है और जब एक वस्तुएक वस्तु

$o = (object) array('1'=>'/foo/bar'); 
$o = new stdClass(); 
var_dump($o); 

मैं यह समझ के रूप में, पीएचपी गुण होने की जरूरत के रूप में एक सरणी कास्टिंग एक अजीब मामला में भाग PHP चर के समान नियमों के साथ घोषित किया गया। वह A valid variable name starts with a letter or underscore, followed by any number of letters, numbers, or underscores है। हालांकि, उपरोक्त कोड निम्नलिखित आउटपुट

object(stdClass)#1 (1) { 
    [1]=> 
    string(8) "/foo/bar" 
} 

जहां यह वास्तव में अजीब हो जाता है जब आप ऑब्जेक्ट में उस जानकारी तक पहुंचने का प्रयास करते हैं।

var_dump($o->1);  // parse error 
var_dump($o->{'1'});  // NULL 
var_dump(get_object_vars($o)); //array(0) { } 

में जानकारी है कि रिपोर्ट var_dump वस्तु में है प्राप्त करने के लिए वैसे भी वहाँ है, या यह सिर्फ अनुरोध जीवन चक्र के आराम के लिए बंद कर दिया जाता है? (इसका व्यावहारिक उपयोग शून्य है, मैं सिर्फ उत्सुक हूं)

+0

मेरे अनुभव से ऐसा लगता है जैसे वे दूर बंद हैं, हालांकि मैं कभी नहीं किया है पर्याप्त अटल सब कुछ कोशिश करने के लिए किया गया। – jlb

+0

वास्तव में यह मामला है, यह PHP में एक ज्ञात मुद्दा है। – GSto

+0

जिसे हमारे द्वारा ज्ञात के रूप में जाना जाता है, या जिसे PHP टीम द्वारा किसी भी तरीके से स्वीकार किया जाता है। –

उत्तर

13

हां, वे तब तक बंद हो जाते हैं जब तक कि किसी सरणी पर वापस नहीं आ जाता। PHP में कुछ छोटे "गॉटचास" हैं, उदाहरण के लिए पुराने संस्करणों में आप निरंतर एक सरणी के रूप में परिभाषित कर सकते हैं, लेकिन फिर कभी भी इसके तत्वों तक पहुंच नहीं सकते। अब भी आप एक संसाधन के रूप में निरंतर परिभाषित कर सकते हैं (उदा।, define('MYSQL',mysql_connect());) हालांकि इससे अपेक्षाकृत अप्रत्याशित व्यवहार होता है और फिर से बचा जाना चाहिए।

आम तौर पर, यदि संभव हो तो सरणी-से-ऑब्जेक्ट से बचने के लिए सबसे अच्छा है। क्या तुम सच में ऐसा करने की जरूरत है, stdClass का एक नया उदाहरण बनाने और फिर मैन्युअल _0, _1 को सभी चर का नाम बदलने, उदाहरण के लिए, आदि

$a = array('cat','dog','pheasant'); 
$o = new stdClass; 
foreach ($a as $k => $v) { 
    if (is_numeric($k)) { 
     $k = "_{$k}"; 
    } 
    $o->$k = $v; 
} 

संपादित करने पर विचार: बस इस परिकल्पना पर एक और त्वरित परीक्षण किया , और हां, वे ऑब्जेक्ट संदर्भ में आधिकारिक तौर पर "अस्तित्व में नहीं हैं"; डेटा संग्रहीत किया जाता है, लेकिन इसका उपयोग करना असंभव है, और इसलिए अंतिम निजी सदस्य है। यहां परीक्षण है:

$a = array('one','two','three'); 
$o = (object)$a; 
var_dump(property_exists($o, 1), property_exists($o, '1')); 

और उत्पादन होता है:

bool(false) 
bool(false) 

संपादित करें फिर से: दिलचस्प अतिरिक्त नोट, निम्नलिखित आपरेशन वापस झूठी आता है:

$a = array('one','two','three','banana' => 'lime'); 
$b = array('one','two','banana' => 'lime'); 

$y = (object)$a; 
$z = (object)$b; 

var_dump($y == $z); 
+2

यह _is_ वास्तव में [एक बग] (https://bugs.php.net/bug.php?id=45959)। इसे "ठीक करने के लिए बहुत महंगा" माना गया है और संकल्प "इस बेकार क्विर्क का वर्णन करने के लिए प्रलेखन को अद्यतन किया गया है, इसलिए अब यह आधिकारिक रूप से सही व्यवहार है"। – lanzz

0

मुझे लगता है कि आप प्राप्त एक त्रुटि क्योंकि किसी ऑब्जेक्ट/उपरोक्त को किसी सरणी की पूर्णांक कुंजी कास्टिंग करना PHP varibles के नामकरण सम्मेलनों को तोड़ देगा।

सुझाव:

  • चाहे आप एक OBJECT या एक ARRAY
  • प्रकार कास्टिंग के साथ सावधान रहें करना चाहते हैं हाथ से पहले तय (जैसे (वस्तु) सरणी (1 => 'स्ट्रिंग') नहीं करते ऐसी बातें) सत्यापन के लिए
  • कास्टिंग का प्रयोग करें और नहीं बातें कन्वर्ट करने के लिए
  • से बचें के रूप में "नकली" सरणियों वस्तुओं का उपयोग कर
7

ऐसा लगता है कि ArrayObject वर्ग गुण

$a = new ArrayObject($obj); 
echo $a[0]; 
+0

यह बहुत आसान है। धन्यवाद! – SuitedSloth

1

हाँ उपयोग कर सकते हैं, वे तो बस दूर जब तक डाली वापस एक सरणी के लिए बंद हैं।

शायद, गुण अभी भी वहां हैं और केवल पहुंच योग्य नहीं हैं। हालांकि, मुझे यकीन नहीं है कि कैसे foreach आंतरिक रूप से काम करता है (यह ऑब्जेक्ट को सरणी में डाल सकता है) क्योंकि मैंने सोर्स कोड में डाइव नहीं किया है।

उदाहरण:

$array = array('one', 'two', 'three', 'four'); 
$obj = (object) $array; 

foreach ($obj as $key => &$val) { 
    print "$key -> $val<br>"; 
    $val = 'Nhaca'; 
    var_dump($obj); 
} 
print_r($obj); 
print_r($array); 

उत्पादन:

0 -> one 
object(stdClass)[1] 
    &string 'Nhaca' (length=5) 
    string 'two' (length=3) 
    string 'three' (length=5) 
    string 'four' (length=4) 
1 -> two 
object(stdClass)[1] 
    string 'Nhaca' (length=5) 
    &string 'Nhaca' (length=5) 
    string 'three' (length=5) 
    string 'four' (length=4) 
2 -> three 
object(stdClass)[1] 
    string 'Nhaca' (length=5) 
    string 'Nhaca' (length=5) 
    &string 'Nhaca' (length=5) 
    string 'four' (length=4) 
3 -> four 
object(stdClass)[1] 
    string 'Nhaca' (length=5) 
    string 'Nhaca' (length=5) 
    string 'Nhaca' (length=5) 
    &string 'Nhaca' (length=5) 
stdClass Object ([0] => Nhaca [1] => Nhaca [2] => Nhaca [3] => Nhaca) 
Array ([0] => one [1] => two [2] => three [3] => four) 
संबंधित मुद्दे