最近更新: 2007-01-16

在 PHP 中以「中文字」為符號名稱之事項

php_syntax

在 PHP 中能否以「中文字」作為變數、常數、函數的符號名稱呢?當然可以,但現階段有些注意事項與使用障礙。本文是個人經驗,供各位參考 (對了,我個人不將程式語言視為「英文」。而那些以 a-z0-9 等字母組成的符號,我僅將其視為視覺識別符號。嘿嘿,畢竟我英語發音很差,那些字大多數是以字形識別其意的)。

在 PHP 下用中文字作為符號名稱時,一般只要注意兩點。一、檔案編碼格式要用 utf-8 ,問題少很多;如果用 ANSI (本地字元內碼) 格式儲存,則「許、功、蓋」等很多字就不能作為符號名稱。二、不嫌打字麻煩... 對我來說這很重要。一般說來只要注意這兩點,我們就能用中文字為符號名稱。但當我們的程式需要讀取外部資料且外部資料不是 utf-8 編碼時,問題就來了。

當我們用 utf-8 編碼格式儲存源碼時,源碼中的字串也會是 utf-8 內碼 (廢話) 。程式自本地字元編碼格式的外部資料來源讀取資料時,字串對比動作會因為內碼不同而判定不相等。例如: 將 '你好' 存在純文字檔中,且文字檔之編碼格式為 ANSI (即本地字元內碼) 。再把下列 PHP 程式以 utf-8 編碼格式儲存,則其中的字串比對 strpos() 會判定資料中沒有 '你好' 這句話。

<?
$s = file_get_contents('hello.txt');

echo (strpos($s, '你好')
    ? '找到了'
    : '沒找到'
);
?>

雖說這種問題只要在讀取外部資料時都加上內碼轉換的動作即可解決。但實務上,我卻常常碰到外部資料中含有自定字 (例如Big5日文字集) 、外部字等各種情形,令 PHP 的 iconv, mb_string 等轉碼函數無法順利轉碼。我們如果有空,可以自己實踐另一個轉碼函數避過這些字。假設我們沒有時間,那麼接下去看。

這時我們不得不多繞一圈,把常值字串寫在另一個以本地字元內碼格式儲存的 php 源碼檔案中,並為此字串定義一個常數名稱 (一般實踐多語系功能時的作法)。然而這作法仍然無法滿足「以中文字為符號名稱」之需求。因為常數名稱不能用中文,否則載入後還是會因內碼不同而被 PHP 視為不同符號。如下例。

<?php
// language.php, 以 Big5編碼格式儲存

define('你好', '你好');
$你好 = '你好';
define('HELLO', '你好');
?>

#############

<?php
include_once 'language.php';

$s = file_get_contents('hello.txt');

echo (strpos($s, 你好) //常數符號, PHP Notice! 常數未定義

    ? '找到了'
    : '沒找到'
);

echo (strpos($s, $你好) //變數符號, PHP Notice! 變數未定義

    ? '找到了'
    : '沒找到'
);

echo (strpos($s, HELLO)
    ? '找到了'
    : '沒找到'
);
?>

我們還有一招最後手段可用,即在 language.php 寫上 define(iconv('big5', 'utf-8', '你好'), '你好'); 就沒問題了。但最後手段往往也是最不得已或最麻煩的手段,這手段誰想用呢?

據說 PHP6 時就會實現所有符號皆用 utf-8 編碼的功能,到那時我們才能真正平順地使用中文或本地字元集作為符號名稱。

樂多舊網址: http://blog.roodo.com/rocksaying/archives/2650736.html