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

2014年1月28日 星期二

[PHP]使用Mail函式透過SMTP發信

大部分的網站應該都需要系統可以進行發信的動作,因為這樣可以發送網站的確認信件或者是密碼遺失的重設信件,不過如果是使用虛擬主機,那主機商基本上都會設定好,使用者不須額外設定。但是若是使用免費空間,那大多數的免費空間會禁止使用,因為怕有使用者濫發廣告信件。
如果是自己架設的網站,想要啟用SMTP該怎麼辦呢?通常我們不需要架設SMTP伺服器,我們可以利用現有的資源,修改一下系統參數就可以了。所謂的限有資源,以架設在家裡來說,就是使用ISP的SMTP,如果是架設在學校,就使用學校的SMTP伺服器就可以,不用額外操心這部分囉!
通常想要使用現有的SMTP伺服器,那使用者一定要改一下php.ini的系統設定,否則是無法使用的,因為預設值都是「localhost」,但是我們本機並沒有架設Mail伺服器,所以這部分是無效用的。那如前面提到,要使用現有的SMTP設定,通常就找你的ISP,如果是在學校,就找學校的SMTP設定就可以了。
以Hinet的光纖網路來說,它的SMTP就是「msa.hinet.net」,如果是寬頻網路可能要再查一下了,當然你也可以用上面這組試試看!如果知道寬頻設定的朋友,可以留言告知我們一下,謝謝。如果你是其它家網路,像SeedNet、So-Net之類的,那就請洽他們的客服人員詢問看看囉!不過,如果你電腦內有設定Outlook這類軟體,其實可以開啟Outlook看一下,因未設定上是一樣的。

修改主機的SMTP

如果想要透過ISP或是學校的SMTP來發現,首先一定要先找到學校或是ISP的SMTP設定了,在此就提供兩個我在使用的SMTP設定,當然並不是人人都可以用的,如果你剛好跟我狀況相同就可以使用了XD。
  • Hinet:msa.hinet.net (目前在光世代測試可以)
  • 世新大學:smtp.shu.edu.tw (限在世新大學校園內的電腦)
如果要設定的話,請開啟伺服器的php.ini後,搜尋一下關鍵字「SMTP」,之後就會看到一區是「mail function」,那邊就是系統設定了,將SMTP後方的「localhost」改成「你要使用的SMTP」設定,在「smtp_port」改成對應的埠號,一般來說預設都是25,所以可以不用額外更動。
另外,下方有個寄件者「sendmail_from」,你可以設定一下發信人的名義是誰,將後面的信箱改一下就可以了,但最重要的,記得把整串語法前面的分號「;」去掉,因為這邊的分號表示「註解」,若無去掉,那設定也是沒用的。
[PHP]使用Mail函式透過SMTP發信
當設定好SMTP伺服器後,接下來就是重啟阿帕契(Apache),重啟後就可以了,你可以丟一支探針看看是不是系統可以進行發信了,當然還有個正簡單的方法,就是直接透過程式來測試,如果你的信箱可以收到信,這表示你的SMTP設定對了,如果不能收到信,那很可能是主機哪邊沒設定好,或者是說SMTP不能使用,也有可能是被防火牆、防毒軟體擋下來也說不定。
<?php 
$to =" yourmail@your.com “; //收件者 
$subject = “test“; //信件標題 
$msg = “smtp發信測試“;//信件內容 
$headers = “From: admin@your.com“; //寄件者
if(mail(“$to", “$subject", “$msg", “$headers"))
echo “信件已經發送成功。“;//寄信成功就會顯示的提示訊息
else
echo “信件發送失敗!“;//寄信失敗顯示的錯誤訊息 
?>
將以上程式碼複製並貼到NotePad++,然後取名為「send.php」,然後丟到你要測試的伺服器上面,然後用瀏覽器開啟「http://你的網站網址/send.php」並執行,透過以上這支簡單的程式就可以測試看看您的設定到底有沒有設定正確,如果設定正確網頁就會顯示「信件已經發送成功。」如果無法寄信,就會顯示「信件發送失敗!」。

如果設定上都可以,就可以開始進行程式的開發了,像是可以弄個會員確認信、電子報等等,你都可以透過mail函式來達成,你可參考PHP5網管實驗室的中文說明,也可以參考一下PHP官方網站的英文說明,好好的利用這個函式來發送信件吧!

2011年9月24日 星期六

About PHP Formatter

http://www.phpformatter.com/


程式碼工作室
ERP/EIP/CMS/CHART/REPORT/SPC/EDA/雲端 系統開發整合
ASP/PHP/JSP/ASP.NET 網頁設計
技術指導顧問
信箱:paulwu0114@gmail.com
http://www.coding.com.tw

2011年9月19日 星期一

How to detect a visitor's IP address

Every visitor to your site or web application has an IP address. It is quite handy to be able to get that address. It can be used for security logging, or perhaps tracing. It can also be used to determine where they are in the world, or at least where their ISP is.
The difficulty is when they're behind a proxy of some sort, you only see the IP address of the proxy server. So, here are the code snippets in PHP,JSP, ASP and .Net that first check for an IP addresses that's forwarded from behind a proxy, and if there's none then just get the IP address.
  • PHP without Proxy detection
    <? $ipaddress = getenv(REMOTE_ADDR); ?>
  • PHP with Proxy detection
    <?if (getenv(HTTP_X_FORWARDED_FOR)) {
    $ipaddress = getenv(HTTP_X_FORWARDED_FOR);
    } else {
    $ipaddress = getenv(REMOTE_ADDR); }
    ?>
  • ASP without Proxy detection
    <%
    ipaddress = Request.ServerVariables("REMOTE_ADDR")
    %>
  • ASP with Proxy detection
    <%
    ipaddress = Request.ServerVariables("HTTP_X_FORWARDED_FOR")
    if ipaddress = "" then
    ipaddress = Request.ServerVariables("REMOTE_ADDR")
    end if
    %>
  • JSP without Proxy detection
    <%
    String ipaddress = request.getRemoteAddr();
    %>
  • JSP with Proxy detection
    <%
    if (request.getHeader("HTTP_X_FORWARDED_FOR") == null) {
    String ipaddress = request.getRemoteAddr();
    } else {
    String ipaddress = request.getHeader("HTTP_X_FORWARDED_FOR");
    }
    %>
我想了解如何获得IP地址的客户端,即访问我的网页。
内容的JSP页面:
<%  
out.print( request.getRemoteAddr() + "<br>"); 
out.print( request.getRemoteHost() );  
%> 
输出:
0:0:0:0:0:0:0:1 
0:0:0:0:0:0:0:1 

2011年9月5日 星期一

UTF-8網頁傳中文字到官方big5網頁

在我的UTF-8網頁裡,用PHP iconv()將UTF-8的字轉成Big5字串,
同時把big5的字用urlencode編碼(這樣才能成功的在UTF-8的網頁內生存並正確傳送),
將編碼好的字加在Form的Action的URL的後面,使它以GET的方式傳送
(這樣才不會再一次被URL Encode),到對方的Big5網頁後,會自動被URL Decode
成big5字元,如此成功的將我的UTF-8網頁內的big5字,傳送到官方的Big5網站,
並正確的顯示出來。
代碼: [選擇]

<?php $big5_ItemName = urlencode&#40;iconv&#40;'utf-8','big5','萬國碼8的中文字'&#41;&#41;; ?>
<form name='ReadyForm' action='http://officialWebSite/Big5Page.php?ItemName=<?php echo $big5_ItemName ?>' method='post'>
<input type='hidden' name='ID' value='<?php echo $ID ?>'>
</form>

2011年8月15日 星期一

(You don't have permission to access - on this server. )解决方法

几天尝试手动安装LAMP,用的操作系统是有名的CentOS,虽然照着网上的教程一步步地操作,可是依旧还是会出现一些意外的东西。
就在今天出现的这个“You don't have permission to access / on this server.”的警告,就令我有点不知所措。我想运行我自己写的php文件,可是一直都没结果,浏览器中只是出现这么一句话。于是用google搜索一下,这到底是怎么回事。结果给的答案是各不相同,其中一个是将apache不能读取权限为root的文件,因为他的权限比root弱。看了下,哦,我这个文件是我前几天用root用户写的,于是把用户和组全改了。结果运行还是不行。之后又说什么权限要为755,之后一查我的已经就是755,看来还是没戏。最后终于让我给找到了,修改httpd.conf的配置,查找下面的红色部分,把它给去掉。
< Directory / >
     Options FollowSymLinks
     AllowOverride None
     Order deny,allow
     Deny from all

< /Directory >
参考文章:经验笔记(记载使用中碰到的问题及解决方法)
<Location /svn>
   DAV svn
   SVNParentPath D:\SVN
   AuthType Basic
   AuthName "Subversion repositories"
   AuthUserFile D:\SVN\passwd
   AuthzSVNAccessFile D:\svnaccessfile
   Require valid-user
</Location>
我的svnaccessfile是
[groups]
admin = yj
project1 = yujun,yemao
project2 = maoju,like

# 为所有库指定默认访问规则
# 所有人可以读,管理员可以写,危险分子没有任何权限
[/]
* = r
@admin = rw
dangerman =

# 允许开发人员可以完全访问他们的项目版本库
[project1:/]
@project1 = rw
[project2:/]
@project2 = rw

2011年7月19日 星期二

MySQL 升級成 5.0 與 UTF-8 之相關解決方法 ......]

[MySQL 升級成 5.0 與 UTF-8 之相關解決方法 ......]

http://www.j2h.tw/bbs/bbs16/150.html


----------------------------------------------


從MySQL4.0升級至5.0。



首先把資料dump出來 。由於先前用4.0時我的資料是存成latin1,不管是Big5或是wordpress的UTF-8存進去後都是變成lantin1,所以dump出來後要用iconf或piconf把他轉成UTF-8,記得dump出來時要加上–default-character-set=latin1



如果原先是Big5的資料,像我的Coppermine Photo Gallery,dump出來後就直接把Big5轉成UTF-8即可



#mysqldump -u帳號 -p –default-character-set=latin1 資料庫 >output.sql



#piconv -f big5 -t utf8 output.sql >utf8.sql



如果原先是UTF-8的資料,像是wordpress,dump出來後要先轉成Big5後,再把他轉成UTF-8,因為原先dump出來的是偽裝成UTF-8的lantin1不是真正的UTF-8



#mysqldump -u帳號 -p –default-character-set=latin1 資料庫 >output.sql



#piconv -f utf8 -t big5 output.sql > big5.sql

#piconv -f big5 -t utf8 big5.sql >utf8.sql



接著MySQL5.0灌好後,MySQL的my.cnf設定檔內要加入以下設定



[client]

default-character-set=utf8

[mysqld]

default-character-set=utf8

default-collation=utf8_general_ci



但也有看到資料說[mysqld]那邊加上 default-character-set=utf8跟 default-collation=utf8_general_ci後,一些舊的使用Big5編碼的php程式,又沒有加入連資料庫時指定的編碼方式的相關code的話,那些程式就會爛掉,所以目前我是沒有加上那兩行。



接著建立空的資料庫準備把dump出來的資料import進去,SQL語法應該類似下面這樣,要加上DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci



CREATE DATABASE `abc` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;



我是用phpMyAdmin建立資料庫的,建立時”校對”要選utf8_general_ci



再來就是把剛剛dump出來後的sql檔在import進去了,這裡有兩點要注意的。

1.剛剛dump出來的sql檔如果原先是Big5里面會有一些像是許功蓋這些字後面會多了一個”\“,記得用文字編輯器把他消掉2.import進去時記得還要先修改一下dump出來的sql檔,在最前面加上



SET NAMES utf8;

SET CHARACTER_SET_CLIENT=utf8;

SET CHARACTER_SET_RESULTS=utf8;



再來把每個資料表後面的



TYPE=MyISAM;



改成



ENGINE=MyISAM DEFAULT CHARSET=utf8;



都改好後就可以把他import進去了



#mysql -u帳號 -p 資料庫 < utf8.sql



不過以上實在有點麻煩,所以我把多餘的”/“消掉後,就直接用phpMyAdmin把他import進去了,import時記得文字編碼檔案要選utf8即可



順便記一下寫php時如是配合UTF-8的資料庫的話該注意,在真正送出query前要先加入以下三行



mysql_query(”SET NAMES ‘utf8‘”);

mysql_query(”SET CHARACTER_SET_CLIENT=utf8“);

mysql_query(”SET CHARACTER_SET_RESULTS=utf8“);



檢查語系的SQL語法



show variables like “%character%”;

----------------------------------------------

MySQL 升級成 5.0 與 UTF-8 之相關解決方法 ......]

[MySQL 升級成 5.0 與 UTF-8 之相關解決方法 ......]

http://www.j2h.tw/bbs/bbs16/150.html


----------------------------------------------


從MySQL4.0升級至5.0。



首先把資料dump出來 。由於先前用4.0時我的資料是存成latin1,不管是Big5或是wordpress的UTF-8存進去後都是變成lantin1,所以dump出來後要用iconf或piconf把他轉成UTF-8,記得dump出來時要加上–default-character-set=latin1



如果原先是Big5的資料,像我的Coppermine Photo Gallery,dump出來後就直接把Big5轉成UTF-8即可



#mysqldump -u帳號 -p –default-character-set=latin1 資料庫 >output.sql



#piconv -f big5 -t utf8 output.sql >utf8.sql



如果原先是UTF-8的資料,像是wordpress,dump出來後要先轉成Big5後,再把他轉成UTF-8,因為原先dump出來的是偽裝成UTF-8的lantin1不是真正的UTF-8



#mysqldump -u帳號 -p –default-character-set=latin1 資料庫 >output.sql



#piconv -f utf8 -t big5 output.sql > big5.sql

#piconv -f big5 -t utf8 big5.sql >utf8.sql



接著MySQL5.0灌好後,MySQL的my.cnf設定檔內要加入以下設定



[client]

default-character-set=utf8

[mysqld]

default-character-set=utf8

default-collation=utf8_general_ci



但也有看到資料說[mysqld]那邊加上 default-character-set=utf8跟 default-collation=utf8_general_ci後,一些舊的使用Big5編碼的php程式,又沒有加入連資料庫時指定的編碼方式的相關code的話,那些程式就會爛掉,所以目前我是沒有加上那兩行。



接著建立空的資料庫準備把dump出來的資料import進去,SQL語法應該類似下面這樣,要加上DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci



CREATE DATABASE `abc` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;



我是用phpMyAdmin建立資料庫的,建立時”校對”要選utf8_general_ci



再來就是把剛剛dump出來後的sql檔在import進去了,這裡有兩點要注意的。

1.剛剛dump出來的sql檔如果原先是Big5里面會有一些像是許功蓋這些字後面會多了一個”\“,記得用文字編輯器把他消掉2.import進去時記得還要先修改一下dump出來的sql檔,在最前面加上



SET NAMES utf8;

SET CHARACTER_SET_CLIENT=utf8;

SET CHARACTER_SET_RESULTS=utf8;



再來把每個資料表後面的



TYPE=MyISAM;



改成



ENGINE=MyISAM DEFAULT CHARSET=utf8;



都改好後就可以把他import進去了



#mysql -u帳號 -p 資料庫 < utf8.sql



不過以上實在有點麻煩,所以我把多餘的”/“消掉後,就直接用phpMyAdmin把他import進去了,import時記得文字編碼檔案要選utf8即可



順便記一下寫php時如是配合UTF-8的資料庫的話該注意,在真正送出query前要先加入以下三行



mysql_query(”SET NAMES ‘utf8‘”);

mysql_query(”SET CHARACTER_SET_CLIENT=utf8“);

mysql_query(”SET CHARACTER_SET_RESULTS=utf8“);



檢查語系的SQL語法



show variables like “%character%”;

----------------------------------------------

2011年7月12日 星期二

分享MySQL和php採用UTF8的詳細方法

******   網 站 全 面 採 用 UTF-8 方法.   ******  

1. 用 vi /etc/httpd/conf/httpd.conf 設定Apache中的語系為:( (記得restart)
         AddDefaultCharset UTF-8

2. 用 vi /etc/php.ini 設定php中的語系為:( (記得restart)
         default_charset = "utf-8"

3. 用 vi /etc/my.cnf 設定MySQL中的語系為:( (記得restart)
      [mysqld]
         init_connect='SET NAMES utf8'
         default-character-set=utf8
      [client]
         default-character-set = utf8

4. 建立資料庫時選擇語系: (記得清除DB Cache)
      DROP DATABASE IF EXISTS `aa`;
      CREATE DATABASE `aa` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
      USE `aa`;
     
      CREATE TABLE  IF NOT EXISTS `aat` (
        `id` char(1) NOT NULL default '1',
        `myStr` varchar(200) default NULL,
        PRIMARY KEY  (`id`)
      ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

5. 用UltraEdit(v11.20a版) 轉換所有ANSI格式的php檔案轉化為UTF-8格式:
      File --> Conversions --> ASCII to UTF-8 (Unicoding Editing)
   ( 在UltraEdit中按Advanced --> configuration --> File Handling
     --> Unicode/UTF-8 Detection --> 剔選Auto detect utf-8 files )
    如有需要時,可執行Remove BOM.php. 當用WinXP的Notepad將php檔由ANSI轉為UTF-8時,
  因檔頭有BOM,會引起排版問題,故必須移除,執行Remove BOM.php即可自動移除.
  Remove BOM.php可由以下網址下載:
  http://www.hoyo.idv.tw/hoyoweb/document/view.php?sid=13&author=hoyo&status=view

6. 在php檔中必須加入:
      <html><head>
         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      </head><body>     

7. 在連接DB的檔中必須加入3行mysql_query才ok:
         $host="localhost";         $DBname="aa";
         $user= "root";         $passwd  = "";    
         $link = mysql_connect($host,$user,$passwd) or die ("Fail");
         $db = mysql_select_db($DBname, $link) or die ("Fail");              
     // 要在真正query DB取出資料前,加入以下3行
         mysql_query("SET NAMES 'utf8'");
         mysql_query("SET CHARACTER_SET_CLIENT=utf8");
         mysql_query("SET CHARACTER_SET_RESULTS=utf8");
         $sql  = "select * from aat where crid='1'";
         $rows = mysql_query($sql);

8. 在php檔中, 如有需要須注意: [Optional]
      運用htmlentities和htmlspecialchars時,要似如下:
         $chars = htmlentities($chars,ENT_QUOTES,"UTF-8");
         $chars = htmlspecialchars($chars,ENT_QUOTES,"UTF-8");
      並且在顯示前要用
         $chars = html_entity_decode($chars,ENT_QUOTES,"UTF8");
      如有用過addslashes()或mysql_real_escape_string()記得用以下:
         $chars = stripslashes($chars);
      如有需要可以用以下function將不同編碼轉換:
         $chars = iconv('Big5','UTF-8',$chars);  //由Big5轉為UTF-8

2011年7月10日 星期日

去掉 BIG-5 轉 UTF-8 衝碼字的反斜線

討論】:關於去掉 BIG-5 轉 UTF-8 衝碼字的反斜線 : http://phpbb-tw.net/phpbb/viewtopic.php?t=41901

進藤ヒカル さん


虛擬画像

作成: 04/28/07 04:57pm
關閉目前運作中的 BIG-5 舊網站

在備份整個網站的資料庫之前,當然要先關閉網站,以免又有不知情的網友,貼心的想要發表新的文章或是回覆文章。請用管理者身分登入,然後點選 “系統管理員選單”:

《按一下可顯示圖片》

這個就是 XOOPS 後台管理畫面的一部份,最底下可以看到目前的版本還是 XOOPS 2.0.13.2。由於 XOOPS 改版速度太慢,幾近於 “超龜速”,所以這已經是很久以前的版本,目前最新的 2.0 系列版本是 2.0.16。不過這個版本的 “Upgrade” 升級模組有 bug,會導致 LDAP 功能異常!如果是全新安裝架設的網站,大概比較沒有問題。

《按一下可顯示圖片》

在 “系統管理” 模組點選 “系統設定” 或是 “偏好設定”:

《按一下可顯示圖片》

把 “暫時關閉網站” 改成 “是”,這樣子就只有管理者可以看到整個網站,建議你登出帳號確認一下網站是不是真的關掉了?

《按一下可顯示圖片》

如果沒有 “登出” 就直接回到網站 “首頁” 的話...

《按一下可顯示圖片》

其實看不出網站到底關掉了沒?請按一下 “登出”:

《按一下可顯示圖片》

這樣子才會看到網站關閉的畫面,提醒你可以先到 “BNW 會議室” 逛逛,晚點再回來瞧瞧,但是要記得回來喔~不要到處亂逛到其他網站去了... :oops:

《按一下可顯示圖片》

進藤ヒカル さん


虛擬画像

作成: 04/28/07 04:58pm
從租用主機備份資料庫

要從租用的網路主機轉移網站,當然要先把整個 MySQL 資料庫全部備份出來。打開網路主機廠商提供的 phpMyAdmin 網頁,先在左邊的面板點選要備份的資料,例如:wusin_test,再按一下網頁上方的 “輸出” 鈕,然後按 “全選” 匯出全部的資料表。

《按一下可顯示圖片》

這種備份方式跟你直接在 phpMyAdmin 首頁點選 “輸出” 不同,沒有打開指定的資料庫,直接在首頁點選 “輸出” 再點選資料庫,會把整個資料庫全部匯出,因此在另外一台 MySQL 主機匯入資料庫的時候,就必須是使用相同的資料庫名稱。因為我想要更換資料庫名稱,不再使用 wusin_test,因此我用全選資料表的方式來匯出整個網站資料。

要提醒你的是... 在 SQL 選項的結構請點選 Add DROP TABLE、Add IF NOT EXISTS 這兩個選項,第一個會在 .sql 檔案裡加上刪除舊的資料表指令,第二個指令是如果資料表不存在的話,就自動新增資料表。這樣子可以減少匯入資料時候的錯誤。

請點選 “使用完整新增指令”:

《按一下可顯示圖片》

接著點選 “下載儲存”,壓縮方式請選用 “zipped”,壓縮成 .zip 檔案。雖然 Linux 主機都支援 .gz 檔,不過使用這種格式,可能會無法完全解壓縮,解到一半就出問題!

《按一下可顯示圖片》

phpMyAdmin 會把資料庫備份、壓縮好,然後自動下載為 wusin_test.sql.zip 壓縮檔。

《按一下可顯示圖片》

解壓縮之後就會看到備份的 wusin_test.sql 資料庫檔案。

《按一下可顯示圖片》

進藤ヒカル さん


虛擬画像

作成: 04/28/07 04:59pm
在 Mac 檢視備份的資料庫內容

所有的 .sql 檔案都是 “純文字” 檔案,基本上可用任何一個文字編輯工具開啟,不過呢... 如果是 BIG-5 HKSCS 編碼的檔案,這個檔案無論在 Mac OS X 還是 Windows 上都會遇到問題!

我用 “文字編輯” 以 Unicode(UTF-8)的方式來開啟 wusin_test.sql 資料庫檔,結果... 當然是無法開啟囉!

《按一下可顯示圖片》

點選 “自定編碼列表...”:

《按一下可顯示圖片》

再點選新增 “繁體中文 (Windows, DOS)” 編碼方式...

《按一下可顯示圖片》

就可以新增更多的文件語系,既然 UTF-8 與 “繁體中文 (Mac OS)” 都無法開啟,試試看 “繁體中文 (Windows, DOS)” 吧~

《按一下可顯示圖片》

居然說無法使用文字編碼的 “繁體中文 (Windows, DOS)” 來打開檔案! :-o

《按一下可顯示圖片》

再點選全部的 “繁體中文” 編碼方式... 每種格式都測試看看,竟然沒有一種格式可以開啟這個 .sql 檔!事實上就算你改用著名的 BBEdit 也無法正確的開啟這個繁體中文編碼的 .sql 檔! :Orz

《按一下可顯示圖片》

好吧,點選 “前往 / 連接伺服器” 把這個 .sql 資料庫檔案透過網路拷貝給 Windows 來試試看吧...

《按一下可顯示圖片》

連接到 Windows 共享的 “網路檔案夾”:

《按一下可顯示圖片》

把這個 .sql 檔案複製給 Windows。資料夾裡面的其他檔案是我先前所做的測試,等到網站租約到期以前,決定關閉的時候再做一次最後的備份。

《按一下可顯示圖片》

進藤ヒカル さん


虛擬画像

作成: 04/28/07 05:00pm
在 Windows 檢視備份的資料庫內容

這就是同樣的檔案在 Windows 看到的畫面,整個 .sql 資料庫大約有 11MB 左右:

《按一下可顯示圖片》

直接用 “記事本” 打開 wusin_test.sql 就會看到這樣的畫面... 嗯~有點奇怪對吧?

《按一下可顯示圖片》

別以為資料庫的內容原本就應該長成這樣喔!事實上是因為 Linux 對於換行的方式與 Windwos 不同,所以原本應該換行的地方都沒有換行,整個 .sql 文件變成超大的一行段落!

在 BIG-5 編碼格式底下,最大的問題就是 “許功蓋” 這號蓋世人物的衝碼問題,為了避開文字內碼與 SQL 衝突,所以在後面補上了一個多餘的 \ 符號。

《按一下可顯示圖片》

並不是每個 “許功蓋” 後面都會補上 \ 符號,你可以看到如果是在一行最後的位置,因為 \r\n 段落換行 (也就是 Enter 鍵) 的關係,會因此補上 \\rn 這樣的符號。

《按一下可顯示圖片》

進藤ヒカル さん


虛擬画像

作成: 04/28/07 05:08pm
透過ConverZ把BIG-5轉UTF-8

雖然 Mac OS X 也有幾個還滿好用的轉換檔案內容編碼格式的工具,不過都沒有 ConvertZ 好用,只是你得用 Windows 2000/XP/Vista 來跑 ConvertZ 這個 Windows 版本的工具程式。

ConvertZ 除了可以轉換文字編碼方式,還可以同時幫我們搜尋、取代特定的文字,一次完成兩件事,又完全免費,還不需要安裝就能直接使用,真是相當不錯的 “站長必備工具”! :-)

你可以在原作者網站下載 ConvertZ:http://alf-li.pcdiscuss.com/c_convertz.html
ConvertZ 屬於環保的綠色軟體,無須安裝,只要將所有檔案解壓到新資料夾,然後直接執行 convertz.exe 即可。

要解決 “許功蓋” 等中文字與 SQL 指令衝突的問題,你可以用 “記事本” 建立一個搜尋與取代的對照檔,例如 “將BIG-5轉UTF-8修正” 或是 “修正許功蓋”,檔名隨便你取,但是副檔名必須是 .dat,因此得用右鍵指定用 “記事本” 來開啟 .dat 文字檔。

《按一下可顯示圖片》

搜尋與取代的對照表就像這樣,把 “功\\” 取代為 “功”,刪除後面重複的 “\\” 雙反斜線符號。

《按一下可顯示圖片》

除了有重複的 “\\” 雙反斜線符號,也有 “\” 單反斜線的情況,只有緊跟著這些字後面的 \ 符號才需要刪除,並不是把全部的 \\ 或 \ 全數刪除喔!

《按一下可顯示圖片》

打開 ConverZ,在來源檔案把 wusin_test.sql 加入到轉換清單,再按一下 “進階選項”,點選輸入格式為 “Big5”、輸出格式為 “UTF-8”,請注意一定要記得點選 “語文輸出模式:繁體中文”,這樣才會轉換 “許功蓋” 的替換文字。

《按一下可顯示圖片》

確定是 “Big5 > UTF-8 繁體”,點選畫面底下的 “轉換檔案內容” 再按 “開始轉換”:

《按一下可顯示圖片》

轉換好了,總共花了 19 秒左右。在一台 Pentium III-1.0GHz 雙 CPU 的老舊電腦上能跑出這樣的成績算是滿快的了。

《按一下可顯示圖片》

轉換好的 UTF-8 格式檔案會自動放在 “我的文件” 裡面,請先在檔名後面加上 utf8 字樣以便區隔:

《按一下可顯示圖片》

直接用 “記事本” 打開這份文件,然後找一下 “許功蓋” 等字,看看後面的 \\ 或 \ 符號處理好了沒?嗯~果然處理好了! :-)

《按一下可顯示圖片》

不過呢... 我發現如果 “許功蓋” 出現在一行的最後,剛剛的轉換編碼+替換文字的動作會把原本 \r\n 的 Enter 符號破壞掉!變成 r\n,這將會導致 “許功蓋” 結尾的那一行最後,會在網頁上看到多了一個 r!

《按一下可顯示圖片》

這個問題要如何解決呢?其實也很簡單,那就是再轉換一次吧!我特別緻做了另外一個轉換檔:

《按一下可顯示圖片》

檔案內容其實就是把 “功r\n” 的錯誤改回到 “功\r\n”,這樣子就可以更完美的修正,因為前面移除 \\ 與 \ 符號的問題喔~ :lol:

《按一下可顯示圖片》

為了解省各位的時間,我把這兩個轉換 “許功蓋衝碼” 的 .dat 檔放在這裡,你可以點選連結把檔案下載回去:

http://bnwwoo.googlepages.com/big5utf801.dat
http://bnwwoo.googlepages.com/big5utf802.dat

要怎樣使用這兩個檔案呢?其實滿簡單的,在 ConvertZ 的工作列圖示上,按一下右鍵並點選 “程式設定”:

《按一下可顯示圖片》

按 “匯入” 並點選指定的 .dat 檔即可:

《按一下可顯示圖片》

按下編輯就可以在 “詞彙修正表” 這裡修改或新增替換文字:

《按一下可顯示圖片》

這是剛剛第一次執行 \\ 與 \ 轉換的對照表,每次只能選用一種,處理的先後順序不可以相反喔!要先處理 “\\ 與 \” 修正,再處理 “r\n” 的修正!

《按一下可顯示圖片》

這次要做的轉換動作是把 “輸入格式” 的 UTF-8 轉成 “輸出格式” 的 UTF-8,也就是編碼方式不變,但是要記得點選 “繁體中文” 以便取代我們想要修正的文字!

《按一下可顯示圖片》

確定是 “UTF-8 > UTF-8 繁體”,就可以 “開始轉換” 囉~

《按一下可顯示圖片》

轉換時間同樣需要 19 秒左右:

《按一下可顯示圖片》

這就是轉換完畢的 UTF-8 編碼的 MySQL 資料庫檔案!這個檔案可以被 “記事本” 或是 Mac OS X 的 “文字編輯”、BBEdit 等工具直接開啟,而不會看到任何錯誤!

《按一下可顯示圖片》

趕緊找一下剛剛的 “練功r\n”,果然現在被修正為正確的 “練功\r\n”! :lol:

《按一下可顯示圖片》

OK,現在你已經學會怎樣把最重要的 .sql 資料庫從 BIG-5 完美的轉換成 UTF-8,如果你發現轉換之後的資料有亂碼,請檢查原始的 BIG-5 檔案,通常原始檔案裡面就已經是亂碼了!亂碼進、當然亂碼出... >:)

接下來把 BIG-5 網站程式,無論你是使用 phpBB、XOOPS 還是哪一套網站系統,都可以透過 ConverZ 來幫你轉換,只要點選整個目錄並按 “全部加入”,就可以一次轉好整個網站檔案夾!如果擔心轉換程式出錯的話,你也可以下載 phpBB、XOOPS 官方提供的 UTF-8 版本,直接覆蓋取代舊的 BIG-5 程式就行了。只是這麼做的話,要特別留意目前網站使用的程式版本。

如果還在使用舊的 BIG-5 版本,建議你先轉好 .sql 資料庫,並匯入到轉換好的 UTF-8 網站程式,最後再執行升級系統版本的動作。當然,你也可以在轉換網站系統之前,先把 BIG-5 的舊網站程式升級到最新版本,再做轉換 .sql 資料庫編碼語系的動作,最後直接用 UTF-8 新版程式覆蓋舊版。

如果你有自行修改過 phpBB 或 XOOPS 程式碼,就不適合用 “取代舊版程式” 的做法,只能採用升級網站系統的方式。這部份就不在這裡討論了。

進藤ヒカル さん


虛擬画像

作成: 04/28/07 05:11pm
匯入 UTF-8 編碼的資料庫到 MySQL

透過網路上的芳鄰把轉換好的 wusin_test utf8.sql 傳回到 Mac OS X,如果你不會的話,也可以透過 “隨身碟” 等其他儲存設備。

《按一下可顯示圖片》

這次直接用 “文字編輯” 就可以開啟 UTF-8 編碼的 .sql 資料庫囉! :lol:

《按一下可顯示圖片》

我不喜歡用 phpMyAdmin 來管理資料庫,有更直接好用的工具,幹嘛不用呢?請使用 MySQL 提供的 MySQL Administrator 來管理資料庫吧~
先按一下 “Catalogs”,並點選要匯入的資料庫,如果是第一次匯入資料庫,你得先按一下 “+” 號鈕,新增一個 xoops 之類的資料庫,再按一下 “Restore” 工具鈕,這樣子 MySQL Administrator 才會知道你要把 “備份的資料表” 匯入到哪一個資料庫裡?

請按 “Choose File...” 並點選要匯入的資料庫檔:

《按一下可顯示圖片》

要選 “wusin_test utf8.sql” 喔~資料的編碼格式為 UTF-8!

《按一下可顯示圖片》

在正常的情況下,不需要點選 Options 的兩個選項,只要直接按 “Restore Backup” 即可,如果會看到錯誤訊息,很可能是在 phpMyAdmin 匯出資料的時候沒有選好,你可以在 MySQL Administrator 刪除舊的資料庫,重建一個新的資料庫,再重新匯入看看。

《按一下可顯示圖片》

如果有錯誤訊息,一定要想辦法解決,否則資料很可能沒有完整匯入!遷移後的新網站也可能因此無法正常運作!

《按一下可顯示圖片》

正在 Restoring 回存備份的資料庫...

《按一下可顯示圖片》

回存完畢囉!請檢查看看資料表數量是否與舊的資料庫相同?如果有短缺,肯定是前面在 phpMyAdmin 匯出的時候點選了錯誤的選項,該選的沒選,點選了不該選的項目。

《按一下可顯示圖片》

雖然你也可以用 “Ignore SQL errors” 略過 SQL 指令錯誤來匯入資料,不過通常在這種情況下,匯入的資料都不完整!

《按一下可顯示圖片》

總共匯入了 126 張資料表,你可以與 phpMyAdmin 比對看看,是不是同樣的 126 張資料表格?當然囉,這是我們的網站,你的網站會因為安裝的模組不同,資料表數量也不相同。

《按一下可顯示圖片》

再次提醒你,要記得點選 phpMyAdmin 最前面的這兩個重要選項,再匯出資料庫:
■ Add DROP TABLE : 加上刪除資料表指令。
■ Add IF NOT EXISTS :加上檢查資料表示否不存在的指令。

《按一下可顯示圖片》

進藤ヒカル さん


虛擬画像

作成: 04/28/07 05:13pm
最後的檢查工作:比對新、舊網站是否一致?

這是舊的「聞字網」網站:

《按一下可顯示圖片》

這是新的搬家後的「BNW 時尚藝文館」網站,請留意兩個網站的網址不同,但是網頁內容應該幾乎完全相同喔~

《按一下可顯示圖片》

我點選「聞字網」其中的一篇公告網頁,讓你再仔細比對一下:

《按一下可顯示圖片》

接著點選「BNW 時尚藝文館」相同的一篇公告網頁畫面,請比對看看是不是一模一樣呢? :-)

《按一下可顯示圖片》

表面上一模一樣的網站,骨子裡可完全不同喔!我把「聞字網」的 “顯示方式 / 文字編碼” 改成 “Unicode (UTF-8)” 就會看到整個網站通通變成亂碼!必須點選 “預設值” 或是 “繁體中文 (BIG5 HKSCS)” 才能恢復正常。

《按一下可顯示圖片》

同樣的動作,將瀏覽器的 “顯示方式 / 文字編碼” 改成 “Unicode (UTF-8)” ,你會看到「BNW 時尚藝文館」並沒有出現亂碼,反倒是故意點選 “繁體中文 (BIG5 HKSCS)” 的時候會出現亂碼!

《按一下可顯示圖片》

也就是說,我們已經把一個過去以 BIG-5 架設的網站,成功的轉移到新的網址、新的網站、新的資料庫 (資料庫名稱與過去不同),新的 UTF-8 多國語系編碼方式! :lol: :lol:

《按一下可顯示圖片》

現在直接在 “搜尋文章” 輸入 “練功”,找找看剛剛的 “許功蓋” 以及 “r\n” 修正處理,到底有沒有轉換成功?

《按一下可顯示圖片》

嗯嗯~你可以看到這裡的 “練功” 後面並沒有多了一個 \ 反斜線編碼喔!

《按一下可顯示圖片》

而另外一行結尾的 “練功” 同樣 100% 完美!不但後面沒有多餘的 \ 反斜線,也沒有多餘的 r 字元喔~真是太完美、太棒了! :lol: :-)

《按一下可顯示圖片》

其實要感謝的還是 “竹貓”,他們幫我完成了前面的 90%,我只是在後面補上缺少的那 “r\n” 修正的 10% 而已,呵呵~ :lol:

進藤ヒカル さん


虛擬画像

作成: 04/28/07 05:17pm
附錄:將BIG5轉UTF8編碼修正2.dat

代碼: 全部選択
-1,-1,-1,-1,-1,-1 修正前,修正後 么r\n,么\r\n 功r\n,功\r\n 吒r\n,吒\r\n 吭r\n,吭\r\n 沔r\n,沔\r\n 坼r\n,坼\r\n 歿r\n,歿\r\n 俞r\n,俞\r\n 枯r\n,枯\r\n 苒r\n,苒\r\n 娉r\n,娉\r\n 珮r\n,珮\r\n 豹r\n,豹\r\n 崤r\n,崤\r\n 淚r\n,淚\r\n 許r\n,許\r\n 廄r\n,廄\r\n 琵r\n,琵\r\n 跚r\n,跚\r\n 愧r\n,愧\r\n 稞r\n,稞\r\n 鈾r\n,鈾\r\n 暝r\n,暝\r\n 蓋r\n,蓋\r\n 墦r\n,墦\r\n 穀r\n,穀\r\n 閱r\n,閱\r\n 璞r\n,璞\r\n 餐r\n,餐\r\n 縷r\n,縷\r\n 擺r\n,擺\r\n 黠r\n,黠\r\n 孀r\n,孀\r\n 踊r\n,踊\r\n 髏r\n,髏\r\n 躡r\n,躡\r\n 尐r\n,尐\r\n 佢r\n,佢\r\n 汻r\n,汻\r\n 岤r\n,岤\r\n 垥r\n,垥\r\n 柦r\n,柦\r\n 胐r\n,胐\r\n 娖r\n,娖\r\n 涂r\n,涂\r\n 罡r\n,罡\r\n 偅r\n,偅\r\n 惝r\n,惝\r\n 牾r\n,牾\r\n 莍r\n,莍\r\n 傜r\n,傜\r\n 揊r\n,揊\r\n 焮r\n,焮\r\n 茻r\n,茻\r\n 鄃r\n,鄃\r\n 幋r\n,幋\r\n 滜r\n,滜\r\n 綅r\n,綅\r\n 赨r\n,赨\r\n 塿r\n,塿\r\n 縷r\n,縷\r\n 槙r\n,槙\r\n 擺r\n,擺\r\n 箤r\n,箤\r\n 踊r\n,踊\r\n 嫹r\n,嫹\r\n 髏r\n,髏\r\n 潿r\n,潿\r\n 蔌r\n,蔌\r\n 醆r\n,醆\r\n 嬞r\n,嬞\r\n 獦r\n,獦\r\n 佢r\n,佢\r\n 螏r\n,螏\r\n 餤r\n,餤\r\n 燡r\n,燡\r\n 螰r\n,螰\r\n 駹r\n,駹\r\n 礒r\n,礒\r\n 鎪r\n,鎪\r\n 瀙r\n,瀙\r\n 酀r\n,酀\r\n 瀵r\n,瀵\r\n 騱r\n,騱\r\n 酅r\n,酅\r\n 贕r\n,贕\r\n 鱋r\n,鱋\r\n 鱭r\n,鱭\r\n 會r\n,會\r\n 育r\n,育\r\n ﹏r\n,﹏\r\n

hollowaysxp さん


虛擬画像

作成: 04/30/07 05:19am
光哥的轉換方式看了之後大概了解方法了。

我之前也是用phpBB2.0.21 Big5版,資料庫校對瑪是Big5。
轉換方式是把資料庫備份成Mysql 4.0的形式。

然後再把Mysql4.1校對碼改成跟Mysql4.0預設一樣的編碼方式拉丁文。
再把資料庫還原這樣子資料庫就轉變成UTF-8了 :shock:

2011年7月9日 星期六

處理含 ASCII 92 字元之文字輸入值

MySQL Big5轉utf8及亂碼問題解決

資料來源:http://www.codecharge.com.tw/phpBB3/viewtopic.php?f=11&t=715&start=0
1、MySQL 新版的變化:
MySQL 4.1 以後對多語言的支持有了很大變化 (這也導致了許多問題的出現);儘管大部分的地方,MySQL 3 仍然占主導地位;但 MySQL 4.1 是 MySQL 官方推薦的數據庫,(截自目前MySQL己出到了5.2.2),已經有主機提供商開始提供並將會越來越多; 許多 PHP 程序以 MySQL 作為默認的數據庫管理軟件,但它們一般不區分 MySQL 4.1 以上與 4.1 以下版本的區別,籠統地稱「MySQL 3.xx.xx 以上版本」就滿足安裝需求了; 因為 latin1 在許多地方 (下邊會詳細描述具體是哪些地方) 作為默認的字符集,成功的蒙蔽了許多 PHP 程序的開發者和用戶,掩蓋了在中文等語言環境下會出現的問題;簡單的說,MySQL 自身的變化和使用 MySQL 的 PHP 程序對此忽略,導致了問題的出現和複雜化,而由於大部分用戶使用的是英文,使得這種問題不被重視。但在中文環境使用下因而產生了許多的問題。
2、MySQL 4.1 字符集支持的原理:
MySQL 4.1 對於字符集的指定可以細化到一台機器上安裝的 MySQL,其中的一個數據庫,其中的一張表,其中的一欄,應該用什麼字符集。但是,傳統的 Web 程序在創建數據庫和數據表時並沒有使用那麼複雜的配置,它們用的是默認的配置,那麼,默認的配置從何而來呢?
編譯 MySQL 時,指定了一個默認的字符集,這個字符集是 latin1;
安裝 MySQL 時,可以在配置文件 (my.ini) 中指定一個默認的的字符集,如果沒指定,這個值繼承自編譯時指定的;
啟動 mysqld 時,可以在命令行參數中指定一個默認的的字符集,如果沒指定,這個值繼承自配置文件中的;
此時 character_set_server 被設定為這個默認的字符集;
當創建一個新的數據庫時,除非明確指定,這個數據庫的字符集被缺省設定為 character_set_server;
當選定了一個數據庫時,character_set_database 被設定為這個數據庫默認的字符集;
在這個數據庫裡創建一張表時,表默認的字符集被設定為character_set_database,也就是這個數據庫默認的字符集;
當在表內設置一欄時,除非明確指定,否則此欄缺省的字符集就是表默認的字符集;
這個字符集就是數據庫中實際存儲數據採用的字符集,mysqldump 出來的內容就是這個字符集下的;
簡單的總結一下,如果什麼地方都不修改,那麼所有的數據庫的所有表的所有欄位的都用 latin1 存儲,不過我們如果安裝 MySQL,一般都會選擇多語言支持,也就是說,安裝程序會自動在配置文件中把 default_character_set 設置為 UTF-8,這保證了缺省情況下,所有的數據庫的所有表的所有欄位的都用 UTF-8 存儲。
當一個 PHP 程序與 MySQL 建立連接後,這個程序發送給 MySQL 的數據採用的是什麼字符集?MySQL 無從得知 (它最多只能猜測),所以 MySQL 4.1 要求客戶端必須指定這個字符集,也就是 character_set_client,MySQL 的怪異之處在於,得到的這個字符集並不立即轉換為存儲在數據庫中的那個字符集,而是先轉換為 character_set_connection 變量指定的一個字符集;這個 connection 層究竟有什麼用我不大明白,但轉換為 character_set_connection 的這個字符集之後,還要轉換為數據庫默認的字符集,也就是說要經過兩次轉換;當這個數據被輸出時,又要由數據庫默認的字符集轉換為 character_set_results 指定的字符集。
以一個典型的環境為例,電腦上安裝著 Apache 2,PHP 5 和 WordPress 1.5.1.3,MySQL 配置文件中指定了 default_character_set 為 utf8。於是問題出現了:
WordPress 按照默認情況安裝,所以所有的表都用 UTF-8 存儲數據;
WordPress 默認採用的瀏覽字符集是 UTF-8 (Options->Reading 中設置),因此所有 WP 頁面的 meta 中會說明 charset 是 utf-8;
所以瀏覽器會以 utf-8 方式顯示所有的 WP 頁面;這樣一來 Write 的所有 Post,和 Comment 都會以 UTF-8 格式從瀏覽器發送給 Apache,再由 Apache 交給 PHP;
所以 WP 從所有的表單中得到的數據都是 utf-8 編碼的;WP 不加轉換的直接把這些數據發送給 MySQL;
MySQL 默認設置的 character_set_client 和 character_set_connection 都是 latin1,此時怪異的事情發生了,實際上是 utf-8 格式的數據,被「當作 latin1」轉換成……居然還是轉換成 latin1,然後再由這個 latin1 轉換成 utf-8,這麼兩次轉換,有一部分 utf-8 的字符就丟失了,變成 ??,最後輸出的時候 character_set_results 默認是 latin1,也就輸出為奇怪的東西了。
3、PHP 程序與 MySQL 建立連接:
所以為了解決這些問題,在PHP 程序與 MySQL 建立連接時,於query 之前先執行:
SET character_set_client=’utf8′
SET character_set_connection=’utf8′
SET character_set_results=’utf8′
如上三列編碼都一樣時,可寫成 SET NAMES ‘utf8′
上面3個變量的作用是這樣的,client表示客戶端發送過來的字符集,results表示發送到客戶端的字符集(這兩個分開是因為發送過來和發送過去的不一定是同一個客戶端),connection則在客戶端和數據庫起一個連接作用。
如果是租用網路伺服器,首先測試服務器MySQL資料庫是否 >= 4.1,編譯時是否加入了 UTF-8 支持;然後測試數據庫以什麼格式存儲 ($dbEncoding);
SET NAMES $dbEncoding 。
4、MySQL資料庫big5轉utf8:
步驟一:首先把資料dump出來
由於先前用4.0時我的資料是存成latin1,所以dump出來後要用iconf或piconf把他轉成UTF-8,記得dump出來時要加上-default-character-set=latin1
#mysqldump -u帳號 -p -default-character-set=latin1 資料庫 >output.sql
步驟二:big5轉成utf8
如果原先是Big5的資料, dump出來後就直接把Big5轉成UTF-8即可
#piconv -f big5 -t utf8 output.sql >utf8.sql
如果原先是UTF-8的資料,像是wordpress,dump出來後要先轉成Big5後,再把他轉成UTF-8,因為原先dump出來的是偽裝成UTF-8的lantin1不是真正的UTF-8
#mysqldump -u帳號 -p -default-character-set=latin1 資料庫 >output.sql
#piconv -f utf8 -t big5 output.sql > big5.sql
#piconv -f big5 -t utf8 big5.sql >utf8.sql
步驟三:修改sql檔
1、修改轉成的sql檔中所產生的‘’\”及換行
的問題(有時換行時會成‘\n’)
2、在dump出來的sql檔最前面加上:
SET NAMES utf8;
SET CHARACTER_SET_CLIENT=utf8;
SET CHARACTER_SET_RESULTS=utf8;
再來把每個資料表後面的TYPE=MyISAM;
改成DEFAULT CHARSET=utf8;
步驟四:建立新的資料庫
方法1. SQL語法
CREATE DATABASE `abc` DEFAULT CHARACTER SET utf8
COLLATE utf8_general_ci;
方法2. 用phpMyAdmin建立資料庫的,建立時”校對”要選utf8_general_ci
步驟五:import資料
方法1. SQL語法
#mysql -u帳號 -p 資料庫 < utf8.sql
方法2. 直接用phpMyAdmin把他import進去了,import時記得文字編碼檔案要選utf8即可。不過使用phpMyAdmin import 有檔案大小的限制,可先把sql檔分成幾個檔案。
方法3.用Webmin import (我即是用此方法,如滙入不成功還可知在那一行的sql出問題,因有時在轉成utf8時有些因‘許功蓋’會產生一些‘\’)
最後記得檢查看MySQL的my.cnf設定檔內要加入以下設定
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
default-character-set=utf8
default-collation=utf8_general_ci

2011年7月7日 星期四

BigDump: Staggered MySQL Dump Importer

Home

Staggered import of large and very large MySQL Dumps (like phpMyAdmin 2.x dumps) even through the web servers with hard runtime limit and those in safe mode. The script executes only a small part of the huge dump and restarts itself. The next session starts where the last was stopped.
The last version includes some very important bugfixes and other improvements. Please don’t hesitate to report any bugs in this release but read the usage notes and the FAQs first!
THIS SCRIPT IS PROVIDED AS IS, WITHOUT ANY WARRANTY OR GUARANTEE OF ANY KIND.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. If you change this script or add any features please tell me. I will consider adding these features for everybody.

BigDump ver. 0.33b (beta)


大家都知道常用的 MySQL 数据库恢复工具是 phpMyAdmin,这是一个开源、免费的工具,大多数主机商都会免费提供 。相信很多wordpress站长也用过 phpMyAdmin 来进行网站数据库的备份和恢复,确实很方便,并且有多国语言界面。不过,有一种情况可能你还没碰到,就是当你的数据库体积比较大时,例如 SQL 备份文件大于 2MB,甚至大于 10MB,这个时候如果你通过 phpMyAdmin 来进行数据库的恢复,就会出错,显示如下的提示:
通过 phpMyAdmin 来进行数据库的恢复,就会出错
这是因为你的 SQL 文件体积太大,超过了 phpMyAdmin 的处理能力,这种情况在网络速度比较慢的情况下尤为突出,例如站长在周末晚上8点这个网络拥挤的时段尝试使用 phpMyAdmin 来恢复大型 MySQL 数据库备份,就容易遇到这种问题。
很显然 phpMyAdmin 只适用于恢复比较小的 SQL 文件备份。对于超大 MySQL 数据库备份的恢复,你必须换一个专用的恢复工具,那就是:BigDump!

BigDump 数据库导入工具简介

BigDump 是由德国人 Alexey Ozerov 用 PHP 语言开发的一个工具脚本,它只有一个文件,名为 bigdump.php(你可以改名运行)。这个文件是独立运行的,因此与你的网站核心程序无关,不管是 WordPress,Drupal 还是 Joomla,只要你使用的是 MySQL 数据库,都可以用 BigDump 来恢复超大的 .sql 格式备份文件。
BigDump 工作的原理也很简单:切割分段导入。它在读取 SQL 文件时,每次只读取一小部分,将其导入,然后重新开始一次恢复进程,再读取一小部分…… 周而复始,直到将整个 SQL 文件全部导入。

BigDump 数据库恢复工具用法演示

假设我们已经有了一个 MySQL 数据库的备份文件,名为 gate2.sql,文件大小约 150MB(这么大的文件别指望通过 phpMyAdmin 来恢复了)。数据库字符编码为 utf-8。我们演示一下如何通过 bigdump.php 工具将这个备份文件恢复到在线数据库中去。

1、获取 BigDump 文件并设置

我们下载 BidDump 工具并解 压,得到一个 bigdump.php 文件。毫无疑问,bigdump.php 文件需要设置一些参数,否则它怎么知道要导入的数据库的连接帐号?
用文本编辑器打开 bigdump.php 文件,在大约第 38 行开始,我们设置要导入的 MySQL 数据库连接参数。如下图所示:
设置要导入的 MySQL 数据库连接参数
一般来说,设置好这几项就可以了。对于某些特殊数据库,还需要在下面第66行左右设置数据库字符编码。bigdump.php 文件中没有预设这个参数,原文是:
$db_connection_charset = ”;
如果你的数据库是 UTF-8 编码,那么此处就要修改为:
$db_connection_charset = ‘utf8′;
注意那个连字符要去掉。如下图所示:
数据库 UTF-8 编码就要修改为: $db_connection_charset = 'utf8'
接下来将设置好的 bigdump.php 文件上传到 Joomla 网站上,推荐上传到 /tmp 这个临时目录。

2、上传 MySQL 数据库备份文件

现在需要将数据库备份文件上传到 bigdump.php 所在的 /tmp 目录中。考虑到文件较大,我们通过 FTP 软件 FileZilla 上传 zip 格式的文件,然后借助 Joomla 后台安装的 eXtplorer 资源管理器组件 将其远程解压,在 /tmp 目录中得到 gate2.sql 文件。

3、启动 BigDump 工具

在浏览器地址栏输入 bigdump.php 所在 URL 并回车,运行这个文件。例如本次演示是在本地测试服务器上进行,那么对应的运行网址是:
http://localhost/gate/tmp/bigdump.php
如果你输入的 URL 正确,就应该看到如下画面:
http://localhost/gate/tmp/bigdump.php
这就表示 BigDump 工具已经成功启动,它在启动时就自动扫描所在目录中的全部文件和子目录。如果找到 SQL 格式或者 gzip/zip 格式文件,就假设这是数据库文件,在这些文件后面,就会显示出相应的操作链接。例如在上图中,它探测到所在目录中有一个 gate2.sql 文件,那么针对该文件就在表格右侧同一行中显示了两条操作链接,分别是“Start Import”(开始导入)和“Delete file” (删除文件)。上图的表格中也显示了 SQL 文件的大小,可以看到这个备份文件接近 150MB。
在上图中,还可以看到一个文件上传功能,点击那个“浏览”按钮,你就可以上传一个 SQL 文件(或其压缩包)来进行导入。但是我们不推荐使用此功能。对于大型文件,FTP 上传是最佳选择。

4、运行 BigDump 导入功能

点击上图中的“Start Import” 链接,就看到如下画面:
点击上图中的“Start Import” 链接
上面这个截图是导入开始一段时间之后所截取的,可以看出 BigDump 正在顺利进行 SQL 文件的导入。表格中不仅显示了文件大小,还显示了已经导入的字节数及总体进度。
经过一段时间后(大约20分钟),这个 150MB 大小的 SQL 文件终于导入结束,看到如下画面:
150MB 大小的 SQL 文件终于导入结束
原来显示进度条的地方,现在显示了一条消息:
“Congratulations: End of file reached, assuming OK”
意思是说:已经到达文件末尾,想必应该成功了。看到这条消息,你就可以完全放心了。BigDump 已经成功地将你的 SQL 备份文件导入到你所指定的 MySQL 数据库里面了。
注意:数据库恢复成功结束后,不要忘记删除 bigdump.php 备份工具和你的 SQL 文件!

使用 BigDump 数据库导入工具的注意事项

1、在开始导入之前,目标数据库必须清空

如果目标数据库里面含有记录,那么 BigDump 就无法导入,会报错停止。因此请在开始运行 bigdump.php 文件之前,将目标数据库清空(最好删除全部内容)。

2、所用的 SQL 文件不能含有 Extended Inserts

或许很多第一次使用 BigDump 的用户都会遭遇这个问题。这是因为 phpMyAdmin 在导出数据库时,已经默认勾选了“使用扩展插入”。
这里的“扩展插入”就是 Extended Inserts,而 BigDump 是不能处理带有 Extended Inserts 的 SQL 文件的。所以,在你制作数据库备份时,必须在 phpMyAdmin 的面板上去掉“扩展插入”的勾选。如下图所示:
phpMyAdmin 的面板上去掉“扩展插入”的勾选

3、如何使 Akeeba Backup 与 BigDump 配合工作?

我们前面推荐大家使用 Akeeba Backup 来制作备份文件。那么,可否使用 Akeeba Backup 来制作数据库备份,然后通过 BigDump 导入?当然是可以的。不过,这里面需要一些特殊技巧。我们将在 Akeeba Backup 使用详解 这篇教程中介绍。

4、使用 BigDump 导入仍然发生超时错误

这种问题多见于配置比较低的服务器,或者服务器繁忙时段。那么,你可以尝试修改 bigdump.php 文件中的“Other settings (optional)” 这部分的 $linespersession 参数,将默认值 3000 修改得更小一些。(不过,我认为你还是换一个更好的服务器吧,例如 Hawkhost)。

5、发生 MySQL 服务器超载怎么办?

如果服务器性能较差,在运行 bigdump.php 过程中可能会发生 MySQL 服务器超载(overrun)故障。你可以修改 bigdump.php 文件中的 $delaypersession 参数来解决。该参数让 bigdump.php 文件在结束一个片段的导入之后,休息一段时间(你设定的数值就是暂停的时间,单位:毫秒),然后再开始下一个片段的导入,这样服务器就不会太累了。

6、直接把 .sql 格式文件交给 BigDump

在本次演示中,我们先将 zip 格式的备份包上传到服务器上,然后又将它解压成 .sql 格式的文件,再通过 BigDump 来导入。为什么不直接用 BigDump 来导入压缩格式的备份文件?
没错,BigDump 具有导入压缩格式 SQL 备份文件(zip/gzip)的能力,但是在处理压缩文件时,它需要先在临时目录中将其解压,再读取。请注意:这个解压并不是一次性的,而是每导入一个小 片段,就要将整个压缩包重新解压一次。因此,直接导入压缩格式文件,反而使 bigdump.php 运行变慢。

7、还有更奇怪的问题……

一般来说,运行 bigdump.php 导入一个 SQL 备份文件非常容易。如果你参照上述注意事项及操作过程,仍然不能顺利完成数据库备份文件的导入,那么请到 BigDump 官方网站 阅读更多 FAQ,查找原因。如果还无法解决,可以到 Joomla 中文论坛 发帖讨论。
 

2011年7月6日 星期三

PHP安全程式寫作範例

PHP安全程式寫作範例

  • 對象: 程式設計人員
  • 難易度: ★★★☆☆
  • 技術新舊: ★★☆☆☆
  • 閱讀所需時間: 2 小時

PHP安全程式寫作

網路應用程式的安全性如今已是大家重視的話題,但是在程式開發過程,常常是到了最後一刻才將security的部分補足。
其中有一個原因是安全程式碼撰寫的概念並未建立,如果在程式撰寫階段就將安全性的問題考慮進去,在日後檢驗與維護系統安全時,將會更容易。

因此,我們針對從客戶端送進來的資料常見的六種攻擊方式,分別提示PHP程式如何撰寫來防禦這些攻擊行為:
1. SQL 注入攻擊 (SQL injection attack)
2. 操縱 GET 的值 (manipulating GET variables)
3. 緩衝器溢位攻擊 (buffer overflow attack)
4. 跨站腳本攻擊 (cross-site scripting)
5. 操縱瀏覽器內的資料 (manipulating data inside the browser)
6. 遠程表格遞交 (remote form posting)

另外,下面有幾項簡單的安全性原則是每一個PHP程式撰寫者都應該遵守的:
1.永遠不信任外來的資料
外來的資料包括所有不是直接由programmer撰寫於PHP code裡的資料,像是從GET、POST取得的input、database、configuration file、session variable、cookie等,這些資料在經過驗證或消毒以前都必須將它視為tainted。而通常最簡單的消毒input方式是利用regular expression,定義你所接受的字串類型或內容。

2.確保一些PHP設定例如register_globals、display_errors等已關閉
如果開啟register_globals,將造成GET和POST的值($_GET、$_POST)都能直接使用$variable去接收,這將造成安全性問題。另外,當系統上線後錯誤報告必須謹慎處理,不該讓它出現在瀏覽畫面上,許多attacker就是利用錯誤報告內的資訊來猜想你系統的相關內容,所以要記得關閉display_errors等error-reporting的功能。

3.寫簡潔清晰的程式碼,使安全漏洞更容易被檢查出來
避免使用艱深的語法,這種寫法或許會有較好的效能,但是如果無法簡單地讓人了解code的內容,也會造成安全性判斷的困難。

4.把「深度防禦」列為座右銘
對於網路應用程式的安全必須為全面性的,當你已利用regex檢驗GET的input值後,當然也不能遺忘SQL query內是否也有安全性的疑慮。

SQL注入攻擊(SQL injection attack)

現今的網站應用程式架構常由$_GET, $_POST取得使用者輸入的資料,並經由 database query 查詢資料庫的資料以動態地產生網頁,但若是網站應用程式沒有仔細驗證使用者的輸入值,則惡意的使用者便可以輸入惡意的資料當作查詢一部分給資料庫執行,而造成程式設計師預期外的結果。
例如下面這個例子,我們的資料庫裡有username和password兩個欄位,我們建立一個登入頁面,讓使用者輸入帳號和密碼以登入網站;當使用者輸入完資料送出後,表單會用post方式將使用者的資料傳給verify.php去做身份驗證。

登入表單:
<form action="verify.php" method="post">
<p>Username:<input type='text' name='user'/></p>
<p>Password:<input type='password' name='pw'/></p>
<p><input type='submit' value='login'/></p>
</form>
verify.php
$okay = 0;
$username = $_POST['user'];
$pw = $_POST['pw'];
$sql = "select count(*) as ctr from users where username='".$username."' and password='". $pw."' limit 1";
$result = mysql_query($sql);
while ($data = mysql_fetch_object($result)){
if ($data->ctr == 1){
//they're okay to enter the application!
$okay = 1;
}
}
if ($okay){
$_SESSION['loginokay'] = true;
header("index.php");
}else{
header("login.php");
}
我們仔細檢視verify.php的程式碼,將發現安全上的漏洞,可能造成SQL injection attack。如果有一個惡意的使用者,在username的部分輸入foo,而在password部分輸入' or '1'='1,這將會造成整個SQL query 呈現以下的形式,由於使用者所加上的惡意輸入使得WHERE中整個判斷式為真,所以此使用者即便沒有帳號密碼也順利登入系統。
$sql = "select count(*) as ctr from users where
username='foo' and password='' or '1'='1' limit 1";
這種由於程式碼寫作疏忽所造成SQL injection的安全漏洞,可以簡單地用PHP內建的函式mysql_real_escape_string()來解決,mysql_real_escape_string()是用來脫逸資料庫語法中的特殊字元,像是\ ,',”。
因此我們將原本的verify.php程式加上mysql_real_escape_string()重新撰寫如下:
$okay = 0;
$username = $_POST['user'];
$pw = $_POST['pw'];
$sql = "select count(*) as ctr from users where 
username='".mysql_real_escape_string($username)."'
and password='". mysql_real_escape_string($pw)."' limit 1";
$result = mysql_query($sql);
while ($data = mysql_fetch_object($result)){
if ($data->ctr == 1){
//they're okay to enter the application!
$okay = 1;
}
}
if ($okay){
$_SESSION['loginokay'] = true;
header("index.php");
}else{
header("login.php");
}
則當username的部分輸入foo,而password部分輸入' or '1'='1時,會產生以下的SQL query,因為 ' (單引號)已被脫逸為string的一部分,所以此查詢會正常執行,去資料庫找尋是否有符合的帳號密碼配對。
$sql = "select count(*) as ctr from users where \
username='foo' and password='\' or \'1\'=\'1' limit 1"

操縱GET的值(manipulating GET variables)

網頁應用程式的某些撰寫方式可能會讓使用者看到與網站內部程式或檔案相關的資訊,例如一個網址 template.php?pid=321,在URL中?之後接的為 GET query string,則該網頁可用 $_GET['pid'] 去接收此變數的值。例如下面的例子,利用 $_GET['pid'] 的值來動態產生頁面:
$pid = $_GET['pid'];
//we create an object of a fictional
class Page
$obj = new Page;
$content = $obj->fetchPage($pid);
//and now we have a bunch of PHP that displays the page
這樣的程式撰寫方式可能會有安全上的漏洞,因為我們不能確定GET變數的值為安全的,有可能是使用者手動輸入的不安全 SQL command 或長度很長的字串。
但我們可以確定的是 pid 的值必須是一個數字,因此我們可以利用 PHP 內建的函式 is_numeric() 去檢查 $_GET['pid'] 的值,不過 is_numeric() 函式仍有一些不足之處;因此最好的方式還是利用 regular expression 來確保變數值為數字。我們可以將程式改寫為:
$pid = $_GET['pid'];
 
if (strlen($pid)){
if (!ereg("^[0-9]+$",$pid)){
//do something appropriate, like maybe logging them out or sending them back to home page
}
}else{
//empty $pid, so send them back to the home page
}
$obj = new Page;
$content = $obj->fetchPage($pid);
//and now we have a bunch of PHP that displays the page
我們先用 strlen() 去看 $_GET['pid'] 是否有長度,如果有就用 all-number regular expression 檢查變數內容是否為數字型態,因此如果變數內容包含 letters, slashes, dots, or hexadecimal-like notations 都會被過濾掉而無法執行此頁面,防止可能的攻擊產生。
那如果使用者試圖輸入很長的數字串來造成 buffer overflow attack 呢?(下一個部分會對 buffer overflow attack 做更詳細的介紹)我們可以藉由 strlen() 函式來檢查字串長度。
$pid = $_GET['pid'];
 
if (strlen($pid)){
if (!ereg("^[0-9]+$",$pid) && strlen($pid) > 5){
//do something appropriate, like maybe logging them out or sending them back to home page
}
}else{
//empty $pid, so send them back to the home page
}
$obj = new Page;
$content = $obj->fetchPage($pid);
//and now we have a bunch of PHP that displays the page

緩衝器溢位攻擊(buffer overflow attack)

buffer overflow attack 主要是藉由 overflow the memory allocation buffer,造成網頁應用程式 denial of service、資料損毀或藉機對主機執行惡意的程式。要防止 buffer overflow attack 最大的重點就是檢查使用者輸入資料的長度。例如下面的表單設定 input text 的 maxlength 為40,並且在後端有 substr() 做第二層防範。
<?php
if ($_POST['submit'] == "go"){
$name = substr($_POST['name'],0,40);
//continue processing....
}
?>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
<p><label for="name">Name</label>
<input type="text" name="name" id="name" size="20" maxlength="40"/></p>
<p><input type="submit" name="submit" value="go"/></p>
</form>
同時使用 maxlength 參數值及 substr() 實現了縱深防禦的概念,利用 maxlength 可以直接防止使用者對資料庫輸入過長的字串;後端的 substr() 確保程式執行中變數如果被操作,長度過長的字串仍會被截斷,不會對應用程式造成傷害。
前一個部分(操縱GET的值中)提到的例子是採用 strlen() 來檢查 $_GET['pid'] 字串的長度,我們也可以藉由 substr() 取得符合我們所需長度的字串後再執行之後的程式碼。
$pid = $_GET['pid'];
if (strlen($pid)){
if (!ereg("^[0-9]+$",$pid)){
//if non numeric $pid, send them back to home page
}
}else{
//empty $pid, so send them back to the home page
}
//we have a numeric pid, but it may be too long, so let's check
if (strlen($pid)>5){
$pid = substr($pid,0,5);
}
$obj = new Page;
$content = $obj->fetchPage($pid);
//and now we have a bunch of PHP that displays the page
此外,不只是過長的 numbers or letters 會造成 buffer overflow attack,過長的 hexadecimal characters (如:\xA3 or \xFF)也會造成同樣效果。不過防止此類攻擊的概念是一樣的:就是確保字串長度沒有超過指定的長度;另外可以配合 regular expression 去除 hexadecimal 的字串。
<?php
if ($_POST['submit'] == "go"){
$name = substr($_POST['name'],0,40);
//clean out any potential hexadecimal characters
$name = cleanHex($name);
//continue processing....
}
function cleanHex($input){
$clean = preg_replace("![\][xX]([A-Fa-f0-9]{1,3})!", "",$input);
return $clean;
}
?>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
<p><label for="name">Name</label>
<input type="text" name="name" id="name" size="20" maxlength="40"/></p>
<p><input type="submit" name="submit" value="go"/></p>
</form>

跨站腳本攻擊(cross-site scripting)

cross-site scripting (XSS) 通常牽扯到使用者可以輸入資料的表單或任何供使用者 input 的地方。例如一個 guestbook 能讓使用者輸入 names, e-mail address, message,惡意的使用者可藉此輸入一些 JavaScript 讓瀏覽者 redirect 到另一個網站或偷取 cookie。
這種 XSS 攻擊可利用 PHP 內建的函式 strip_tags() 去除字串中的 HTML 和 PHP 標籤,同時這函式也可以自己設定可接受的 tags(例如:<b>、<i>)。
<?php
if ($_POST['submit'] == "go"){
//strip_tags
$name = strip_tags($_POST['name']);
$name = substr($name,0,40);
}
?>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
<p><label for="name">Name</label>
<input type="text" name="name" id="name" size="20" maxlength="40"/></p>
<p><input type="submit" name="submit" value="go"/></p>
</form>
但相對地,如果你開放使用者使用 HTML 標籤來發表內容的話,就必須使用 htmlspecialchars() 讓使用者輸入的 HTML 標籤保留它的意義,例如此函式會將 ampersand (&) 轉化成 &amp ;將 < 和 > 視為 HTML entities。

操縱瀏覽器內的資料(manipulating data inside the browser)

有些瀏覽器的 plug-in 提供使用者操作 header 或 form 資料內容的功能。例如 firefox plug-in:Tamper Data 可以輕鬆修改 HTTP headers、cookies、hidden text fields 的參數……等。因此在使用者點選 Submit 傳送出表單前,他可以先開啟 Tamper Data 將資料做些修改後再傳送。
以下面這個程式為例,我們在表單中加了許多 hidden text fields,其中像 action field 的值為 create,如果程式執行中會使用此值做 SQL command;那惡意的使用者就可藉由 plug-in 改變 hidden text fields 的內容,例如改為 delete 造成資料庫傷害。
<?php
if ($_POST['submit'] == "go"){
//strip_tags
$name = strip_tags($_POST['name']);
$name = substr($name,0,40);
//clean out any potential hexadecimal characters
$name = cleanHex($name);
//continue processing....
}
function cleanHex($input){
$clean = preg_replace("![\][xX]([A-Fa-f0-9]{1,3})!", "",$input);
return $clean;
}
?>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
<p><label for="name">Name</label>
<input type="text" name="name" id="name" size="20" maxlength="40"/></p>
<input type="hidden" name="table" value="users"/>
<input type="hidden" name="action" value="create"/>
<input type="hidden" name="status" value="live"/>
<p><input type="submit" name="submit" value="go"/></p>
</form>
要防範這類的攻擊,我們只能假設使用者可能擁有類似 Tamper Data 功能的工具,因此在撰寫程式碼時要小心謹慎,避免透露過多和系統操作相關的訊息,盡量不要使用 hidden 的方式傳送變數……等。

遠程表格遞交(remote form posting)

使用者瀏覽網頁時,任何人都可以用「另存新檔」的方式複製一份網頁檔案到自己電腦中;而惡意的使用者可複製一份含有表單的網頁,將 action 的值改為正確的指向,並且修改任何內容後再傳送,這時對方的 server 會把它視為合法的資料,但事實上,這個 request 並非由本身 server 所發出。
要防制 remote form posting 的攻擊可產生一個 token,為一個獨特的字串或者是一個 timestamp,再將這個 token 存進 session 以及放入表單中,藉由檢查這兩個 tokens 是否相同,來判定是否是 remote 的表單發出的 request。因為 session 的值會存放在 server 中,並且不會轉移。
以下的程式產生 random token,使用到 PHP 內建函式 md5()、uniqid()、rand()。
<?php
session_start();
if ($_POST['submit'] == "go"){
//check token
if ($_POST['token'] == $_SESSION['token']){
//strip_tags
$name = strip_tags($_POST['name']);
$name = substr($name,0,40);
//clean out any potential hexadecimal characters
$name = cleanHex($name);
//continue processing....
}else{
//stop all processing! remote form posting attempt!
}
}
$token = md5(uniqid(rand(), true));
$_SESSION['token']= $token;
function cleanHex($input){
$clean = preg_replace("![\][xX]([A-Fa-f0-9]{1,3})!", "",$input);
return $clean;
}
?>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
<p><label for="name">Name</label>
<input type="text" name="name" id="name" size="20" maxlength="40"/></p>
<input type="hidden" name="token" value="<?php echo $token;?>"/>
<p><input type="submit" name="submit" value="go"/></p>
</form>