<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" 
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>將資料和程式分離</title>
<link>http://blog.roodo.com/jaceju/archives/2617536.html/</link>
<description><![CDATA[有位 jocosn 網友問了一個我覺得很棒的問題，我把我的觀點提出來供大家參考。
註：以下我會以引用區塊的方式來標示該網友的問題，然後以回答該問題的語氣說明。且基於本人龜毛的個性，也會把內容稍作排版。

如果我有一個 welcome.php，它的樣版檔是 welcome.tpl.htm，但是兩個檔案的編碼不相同，也就是 php 使用 &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot;&gt; ， tpl.htm 使用 &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=big5&quot;&gt;，結果螢幕顯示時會以  utf-8 編碼格式顯示 tpl.htm 檔案，必須再手動挑選 big5，請問這種情況有辦法解決嗎？還是程式這種架構有問題？
使用 big5 是因為 tpl.htm 檔案有用到 mailto，像這樣：
&lt;a href='mailto:h...@yahoo.com.tw?subject=其他問題&amp;body=問題描述：%0A%0A%0A%0A聯絡方式%0A地址：%0A電話：%0A聯絡人：%0A'&gt;寫信連絡&lt;/a&gt;
如果改用 utf8，點下 mailto 開啟 outlook 6 會出現亂碼。所以採用 big5 才會正常顯示中文字。但是 php 檔案因有些部份未使用樣板處理一些簡單的小訊息 (如顯示&quot;檔案建立成功&quot;) ，所以採用 utf8，以免顯示中文像「功」字會出現問題。
像這種情況下，請問該怎麼處理，或是有更好的解決方式嗎？

事實上你的 template 還是可以用 utf-8 的，只不過有些地方要做一些手腳。
在這之前，先給你一個觀念：把資料和程式分離。怎麼說呢？直接給你看例子好了：
首先我把 mailto 會用到的中文字另存成一個 ini 檔：
[mailto]
subject = &quot;其他問題&quot;
body = &quot;問題描述：\n\n\n\n聯絡方式\n地址：\n電話：\n聯絡人：\n&quot;
特別要注意的是，這個 ini 檔是用 big5 來存檔的。
然後我在 index.php 裡把它載入：
&lt;?php
$mailto = parse_ini_file('mailto.ini');
  
$subject = urlencode($mailto['subject']);
$body = str_replace('%250A', '%0A', urlencode(str_replace('\n', '%0A',  $mailto['body'])));
  
include('template.php');
這邊要特別注意的是 php 檔是用 utf-8 來存檔 (事實上你也可以用 ANSI 來存) 。
最後來看看 template.php ：
&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
&lt;title&gt;測試 mailto&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;
&lt;a href=&quot;mailto:jxxxxxxxxx@gmail.com?subject=&lt;?php echo $subject; ?&gt;&amp;body=&lt;?php echo $body; ?&gt;&quot;&gt;寫信連絡&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;
這裡一樣也是用 utf-8 存檔。
執行它看看，跑出來的結果是不是符合你的需要呢？
這裡就導出一個觀念了： PHP 在處理資料時，其程式檔案的編碼是不會影響資料本身的編碼的。
在上面的例子裡， parse_ini_file 取得的資料就是 mailto.ini 本身的編碼 (也就是 big5) ，而 PHP 也不會因為自己的檔案編碼是 utf-8 而改變 parse_ini_file 所取得的資料編碼。因此這時候的「其他問題」和「問題描述...」都能夠用在 template 上...
不過等一下，如果你直接把 $mailto['subject'] 和 $mailto['body'] 套入 template.php 的話，那就慘了。為什麼呢？因為 big5 編碼的內容在 utf-8 編碼的網頁裡，瀏覽器不知道該怎麼解釋它們 (也就是一堆亂碼啦) 。所以這裡我們要利用 urlencode 這個函式，來將 big5 的文字做 URL 編碼。
至於 \n 的部份只是個表示方式，實際上我們還是要手動將它換成 %0A (雖然我換的方式還滿醜的) 。
當然不只是文字檔案，就連資料庫中取出的資料也是相同的道理。這點你可以參考我先前寫的 MySQL 中文編碼徹底研究，裡面有詳細的內容。

再請問，如果用 smarty 時，php 檔案是不是應該儘量只有 php 程式碼？

依照上面的觀念，你認為我這裡會給什麼樣的答案呢？想想看吧 :)

另外 php 檔案存成 utf-8 或 big5 有差嗎？還是說網頁儘量不要存成 big5，以免特殊中文字會出現錯誤？
例如 php 檔案中像這樣 $mysmarty-&gt;assign('myVar1','許蓋功') ，存成 big5，我在測試時，就會出現錯誤 Parse error: parse error, unexpected T_STRING 

PHP 引擎會對 &lt;?php ?&gt; 裡面的特殊字元很敏感，所以上面的觀念一樣適用在這裡；當然如果是在 &lt;?php ?&gt; 外的話 (通常是 HTML ) 就沒問題了。
希望上面的說明能讓你清楚相關的觀念 :)
]]>
	</description>
<language>zh-tw</language>
<generator>Roodo Blog System</generator>
<copyright>All Rights Reserved</copyright>
<atom:link href="http://blog.roodo.com/jaceju/archives/2617536-comment.xml" rel="self" type="application/rss+xml" />
<item>
	<title>回應：將資料和程式分離</title>
	<description><![CDATA[To mimic3:

目前沒有用 ThunderBird 耶，我有空試試看好了。]]>
	</description>
	<link>http://blog.roodo.com/jaceju/archives/2617536.html</link>
	<guid>http://blog.roodo.com/jaceju/archives/2617536.html#comment-14147197</guid>
		<category>文章回應</category>
	<pubDate>Tue, 07 Aug 2007 18:35:33 +0800</pubDate>
</item>
<item>
	<title>回應：將資料和程式分離</title>
	<description><![CDATA[thunderbird 不能用 urlencode 有其他方法嗎?]]>
	</description>
	<link>http://blog.roodo.com/jaceju/archives/2617536.html</link>
	<guid>http://blog.roodo.com/jaceju/archives/2617536.html#comment-14145861</guid>
		<category>文章回應</category>
	<pubDate>Tue, 07 Aug 2007 17:56:41 +0800</pubDate>
</item>
<item>
	<title>回應：將資料和程式分離</title>
	<description><![CDATA[嗯 抱歉是我耍寶了

另外 記得以前可以在html網頁裡面插入一種代碼
例如 title="name[代碼]pass"
用瀏覽器看之後 會變成

name
pass

跟\n不盡相同的東西
突然忘了那個代碼是什麼 請問站長知道嗎?]]>
	</description>
	<link>http://blog.roodo.com/jaceju/archives/2617536.html</link>
	<guid>http://blog.roodo.com/jaceju/archives/2617536.html#comment-4559309</guid>
		<category>文章回應</category>
	<pubDate>Fri, 09 Feb 2007 04:37:33 +0800</pubDate>
</item>
<item>
	<title>回應：將資料和程式分離</title>
	<description><![CDATA[To sdcgf:

你要從上到下看完我說明的文字呀！

這裡的 \n 只是用來表示換行意義的，不是真的換行字元，所以不用雙引號。]]>
	</description>
	<link>http://blog.roodo.com/jaceju/archives/2617536.html</link>
	<guid>http://blog.roodo.com/jaceju/archives/2617536.html#comment-4559307</guid>
		<category>文章回應</category>
	<pubDate>Fri, 26 Jan 2007 08:59:59 +0800</pubDate>
</item>
<item>
	<title>回應：將資料和程式分離</title>
	<description><![CDATA[等等 我記得
$body = str_replace('%250A', '%0A', urlencode(str_replace('\n', '%0A',  $mailto['body'])));

寫成 '\n' 是沒有作用的吧?
好像應該寫成 "\n"才對]]>
	</description>
	<link>http://blog.roodo.com/jaceju/archives/2617536.html</link>
	<guid>http://blog.roodo.com/jaceju/archives/2617536.html#comment-4559305</guid>
		<category>文章回應</category>
	<pubDate>Fri, 26 Jan 2007 04:05:58 +0800</pubDate>
</item>
<item>
	<title>回應：將資料和程式分離</title>
	<description><![CDATA[感謝 jaceju 大這麼精彩的解法，還特別加以重新排版，很感動。]]>
	</description>
	<link>http://blog.roodo.com/jaceju/archives/2617536.html</link>
	<guid>http://blog.roodo.com/jaceju/archives/2617536.html#comment-4559303</guid>
		<category>文章回應</category>
	<pubDate>Wed, 03 Jan 2007 23:56:38 +0800</pubDate>
</item>
</channel>
</rss>