【問題描述】
當前使用的版本是DedeCMS V5.5的UTF8版本。庫中已經注冊了若干用戶,從問答模塊點擊某用戶名時卻無法進入其個人空間,顯示“你訪問的用戶可能已經被刪除!”提示。依次檢查所有用戶,并非所有漢字名用戶不能用,個別可用的用戶名完全無規律可循,即便出現了錯誤的漢字用戶名如果將其連接輸入在瀏覽器的地址欄中,卻能夠正常的打開。
在網絡上尋找錯誤解決方法,發現Dede官網中提出此問題的人很多,而且從5.3開始就一直存在這個問題,有個別朋友提出的底層解決方案,修改空間模版中“../member/space/company”文件夾下的index.htm, introduce.htm, listshop.htm, contact.htm, guestbook.htm 五個文件中<a href="/main/?uid=company&action=products&mtype={dede:value.mtypeid/}" target="_blank">{dede:value.mtypename/}</a>語句的company替換為{dede:var.userid_e /}變量的方法,經過實驗并沒有解決問題。
又看到網上教程中發布的文章提到的在保留uid訪問方式同時增加mid訪問的方法,經過實驗問題依然存在。教程中提到將“member/index.php”文件中的
if(empty($uid)) { $uid = ''; } else { $tmpstr = @gb2utf8($uid); $tmpstr2 = @utf82gb($tmpstr); if($tmpstr2==$uid) $uid = $tmpstr; } |
代碼更改為
if(empty($uid)) { if (empty($_REQUEST['mid'])) { $uid = ''; }else{ $uid=$dsql->GetOne("Select userid From `dede_member` where mid='".$_REQUEST['mid']."'; "); if (!is_array($uid)){ $uid=''; }else{ $uid=$uid['userid']; } } } |
分析這兩段代碼,武林網小編提出的代碼中增加了從數據庫中重新讀出用戶ID的內容重新給uid傳遞一個值,但是把源程序中用于判斷uid值是否UTF8編碼格式的內容給丟了。這樣的修改大概可以解決同時出現了uid、mid兩個訪問參數撞車時的問題,但是依然解決不了UTF8編碼漢字用戶名的問題。
還有些網友干脆認真提出方案限制用戶使用漢字名注冊,方法相當詳備。不過如果使用UTF8編碼就放棄漢字用戶名注冊未免有點說不過去了,這里就不再詳轉具體方法了。
【問題分析】 從故障的現象看,應該是在判斷uid值是出現了錯誤,導致系統無法識別用戶,仔細分析官方代碼中對于漢字UTF8編碼的uid判斷語句,是利用了GB2UTF8和UTF82GB兩個函數進行兩次轉換然后判斷代碼。在網上找了關于UTF8和GB編碼的判斷問題,發現其實遠遠不是這么簡單的事兒。在GB編碼和UTF8編碼中,存在著部分漢字編碼是相同或某部分字節相同的情況,這樣利用兩次轉換的方法判斷編碼是很不準確的,于是出現了沒有重碼的漢字用戶名可以正確判斷并使用,而出現重碼的漢字名不能正確判斷,發生了“你訪問的用戶可能已經被刪除!”錯誤。
【解決方法】
在網絡上搜索了一些關于UTF8編碼判斷的代碼,找到了一個用PHP編寫的判斷函數。將此名為isUTF8($str)的函數添加在“member/config.php”文件的最后:
[php] function isUTF8($str){ $length=strlen($str); for($i=0;$i<$length;$i++){ $high=ord($str{$i}); if(($high==0xC0)||($high==0xC1)){ return false; }elseif($high<0x80){ continue; }elseif($high<0xC0){ return false; }elseif($high<0xE0){ if(++$i>=$length) return true; elseif(($str{$i}&"/xC0")=="/x80") continue; }elseif($high<0xF0){ if(++$i>=$length){ return true; }elseif(($str{$i}&"/xC0")=="/x80"){ if(++$i>=$length) return true; elseif(($str{$i}&"/xC0")=="/x80") continue; } }elseif($high<0xF5){ if(++$i>=$length){ return true; }elseif(($str{$i}&"/xC0")=="/x80"){ if(++$i>=$length){ return true; }elseif(($str{$i}&"/xC0")=="/x80"){ if(++$i>=$length) return true; elseif(($str{$i}&"/xC0")=="/x80") continue; } } } return false; } return true; } [/php] |
并修改“member/index.php”中的代碼:將 $tmpstr = @gb2utf8($uid); $tmpstr2 = @utf82gb($tmpstr); if($tmpstr2==$uid) $uid = $tmpstr; 修改為 if(!isUTF8($uid)) $uid = @gb2utf8($uid); 故障排除。
這里僅對官方代碼中判斷用戶UTF8編碼的方法進行了修改,并沒有對武林網小編提出的mid參數問題進行修改,若出現了武林網小編提出的故障現象相信他們提到的方法是不錯的解決方案。此文已扼要列出了武林網小編的方法備考。
新聞熱點
疑難解答