GORAGOD.com

บทที่ 32 RSS feed reader ด้วย AJAX

ใน RSS บทก่อนๆ จะเป็นการ parse ด้วย Javascript แต่โค้ดนี้จะเป็นการ parse ด้วย PHP ครับ ซึ่งการ parse ด้วย PHP สามารถมีได้ 2 ลักษณะใหญ่ ก็คือการ parse ด้วย Library ของ PHP เองซึ่ง PHP สนับสนุนฟังก์ชั่นนี้ด้วย เช่น

$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
xml_parser_free($xml_parser);

อีกแบบหนึ่งคือการ parse ด้วยฟังก์ชั่นที่เขียนขึ้นเอง ดังตัวอย่างนี้ ซึ่งทำให้ไม่ต้องกังวลว่า PHP จะสนับสนุนหรือไม่

ไฟล์นี้เป็นส่วนของการ parse ครับ ส่วนตัวอย่างและโค้ด เป็นการอ่าน RSS feed ดูโค้ดส่วน AJAX ได้ที่ตัวอย่างเลย การเขียน header ของ XML กลับลงไปอีกเพื่อไม่ให้ต้องกังวลเรื่องภาษาครับ และโค้ด สามารถแสดงรูปที่แทรกมาในเอกสารได้

<?
set_time_limit(30000); //กำหนดเวลา time out เพื่อให้อ่านได้นานขึ้น

$feedURL = str_replace(";", "&", $_POST['url']);

if($feedURL & preg_match("/^https?:\/\/.+$/",$feedURL) & ($feedRef = @fopen($feedURL, 'rb'))) {
  $contents = '';
  while(!feof($feedRef)) {
    $contents .= fread( $feedRef, 8192 );
  }
  fclose($feedRef);
  $charset=getXMLHeader($contents);
  if ($charset=="") $charset="UTF-8";
  header("content-type: application/x-javascript; charset=$charset"); //เขียน header ของเอกสาร จาก XML ที่่ได้รับ
  $rss = RSStoArray($contents); //parse RSS ออกเป็น array
  //print_r($rss[0]); //แสดงข้อมูล ถ้าต้องการดูข้อมูลในรูปแอเรย์
} else { //หากไม่สามารถอ่าน RSS ได้
  header("content-type: application/x-javascript; charset=UTF-8");
  $rss[0][title][data] = 'Invalid feed URL detected';
  $rss[0][description][data] = 'RSS newsfeeds are served with a URL beginning with http:// or https://';
  $rss[0][link][data] = 'http://www.google.com/search?q=rss';
}

//อ่าน header
function getXMLHeader($xml) {
  $headers = explode("<?xml", $xml);
  $ret="";
  for ($i=0; $i<count($headers); $i++) {
    $ret.=parseXMLHeader(trim($headers[$i]));
  }
  return $ret;
}

//แยกเอา attributies ออก
function parseXMLHeader($data) {
  if ($data!="") {
    $EndPos = strpos($data, '?>'); //ค้นหา tag ปิดของ header
    $datas = explode(" ", substr($data, 0, $EndPos));
    for ($i=0; $i<count($datas); $i++) {
      $temps = explode("=", $datas[$i]);
      if (trim($temps[0])=='encoding') {
        $value = trim($temps[1]);
        $value = str_replace('"', '', $value);
        $value = str_replace("'", '', $value);
        return $value;
      }
    };
  }
  return;
}

//เปลี่ยน XML เป็น แอเรย์ของ RSS
function RSStoArray($xml) {
  $channels = preg_split('/<channel[\s|>]/', $xml, -1, PREG_SPLIT_NO_EMPTY);
  array_shift($channels);
  $i = 0;
  foreach ($channels as $channel) {
    $array[$i]['title'] = getTextBetweenTags($channel, 'title');
    $array[$i]['link'] = getTextBetweenTags($channel, 'link');
    $array[$i]['description'] = getTextBetweenTags($channel, 'description');
    $array[$i]['pubDate'] = getTextBetweenTags($channel, 'pubDate');
    $array[$i]['image'] = getImage($channel);
    $array[$i]['items'] = getItems($channel);
    $i++;
  }

  return $array;
}

//อ่าน Image ในส่วน header
function getImage($text) {
  preg_match("'<image.*?>(.*?)</image>'si", $text, $out);
  if (isset($out[1])) {
    preg_match("'<title.*?>(.*?)</title>'si", $out[1], $ret);
    $image['title'] = $ret[1];
    preg_match("'<url.*?>(.*?)</url>'si", $out[1], $ret);
    $image['url'] = $ret[1];
    preg_match("'<link.*?>(.*?)</link>'si", $out[1], $ret);
    $image['link'] = $ret[1];
    preg_match("'<width.*?>(.*?)</width>'si", $out[1], $ret);
    $image['width'] = $ret[1];
    preg_match("'<height.*?>(.*?)</height>'si", $out[1], $ret);
    $image['height'] = $ret[1];
  };

  return $image;
}

//อ่านรายการ item ทั้งหมด
function getItems($xml) {
  $items = preg_split('/<item[\s|>]/', $xml, -1, PREG_SPLIT_NO_EMPTY);
  array_shift($items);
  $i = 0;

  foreach ($items as $item) {
    $array[$i]['title'] = getTextBetweenTags($item, 'title');
    $array[$i]['link'] = getTextBetweenTags($item, 'link');
    $array[$i]['description'] = getTextBetweenTags($item, 'description');
    $array[$i]['author'] = getTextBetweenTags($item, 'author');
    $array[$i]['category'] = getTextBetweenTags($item, 'category');
    $array[$i]['comments'] = getTextBetweenTags($item, 'comments');
    $array[$i]['enclosure'] = getTextBetweenTags($item, 'enclosure');
    $array[$i]['guid'] = getTextBetweenTags($item, 'guid');
    $array[$i]['pubDate'] = getTextBetweenTags($item, 'pubDate');
    $array[$i]['source'] = getTextBetweenTags($item, 'source');
    $i++;
  }

  return $array;
}

//อ่าน tag และ property
function getTextBetweenTags($text, $tag) {
  $StartTag = "<$tag";
  $EndTag = "</$tag";

  $StartPosTemp = strpos($text, $StartTag);
  $StartPos = strpos($text, '>', $StartPosTemp);
  $StartPos = $StartPos + 1;
  $EndPos = strpos($text, $EndTag);
  
  $StartAttr = $StartPosTemp + strlen($StartTag) + 1;
  $EndAttr = $StartPos;
  if ($EndAttr > $StartAttr) {
    $attribute = substr ($text, $StartAttr, $EndAttr - $StartAttr - 1);
    $datas = explode(" ", $attribute);
    for ($i=0; $i<count($datas); $i++) {
      $temps = explode("=", $datas[$i]);
      $name = trim($temps[0]);
      if ($name!="/" & $name!="") {
        $value = trim($temps[1]);
        $value = str_replace('"', '', $value);
        $value = str_replace("'", '', $value);
        $items[$name] = trim($value);
      }
    }
  };

  if($EndPos > $BeginPos) {
    $text = substr ($text, $StartPos, ($EndPos - $StartPos));
  } else {
    $text = '';
  }
  if (strpos($text, '[CDATA[')==false) {
    $text = str_replace('&lt;', '<', $text);
    $text = str_replace('&gt;', '>', $text);
    $text = str_replace('&amp;', '&', $text);
    $text = str_replace('&quot;', '"', $text);
  } else {
    $text = str_replace('<![CDATA[', '', $text);
    $text = str_replace(']]>', '', $text);
  }
  $items["data"] = trim($text);

  return $items;
}

$cols=1;

//แสดงผล
for ($n=0; $n<count($rss); $n++) {
  echo "<div class=\"rss_header\">";
  if ($rss[$n][image][url]!="") {
    echo "<img src=\"".$rss[$n][image][url]."\" alt=\"".$rss[$n][image][title]."\" /><br /> ";
  }
  echo "<a href=\"".$rss[$n][link][data]."\" target=\"_blank\" class=\"rss_a_header\">".$rss[$n][title][data]."</a><br /> ";
  echo $rss[$n][description][data];
  echo "</div><br /> ";
  echo "<table class=\"rss\" celllpadding=\"0\" cellspacing=\"0\"> <tr class=\"rss\">";
  $c=0;
  for($i=0; $i<count($rss[$n][items]); $i++) {
    $c++;
    if (($c>=$cols & $i>0) || ($cols==1 & $i>0)) {
      echo "</tr> <tr class=\"rss\">";
      $c=0;
    }
    echo "<td class=\"rss\">";
    echo "<div class=\"header\"><img src=\"img/bullet.gif\" alt=\"\" />&nbsp;&nbsp;<a href=\"".$rss[$n][items][$i][link][data]."\" target=\"_blank\">".$rss[$n][items][$i][title][data]."</a></div>";
    $enclosure_type=$rss[$n][items][$i][enclosure][type];
    echo "<div class=\"content\">";
    if ($enclosure_type=="image/jpeg" || $enclosure_type=="image/gif") {
      echo "<img src=\"".$rss[$n][items][$i][enclosure][url]."\" alt=\"\" /><br />";
    };
    echo $rss[$n][items][$i][description][data]."</div></td>";
  }
  echo "</tr> </table><br /> ";
}
?>

ตัวอย่าง
 (468)
 (468)