2012/12/19

「Microsoft Drivers for PHP for SQL Server」のv2.0とv3.0

前置き

こんばんは。3か月ぶりのエントリです。
表題のとおり、今回のネタは PHP と Microsoft な Windows 限定のお話です。

皆さんは「Microsoft Drivers for PHP for SQL Server」というのをご存じでしょうか。
PHPからMicrosoft SQL Serverに接続するためのMicrosoftが提供するドライバです。


.

「Microsoft Drivers 2.0 for PHP for SQL Server」からPDOに対応しているので、使いやすくなりました。
当時のMSの中の人が書いた記事には期待あふれる内容が書かれています。
(参考) CodeZine PHPからMicrosoft SQL Serverを使おう! 第2回 PHPからSQL Serverへの正しい接続方法 (2011/02/08)

ですが、「値はUTF-8に変換されるのに列名がSJISのまま」とか意味わからない仕様だったり、他にも不具合はあるみたいです。
(参考) GINPRO / SQLの窓と銀プログラマ Microsoft Drivers 3.0 for PHP for SQL Server が実運用では役に立たない件について (2012/06/12)
(いやまぁ「まず日本語列名やめろ」ってのは正しいと思うんですけどね。)

さて、私が面倒を見ているWEBアプリの中にこのドライバを使うものがありまして、
最近、業務兼開発環境のPCをWindowsXP(32bit)からWindows7(64bit)に移行し始めていて、このドライバをインストールする必要ができたわけです。
これのインストールの手順はGoogleで探せばいくらでも出てくるのでほとんどの人は迷わないはずですが、愚かな私は最近これのインストールではまったのでみなさんとの共有を兼ねて書き残します。

バージョン間の違い

現在このドライバの最新版は3.0.1で、「Microsoft Drivers 3.0 for PHP for SQL Server」の名称でダウンロードできるようになっていますが、同じページから古いバージョン「Microsoft Drivers for PHP for SQL Server 2.0」もまだダウンロードできます。
Download Center Microsoft Drivers 3.0 for PHP for SQL Server
  • SQLSRV20.EXE =「Microsoft Drivers for PHP for SQL Server 2.0」
  • SQLSRV30.EXE =「Microsoft Drivers 3.0 for PHP for SQL Server」
※このページに書かれている「System requirements」(システム要件)は「Microsoft Drivers 3.0 for PHP for SQL Server」のものであることに注意してください。

「Microsoft Drivers PHP for SQL Server 2.0」単体のダウンロードページはなくなっているのでちゃんとしたシステム要件を確認するのは難しいですが、
MSDNのページなどをまとめるとv2.0とv3.0は以下の違いがあります。

項目v2.0v3.0
対応しているOS Windows Server 2003 SP1
Windows Server 2008
Windows Server 2008 R2
Windows XP SP3
Windows Vista SP1
Windows 7
Windows Server 2008 SP2
Windows Server 2008 R2 SP1
Windows Vista SP2
Windows 7 SP1
対応しているPHPのバージョン PHP5.2
PHP5.3
PHP5.3
PHP5.4
必要な Microsoft SQL Server Native Client Microsoft SQL Server 2008 R2 Native Client Microsoft SQL Server 2012 Native Client
対応しているSQL Serverのバージョン SQL Server 2000 ~ 2008 R2 SQL Server 2005 ~ 2012
「対応しているSQL Serverのバージョン」の違いは、ドライバの仕様ではなくドライバが使う「Microsoft SQL Server Native Client」が違うことに起因しています。

(参考) Microsoft SQL Server 2008 R2 Native Client
(参考) Microsoft SQL Server 2012 Native Client

なお、「Microsoft SQL Server 2008 R2 Native Client」と「Microsoft SQL Server 2012 Native Client」は共存可能なので、両方インストールしても問題ないと思われます。

困るのは、この「Native Client」はバージョン違ってもインストーラーのファイル名が同じ「sqlncli.msi」になっていることです。Microsoftさんの悪い癖です。
(「Microsoft SQL Server 2005 Native Client」は「sqlncli_x64.msi」とかになってましたが、2008R2からはx64/x84の区別すらありません。)
ファイルのプロパティの詳細タブを見るとバージョンなどが書いてありますが、ファイル名だけでは区別がつかないのでご注意ください。

(ちなみに「Microsoft Drivers PHP for SQL Server」はバージョン2.0の前にv1.1とv1.0(?)があったのですが、今回の記事では省略させていただきます)


組み合わせが間違っている場合のエラー

ドライバのバージョンと「Native Client」のバージョンが違うと正しく動作しません。

「Microsoft Drivers for PHP for SQL Server 2.0」 + 「SQL Server 2012 Native Client」または「Native Client」なし
SQLSTATE[IMSSP]: This extension requires either the Microsoft SQL Server 2008 Native Client (SP1 or later) or the Microsoft SQL Server 2008 R2 Native Client ODBC Driver to communicate with SQL Server. Neither of those ODBC Drivers are currently installed. Access the following URL to download the Microsoft SQL Server 2008 R2 Native Client ODBC driver for x86: http://go.microsoft.com/fwlink/?LinkId=163712

これのすごいところはエラーメッセージで適切なURLに誘導していること。
これの痛いところはx64とすべき場合もx86と出しちゃっているところ。
リンク先には確かに「Download the X86 package」のリンクがあるが、もちろんこれは32bitOS向けのものである。
「x86 package」をx64のOSにインストールしようとしてもインストール自体がエラーになってできないので大事には至らないで済むけど、迷子になる子もいました。(ここに)


「Microsoft Drivers 3.0 for PHP for SQL Server」 + 「SQL Server 2008 R2 Native Client」または「Native Client」なし
could not find driver

えっと、ずいぶんシンプルになりましたね。誘導はしてくれないんですか。そうですか。

「Microsoft Drivers 3.0 for PHP for SQL Server」 + 「SQL Server 2012 Native Client」 で「Microsoft SQL Server 2000」に接続
SQLSTATE[08001]: [Microsoft][SQL Server Native Client 11.0]SQL Server Native Client 11.0 は、SQL Server 2000 以前のバージョンへの接続をサポートしていません。

ダメですか。そうですか。やっぱりダメですか。


というわけで

「Microsoft Drivers PHP for SQL Server」は 「PHP5.4 + SQL Server 2000」の組み合わせでは利用できません。
「PHP5.2 + SQL Server 2012」も同様です。
「SQL Server 2000」なんて未だに使っているところなんてほとんどないと思いますが。
まさかね・・・・・まさか・・・・ ぉぃゃm

2 件のコメント:

  1. この記事が大変参考になりました。
    ありがとうございました。

    ちなみに日本語カラム名は利用出来ないのでしょうか。

    foreach ($conn->query($sql) as $row)
    print($row['お客様管理番号']); //NG

    SQL文内にAS句で英文字カラム表現にしたので支障は
    ございませんが。

    foreach ($conn->query($sql) as $row)
    print($row['CustNum']); // OK Display


    参考までに教えて頂けませんでしょうか

    返信削除
    返信
    1. 拙ブログへのコメントありがとうございます。
      また参考になったとのことでうれしく思います。

      >ちなみに日本語カラム名は利用出来ないのでしょうか。

      「Microsoft Drivers PHP for SQL Server」を使った場合、日本語の列名はSJISまたはCP932(どちらなのかは未確認)のエンコードのままPHPに渡されてきます。(v2.0、v3.0どちらでも同様です。)
      これを必要な文字コードに変換してから使うなどすれば、利用できないことはありません。

      ----------------------------------------------------------
      $result = array();
      foreach ($conn->query($sql) as $key => $row) {
      foreach ($row as $column => $value) {
      $result[$key][mb_conver_encoding($column, 'UTF-8', 'SJIS')] = $value;
      }
      }
      foreach ($result as $row) {
      print($row['日本語列名']);
      }
      ----------------------------------------------------------

      もちろんコメントの通り「列名を英数として」取り出すほうが安全です。

      ちなみに私が使う場合は、基本的には両方実施するようにしています。
      これについては今度また別の記事を書こうと思います

      削除