完整程式碼
<?php
// RSS 來源陣列
$rssfeed = array(
"https://www.example.com/feed",
"https://rss.example.com/news.xml",
"https://blog.example.com/rss.xml"
);
// 設定輸出編碼
header('Content-Type: text/html; charset=UTF-8');
for ($i = 0; $i < sizeof($rssfeed); $i++) {
$buff = "";
$rss_str = "";
// 讀取 RSS 內容
$fp = fopen($rssfeed[$i], "r") or die("無法開啟 $rssfeed[$i]");
while (!feof($fp)) {
$buff .= fgets($fp, 4096);
}
fclose($fp);
// 建立 XML 解析器
$parser = xml_parser_create();
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
xml_parse_into_struct($parser, $buff, $values, $idx);
xml_parser_free($parser);
$is_item = 0;
$title = '';
$link = '';
foreach ($values as $val) {
$tag = strtolower($val["tag"]);
$type = $val["type"];
$value = $val["value"];
if ($tag == "item" && $type == "open") {
$is_item = 1;
} elseif ($tag == "item" && $type == "close") {
// 產生輸出連結
$rss_str .= "<a href='$link' target='_blank'>$title</a><br />";
$is_item = 0;
}
// 僅讀取 item 內的 title 與 link
if ($is_item == 1) {
if ($tag == "title") { $title = $value; }
if ($tag == "link") { $link = $value; }
}
}
echo $rss_str . "<br />";
}
?>
關鍵技術點解析
| 函數/步驟 | 說明 |
xml_parser_create() | 建立 XML 解析器 |
XML_OPTION_SKIP_WHITE | 忽略空白節點,減少陣列大小 |
xml_parse_into_struct() | 將 XML 解析為結構化陣列 $values(含 tag、type、value、level 等) |
| 狀態機邏輯 | 用 $is_item 旗標追蹤是否在 <item> 區塊內,僅擷取該區塊的 title/link |
編碼處理建議
- RSS 來源編碼不一(UTF-8、Big5、GB2312),建議先偵測編碼再統一轉 UTF-8
- 可使用
mb_detect_encoding() + iconv() 或 mb_convert_encoding()
現代替代方案
PHP 5.1+ 內建 SimpleXML,語法更簡潔:
<?php
$xml = simplexml_load_file('https://example.com/feed');
foreach ($xml->channel->item as $item) {
echo "<a href='{$item->link}' target='_blank'>{$item->title}</a><br/>";
}
?>
總結
傳統 XML 解析器適合需精細控制的場景,SimpleXML 則適合快速開發。實務上建議加上快取機制(如檔案快取 10 分鐘),避免頻繁請求外部 RSS 來源導致效能問題。
- 上一篇文章: PHP 自適應分頁類:智慧型頁碼範圍與 SQL LIMIT 產生器
- 下一篇文章: Delphi IStream 與 TStream 相互轉換實作
Copyright ©
程式碼之家 All Rights Reserved