2018年3月7日 星期三

PHP 連接 MS SQL Server 2000 的考量

Microsoft SQL Server 2000,雖然已有將近 20 年,但使用起來很方便,尤其現今電腦硬體強大,跑起來,更是非常有效率。

但是,使用 PHP,微軟提供的官方版本,只支援連接 SQL Server 2005 以上的版本。有人重新編譯,將限制拿掉,雖然可以連接 SQL Server 2000,但是使用上會有問題。

例如 $rs = DB::select("SELECT * FROM ifcrfcotmp where id=:p1",  ['p1' => '']);
會出現 Invalid precision value 的錯誤。使用 Query builer 也有同樣的問題,ORM 我沒有用,所以沒測過。
這種問題,使用得在應用上,很不方便。因為使用 parameter 或 Query builer,可以處理特殊字元,如單引號,尤其可以避免 sql injection 的攻擊。

在 Linux 下面,PHP 7.0 以上的版本,可以使用 dblib 來連接,也不會有上述問題。

在 Windows 的平台,Laravel 5.2 之後,可以透過 ODBC 來連接 SQL Server 2000,但是無法傳回 UTF-8 編碼的字串,必須轉換。

現在辦公室,還在大量的使用 Windows Server 2003,只能跑 PHP 5.4,也就只能用 Laravel 5.0。Laravel 5.2 中,連接 ODBC 在單一的程式中,其在 Laravel 5.0 也可以使用,可在 composer.json 中,"scripts" 的 "post-update-cmd" 部分,加上下述命令,在 update 之後,以 5.2 的程式覆蓋。
"cp SqlServerConnector_52.php vendor/illuminate/database/Connectors/SqlServerConnector.php"

Laravel 的 database 設定檔,內容如下
'connections' => [
    'odbc' => [
        'driver'   => 'sqlsrv',
        'database' => '',  // 需保留,可空白
        'username' => 'uid',
        'password' => 'pwd',
        'charset'  => 'utf8',  // 這設定是沒用的
        'prefix'   => '',
        'odbc' => true,  // Tell the driver to use ODBC connection
        'odbc_datasource_name' => 'Driver={SQL Server};Server=db_host;Database=db_name;',  // Only the name, don't include 'odbc:' prefix
        ],
],

因此,難以抉擇的是,該用那一種方式。以前都是用微軟的driver,碰到錯誤再處理,或將長度為0的字串改為長度為1的空白。或偷懶,直接串 sql 指令。這些都不是好的解法。

若改為使用 odbc 來連接,雖然要在 big5 與 utf8 之間轉換,麻煩些。但比較麻煩的問題是,轉換之後,有些字會不見,如簡體字。
例如 " 机器人公民索菲亚",轉成 big5,再轉回 utf8,就變成 "机器人公民索菲?",最後一個字變問號了。

小結

整理這篇文章,供自己日後參考,以免以後又再做重複的比較,浪費時間。
很顯然的,要連接 SQL 2000,一個是用 Linux + PHP 7.0 + dblib,若使用 Windows server 2003 + PHP 5.4 + sqlsrv driver,就麻煩點,處理好長度為0的字串。odbc 不予考慮,少字的問題,是無法控制的。

沒有留言:

張貼留言

網誌存檔