iT邦幫忙

0

[已解決]PHP 難字寫入SQL Server亂碼問題

SQL Server 版本 : 2005
SQL 難字寫入欄位型態 nvarchar
SQL 難字寫入欄位定序 Chinese_Taiwan_Stroke_CI_AS (BIG5)
PHP 版本 5.2.6

SQL 範例資料庫如下

CREATE TABLE [dbo].[zzzzpost] (
[aaa] nvarchar(10) NULL ,
[bbb] nvarchar(10) NULL ,
[ccc] nvarchar(10) NULL ,
[ddd] nvarchar(10) NULL ,
[eee] nvarchar(10) NULL ,
[dt] nvarchar(50) NULL ,
[id] bigint NOT NULL IDENTITY(1,1) ,
[fff] nvarchar(50) NULL 
)

ALTER TABLE [dbo].[zzzzpost] ADD PRIMARY KEY ([id])

PHP POST端測試範例程式碼如下

<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<form role="form" action="post.php" method="post">
	
<input type="text" name="aaa" value="<?PHP echo rand(100,200); ?>"><br/>
<input type="text" name="bbb" value="<?PHP echo rand(100,200); ?>"><br/>
<input type="text" name="ccc" value="<?PHP echo rand(100,200); ?>"><br/>
<input type="text" name="ddd" value="<?PHP echo rand(100,200); ?>"><br/>
<input type="text" name="eee" value="<?PHP echo rand(100,200); ?>"><br/>
<input type="text" name="fff" value="堃彣瀞">
<input type="submit">		
</form>

PHP接收端測試範例程式碼如下

<?PHP
header("Content-Type: text/html; charset=utf-8");
include($_SERVER['DOCUMENT_ROOT'].'/admin/conn/conn.php');
include($_SERVER['DOCUMENT_ROOT'].'/admin/function/function.php');

ini_set('display_errors','1');
error_reporting(E_ALL);

?>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<?PHP

	$nowtime = time();
	$wordtime = date('Y-m-d H:i:s',$nowtime);   

if(isset($_POST['aaa']) && $_POST['aaa'] != ''){echo 'aaa : '.$_POST['aaa']."<br/>";$aaa=$_POST['aaa'];}else{$aaa='';}

if(isset($_POST['bbb']) && $_POST['bbb'] != ''){echo 'bbb : '.$_POST['bbb']."<br/>";$bbb=$_POST['bbb'];}else{$bbb='';}

if(isset($_POST['ccc']) && $_POST['ccc'] != ''){echo 'ccc : '.$_POST['ccc']."<br/>";$ccc=$_POST['ccc'];}else{$ccc='';}

if(isset($_POST['ddd']) && $_POST['ddd'] != ''){echo 'ddd : '.$_POST['ddd']."<br/>";$ddd=$_POST['ddd'];}else{$ddd='';}

if(isset($_POST['eee']) && $_POST['eee'] != ''){echo 'eee : '.$_POST['eee']."<br/>";$eee=$_POST['eee'];}else{$eee='';}

if(isset($_POST['fff']) && $_POST['fff'] != ''){echo 'fff : '.$_POST['fff']."<br/>";$fff=$_POST['fff'];}else{$fff='';}

echo "<hr/>";

$sql = "insert into zzzzpost (
			         aaa,bbb,ccc,ddd,eee,fff,dt
					 )values(
					 '".$aaa."','".$bbb."','".$ccc."','".$ddd."','".$eee."',N'".$fff."','".$wordtime."')";
      	$result=mssql_query($sql);

if($result){
echo 'Data Insert OK';
}else{
echo $sql.' Data Insert Error';
}	
		
?>

透過網頁(都是UTF-8編碼)POST寫入後都會報如下圖的錯誤訊息
https://ithelp.ithome.com.tw/upload/images/20180208/20090631WVEP1wPGvl.jpg

但是直接將SQL語法貼在SSMS執行卻可順利執行且寫入的是實體的難字...
insert into zzzzpost ( aaa,bbb,ccc,ddd,eee,fff,dt )values( '123','139','142','152','186',N'堃彣瀞','2018-02-08 23:15:21')
https://ithelp.ithome.com.tw/upload/images/20180208/20090631nYiYM9DXGv.jpg

若我先將難字變數寫入SQL前 iconv("UTF-8","big5",'堃彣瀞') 轉碼
會由於BIG5沒這些字導致變空白....

一、不考慮修改欄位定序 (會引發一連串系統相關聯的查詢上定序相容要修改)
二、難字若改為unicode編碼寫入,擔心會否影響該欄位值的搜尋匹配
第二點測試結果存入是unicode編碼,顯示在網頁沒問題,但若搜尋匹配就有問題了...
https://ithelp.ithome.com.tw/upload/images/20180208/20090631e942rVUBf2.jpg

虛心請教處理過類似問題的大德,懇請分享您的寶貴經驗....感恩

看更多先前的討論...收起先前的討論...
froce iT邦研究生 5 級 ‧ 2018-02-08 19:02:50 檢舉
1.不用unicode你就得把難字替代掉。
2.建議去試試看。

這年頭就不要再堅持用 BIG5。
badbayz iT邦新手 4 級 ‧ 2018-02-08 23:17:21 檢舉
我定序沒改的情況下從網頁POST寫過去會出錯,但我將echo出來的SQL語法貼在SSMS上執行卻是可以寫入真實難字@@ 真怪
insert into zzzzpost ( aaa,bbb,ccc,ddd,eee,fff,dt )values( '123','139','142','152','186',N'堃彣瀞','2018-02-08 23:15:21')
froce iT邦研究生 5 級 ‧ 2018-02-09 09:58:14 檢舉
因為你不知道SSMS在傳送指令的時候會不會自動幫你轉或做什麼處理啊。
你在SSMS看得到那些難字,表示SSMS是使用unicode來做輸入。
我也有遇過在程式寫SQL沒問題,在SSMS出錯的時候。
ccutmis iT邦研究生 5 級 ‧ 2018-02-09 12:27:08 檢舉
php 文件編碼可能是 ANSI 格式,用notepad++之類的軟體確認文件編碼是UTF-8後應該就可以了
badbayz iT邦新手 4 級 ‧ 2018-02-09 13:30:30 檢舉
php 文件都再次用notepad++確認是UTF-8編碼了,還是一樣,目前感覺是php在寫入SQL的部分要改,持續測試中...
ccutmis iT邦研究生 5 級 ‧ 2018-02-12 17:17:30 檢舉
我建議您可以從反方向來解決問題,例如 SQL Server 版本 : 2005就我的印象這十幾年前的產品,可能對unicode支援度不是很好,可試試把[POST端][跟接收端]的php用ansi格式big5編碼(就是 charset=utf-8改成 charset=big5,並確認文件編碼,最好先備份再試),也許就成功了。寫入部份用big5,如果是要讀取用的網頁再視情況用iconv把big5轉unicode
badbayz iT邦新手 4 級 ‧ 2018-02-13 11:23:33 檢舉
THX 文件編碼部分我都試過幾種編碼下去跑過,問題仍在,目前先擱著了,有空繼續研究下,若找到完美解決方案在分享給大家^_^
badbayz iT邦新手 4 級 ‧ 2018-02-19 21:24:20 檢舉
最後還是屈服了,送出表單後由PHP接手判斷自串內有無難字,若有難字則將難字轉為Unicode編碼後再存入SQL Server;而搜尋部分同理,搜尋的inpit送出後PHP判斷是否包含難字,若有難字同樣轉為Unicode編碼後再進行與資料庫內容匹配,這樣也是一樣的效果,使用者體驗上感覺不出差異就是了,實在恨透了BIG5...哈哈,但工作上總是有必須硬著幹的 ~""~

1 個回答

0
leotse
iT邦新手 5 級 ‧ 2018-02-09 21:16:19

我在 mariadb 試過類似情況,看看以下網頁能否有幫助:http://php.net/manual/en/mysqli.set-charset.php

badbayz iT邦新手 4 級 ‧ 2018-02-19 21:26:42 檢舉

謝謝你的熱心,基本上MySQL、Mariadb,等SQL發生這類編碼問題較單純,就微軟的可能2005對Unicode支援度較差吧/images/emoticon/emoticon02.gif

我要發表回答

立即登入回答