顯示具有 xml 標籤的文章。 顯示所有文章
顯示具有 xml 標籤的文章。 顯示所有文章

2012/06/15

導致 PHP 語法錯誤的 xml 標籤

處理到一個很奇怪的問題。

有個負責 echo 出 xml 內容的 php 程式,一直出現語法錯誤:
Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING your_file.php on line 123

your_file.php 是在 Windows 環境來的,在 Linux 內使用 Vim 開啓時,行尾會出現 Windows 的蠢符號 ^M

我如同往常一樣使用以下指令將 ^M 清除:
:%s/^M//g
(^M 是壓 Ctrl + V 再壓 Ctrl + M 的效果)

但是 123 行一直報錯,123 行的 php code 類似這樣:
<p id="$_GET['id']">

如果把 123 行註解掉,在 Vim 內的重新輸入一模一樣的內容,就 ok 了!
看起來是有些神祕的行尾符號,人類的肉眼無法察覺,待查 .....

Vim 有沒有好的外掛顯示 space、tab、break 啊!?

熱心的朋友們給了許多解法:
曼珠:":set invlist"可達到要求嗎?我自己試用是看的到行尾的 $,但我沒有其他的不可見符號所以沒辧法進一步測試。原來 :set invlist 是 invert list 的簡寫(等同 :set list!),而查詢 'list' 後發現他能顯示 ^I 和行尾,但對於其他不可見字元就沒多寫了,所以可能要再查。

雲端CrBoy+:把那行複製出來塞進新的檔案 用 hexdump 去看!

__CA__.py:vim -b abc.php ?

Chester Chang:try hex editor

Reference:
http://www.perturb.org/display/679_Make_Vim_show_hidden_characters.html
http://grx.no/kb/2008/11/17/remove-windows-line-endings-in-vim/
http://www.grok2.com/blog/2010/04/21/getting-rid-of-m-ctrl-m-characters-in-windows-text-using-vim/
http://stackoverflow.com/questions/799417/gvim-showing-carriage-return-m-even-when-file-mode-is-explicitly-dos

====================================================

後來發現根本不是行尾的問題!

該 php 檔中混合了 php tag 與 xml tag,例如:
<?php
    // code
?>
<?xml version="1.0" encoding="UTF-8" ?>
<?php 
    // code
    echo $XML 
?>

如果修改成以下格式,將 xml tag 使用 heredoc 輸出就正確了:
<?php
    // code

    echo <<<HERE
<?xml version="1.0" encoding="UTF-8" ?>
 HERE

    // code
    echo $XML 
?>

看起來是 php 與 xml 的 tag 讓 Web Server 混亂了,不是行尾有問題 ....

2010/08/13

使用 PHP 動態產生 XML

直接看一個靜態的例子:
<?php
ob_start();
header('Content-Type: text/xml');

$dom = new DOMDocument('1.0');
$dom->encoding = 'UTF-8';

// 建立母節點 $root
$root = $dom->createElement('root');
$dom->appendChild($root);

// 設定屬性
$root->setAttribute('name', 'xxx');

// 建立 $root 的子節點 $child
$child = $dom->createElement('child');
$root->appendChild($child);

// 建立文字節點 $text
$text = $dom->createTextNode('文字');

// $text 加到 $child 節點底下
$child->appendChild($text);

$xmlStr = $dom->saveXML();
echo $xmlStr;

?>

底下是一個從資料庫撈資料動態產生 RSS 檔的例子:
<?php
ob_start();
header('Content-Type: text/xml');

$dom = new DOMDocument('1.0');
$dom->encoding = 'UTF-8';

// 建立母節點 $rss
$rss = $dom->createElement('rss');
$dom->appendChild($rss);
$rss->setAttribute('version', '2.0');

// 建立第一子節點 $channel
$channel = $dom->createElement('channel');
$rss->appendChild($channel);

// $channel 底下的節點及其文字內容
$title = $dom->createElement('title');
$titleText = $dom->createTextNode('您的 RSS 標題');
$title->appendChild($titleText);
$channel->appendChild($title);

$link = $dom->createElement('link');
$linkText = $dom->createTextNode('http://您的網站連結/');
$link->appendChild($linkText);
$channel->appendChild($link);

$description = $dom->createElement('description');
$descriptionText = $dom->createTextNode('您的描述');
$description->appendChild($descriptionText);
$channel->appendChild($description);

// 查詢資料庫,撈資料來建立 item 節點
require_once("您的資料庫連結檔,包括資料庫名稱,帳號,密碼,連結等.php");
$query = "您的 SQL 子句";
$result = mysql_query($query, 連結);

while($row = @mysql_fetch_assoc($result))
{
$item = $dom->createElement('item');
$channel->appendChild($item);

$title = $dom->createElement('title');
$titleText = $dom->createTextNode($row['文章標題']);
$title->appendChild($titleText);
$item->appendChild($title);

$pubDate = $dom->createElement('pubDate');
$pubDateText = $dom->createTextNode($row['文章日期']);
$pubDate->appendChild($pubDateText);
$item->appendChild($pubDate);

$description = $dom->createElement('description');
$descriptionText = $dom->createTextNode($row['文章描述']);
$description->appendChild($descriptionText);
$item->appendChild($description);

$link = $dom->createElement('link');
$linkText = $dom->createTextNode('您的連結');
$link->appendChild($linkText);
$item->appendChild($link);
}

$xmlStr = $dom->saveXML();
echo $xmlStr;

mysql_close($link);
?>