PHP 使用 SimpleXML 遇到 Illegal offset type(型態轉換問題) 解法

來源:互聯網
上載者:User
PHP 使用 SimpleXML 遇到 Illegal offset type(型態轉換問題) 解法

PHP 的 simplexml_load_string/simplexml_load_file 很方便, 很簡單的就能把 XML parse 成 PHP Object, 然後就看要怎麼處理資料, 再處理即可~

  • simplexml_load_string : 丟 XML 進去即可
  • simplexml_load_file : 丟 URL 進去也吃, 拿來 Parse XML/RSS Feed 超方便


簡單的處理都沒什麼異常, 但是現在遇到要將 Object value 轉換成一般 PHP Array 的 key -> value
型態就遇到問題了. 不曉得是我不會用還是怎麼樣, 查不到正確該怎麼解, 所以寫起來紀錄一下.(希望有正確解法, 還請指導.. Orz)

註: PHP Version: PHP 5.2.3

先來看一段簡單的程式範例(原始程式):

<?php<br />$data = <<<EOF<br /><?xml version="1.0" encoding="UTF-8"?><br /><response><br /> <status>0</status><br /> <result><br /> <doc><br /> <str name="title">title value</str><br /> <str name="description">description value</str><br /> </doc><br /> </result><br /></response><br />EOF;<br />$xml = simplexml_load_string($data);<br />$results = array();<br />foreach ($xml->result->doc as $story) {<br /> $xmlarray = array();<br /> try {<br /> foreach ($story as $item) {<br /> $name = $item->attributes()->name;<br /> $value = $item->attributes()->{0};<br /> $xmlarray[$name] = $value; // have "Illegal offset type" error.<br /> }<br /> } catch (Exception $e) {<br /> echo 'Problem handling XML array.';<br /> }<br /> print_r($xmlarray);<br />}<br />?>

此程式目的是要 讀取 $data 的 XML, 然後轉換成 $xmlarray, 並指定 $xmlarray 的 KEY 是 Tag attribute name 的值, VALUE 就是 name Tag 包起來的值, 或者直接看希望的執行結果 如下:

Array<br />(<br /> [title] => title<br /> [description] => description<br />)

但是執行結果是 $xmlarray 都是空的, 主要是出現下述 Warning:

Warning: Illegal offset type in xml.php on line 24

然後 var_dump($name) 來看看, 是 Object 的結構如下:

object(SimpleXMLElement)#9 (1) {<br /> [0]=><br /> string(5) "title"<br />}


明顯就是要在存取進 object 的 [0] 即可, 但是發現我試著 $name[0], $name->{0},
就是一直沒辦法單獨把值拿出來(用 $name[0], $name->{0} 用 var_dump() 都是同樣上述狀況),
而且一樣都是出現Illegal offset type的問題.

再來當然就網路找來找去, 似乎都沒有想說怎麼解(或許是我找的能力太差 Orz), 所以先放棄, 後來腦筋轉到型態轉換這邊去(想說型態一直轉不過來, 那我就強迫換型態好了).........就開始做做邪惡的事情囉~

於是我就對 $name 做 strval(), 沒想到一試就成功了~

所以程式改寫如下($data 沒變, 只修改最裡面 foreach, 先用 strval() 轉換型態):

<?php<br />$data = <<<EOF<br /><?xml version="1.0" encoding="UTF-8"?><br /><response><br /> <status>0</status><br /> <result><br /> <doc><br /> <str name="title">title value</str><br /> <str name="description">description value</str><br /> </doc><br /> </result><br /></response><br />EOF;<br />$xml = simplexml_load_string($data);<br />$results = array();<br />foreach ($xml->result->doc as $story) {<br /> $xmlarray = array();<br /> try {<br /> foreach ($story as $item) {<br /> $name = $item->attributes()->name;<br /> $value = $item->attributes()->{0};<br /> $name = strval($name); // 這邊用 $name/$name->{0} 都一樣<br /> $value = strval($value); // 這邊用 $value/$value->{0} 都一樣<br /> $xmlarray[$name] = $value;<br /> }<br /> } catch (Exception $e) {<br /> echo 'Problem handling XML array.';<br /> }<br /> print_r($xmlarray);<br />}<br />?>

這樣子執行後, $xmlarray 就是我們要的結果囉~

感謝 lp81sam 提供正解:

<?php<br />$data = <<<EOF<br /><?xml version="1.0" encoding="UTF-8"?><br /><response><br /> <status>0</status><br /> <result><br /> <doc><br /> <str name="title">title value</str><br /> <str name="description">description value</str><br /> </doc><br /> </result><br /></response><br />EOF;<br />$xml = simplexml_load_string($data);<br />$results = array();<br />foreach ($xml->result->doc as $story) {<br /> $xmlarray = array();<br /> try {<br /> foreach ($story as $item) {<br /> $$name = $item->getAttribute('name'); // use getAttribute()<br /> $value = $item->getAttribute(0);<br /> }<br /> } catch (Exception $e) {<br /> echo 'Problem handling XML array.';<br /> }<br /> print_r($xmlarray);<br />}<br />?>

getAttribute() 內部運行的模式大概如下:

public function getAttribute($name){<br /> foreach($this->attributes() as $key=>$val){<br /> if($key == $name){<br /> return (string)$val;<br /> }// end if<br /> }// end foreach<br />}// end function getAttribute

所以可以用 getAttribute() 去抓值, 或者跑 foreach 取值都可以

 

 

------------------------------------------------------------------------------------------------------------

 

原來如此, 我懂了... 主要是 getAttribute() 吧

getAttribute() 的內部運作是:
function getAttribute($name){
foreach($this->attributes() as $key=>$val) {
}
}
所以使用 foreach($this->attributes() as $key=>$val) 就可以把每個值拉出來, 然後再自行做處理.
或者就是用 getAttribute() 直接拉值就可以了~~~

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.