CakeFest 2024: The Official CakePHP Conference

ODBC および DB2 関数 (PDO_ODBC)

はじめに

PDO_ODBC は PHP Data Objects (PDO) インターフェイスを実装したドライバで、 PHP から ODBC ドライバあるいは IBM DB2 Call Level Interface (DB2 CLI) ライブラリを使用した データベースへのアクセスが可能となります。 PDO_ODBC は、現在 3 種類のデータベースドライバをサポートしています。

ibm-db2

フリーの DB2 express-C クライアントを使用した、 IBM DB2 Universal Database、Cloudscape および Apache Derby サーバーへのアクセスをサポートします。

unixODBC

unixODBC ドライバマネージャおよびデータベースごとの ODBC ドライバを使用した、データベースサーバーへのアクセスをサポートします。

generic

PDO_ODBC が明示的にサポートしていない ODBC ドライバマネージャのためのコンパイルオプションを提供します。

Windows では、php_pdo_odbc.dll を拡張モジュールとして php.ini で有効にする必要があります。 これは Windows ODBC ドライバマネージャに対してリンクされており、 システムの DSN に登録されているあらゆるデータベースに対して PHP から接続することができます。

インストール手順

UNIX システムでの PDO_ODBC
  1. PDO_ODBC は PHP ソースの中に含まれています。 PDO_ODBC 拡張モジュールを静的モジュールあるいは共有モジュールとして コンパイルするには次のような configure コマンドを実行します。

    ibm_db2

    ./configure --with-pdo-odbc=ibm-db2,/opt/IBM/db2/V8.1/
    
    PDO_ODBC を ibm-db2 形式でビルドするには、PDO_ODBC をコンパイルするのと同じマシンに DB2 アプリケーション開発用ヘッダが インストールされていなければなりません。DB2 アプリケーション開発ヘッダは DB2 サーバーのインストールオプションに 含まれており、また IBM developerWorks の » Web サイト からフリーでダウンロードできる DB2 Application Development Client にも含まれています。

    configure コマンドに DB2 ライブラリおよび ヘッダの場所を指定しなかった場合は、PDO_ODBC はデフォルトとして /home/db2inst1/sqllib を使用します。

    unixODBC

    ./configure --with-pdo-odbc=unixODBC,/usr/local
    
    configure コマンドに unixODBC ライブラリおよび ヘッダの場所を指定しなかった場合は、PDO_ODBC はデフォルトとして /usr/local を使用します。

    generic
    ./configure --with-pdo-odbc=generic,/usr/local,libname,ldflags,cflags
    

定義済み定数

このドライバでは以下の定数が定義されて います。これは拡張モジュールが PHP に組み込まれているか、実行時に動的にロード されている場合のみ使用可能です。さらに、これらのドライバ固有の定数は そのドライバを使用している場合にのみ使用されます。 あるドライバ固有の属性を別のドライバで使うと、予期せぬ結果を引き起こします。 もし複数のドライバを使用しているコードを実行している場合、 PDO::getAttribute()PDO::ATTR_DRIVER_NAME 属性を使用することで、使用中のドライバ名を調べることが可能です。

PDO_ODBC_TYPE (string)

PDO::ODBC_ATTR_USE_CURSOR_LIBRARY (int)

このオプションは、ODBC のカーソルライブラリが使うかを制御します。 ODBC カーソルライブラリは、ドライバが実装していない高度なODBCの機能 (例: スクロール可能なブロックカーソル) をいくつかサポートします。 サポートしている値は以下の通りです:

  • PDO::ODBC_SQL_USE_IF_NEEDED (デフォルト): ODBC カーソルライブラリを必要な時に使います。

  • PDO::ODBC_SQL_USE_DRIVER: ODBC カーソルライブラリを使いません。

  • PDO::ODBC_SQL_USE_ODBC: ODBC カーソルライブラリを常に使います。

PDO::ODBC_ATTR_ASSUME_UTF8 (bool)

Windows のみ有効です。 true の場合、UTF-16 でエンコードされた文字データ( CHAR, VARCHAR, LONGVARCHAR) を データベースから読み取ったり、書き込んだりする際に UTF-8 に変換します。 false の場合(デフォルト)、 エンコーディングの変換はドライバが行う可能性があります。

実行時設定

php.ini の設定により動作が変化します。

PDO_ODBC 設定オプション
名前 デフォルト 変更可能 変更履歴
pdo_odbc.connection_pooling "strict" INI_ALL  
pdo_odbc.db2_instance_name NULL INI_SYSTEM この非推奨の機能は、きっと 将来 削除 されるでしょう。
INI_* モードの詳細および定義については どこで設定を行うのか を参照してください。

以下に設定ディレクティブに関する 簡単な説明を示します。

pdo_odbc.connection_pooling string

ODBC 接続のプール方法を指定します。"strict""relaxed" あるいは "off" ("" と同じ) のいずれかです。このパラメータは、 プールされている既存の接続との比較をどの程度厳密に行うのかを 接続マネージャに指定します。 strict は推奨されているデフォルト設定で、 接続パラメータが完全に一致する場合にのみ既存の接続を使用します。 relaxed は、接続パラメータが似ている場合に 既存の接続を使用します。これはキャッシュの再利用率を高めますが、 (例えば) 仮想ホスト間での接続情報がおかしくなってしまう恐れがあります。

この設定は php.ini ファイルでのみ変更可能で、 その内容はプロセス全体に影響します。同じ ODBC ライブラリを使用している すべてのモジュール、たとえば Unified ODBC 拡張モジュール などが影響を受けます。

警告

relaxed を共有サーバーで使用してはいけません。 これはセキュリティの問題があるためです。

ヒント

どうしても変更する必要がない限り、この設定はデフォルトの strict のままにしておきましょう。

pdo_odbc.db2_instance_name string

db2 方式で PDO_ODBC をコンパイルした場合、 Linux および UNIX 上で DB2 インスタンスを指定するための環境変数 DB2INSTANCE の値を設定します。これによって PDO_ODBC が DB2 ライブラリの場所を見つけられるようになり、 DB2 データベースへのカタログ接続が可能になります。

この設定は php.ini ファイルでのみ変更可能で、 その内容はプロセス全体に影響します。同じ ODBC ライブラリを使用している すべてのモジュール、たとえば Unified ODBC 拡張モジュール などが影響を受けます。

この設定は、Windows 上では何の意味も持ちません。

目次

  • PDO_ODBC DSN — ODBC あるいは DB2 データベースに接続する
add a note

User Contributed Notes 5 notes

up
10
ChristianF
8 years ago
I just spent a couple of hours trying to track down the Exception "Could not find driver". This was despite having ODBC and PDO_ODBC installed, and all of the configuration seemed to be correct.

Turned out the problem was that I used ODBC in upper-case in the dsn. As soon as I changed the dns to "odbc:database" it worked.

As this code used to work a few months ago, this sudden case-sensitivity threw me for a loop. So in case you get this error, check the casing first.
up
5
tuomas
14 years ago
If you want to avoid installing DB2 Connect and/or PECL modules ibm_db2 and PDO_IBM, you can also use IBM DB2 databases trough unixODBC.

If you have DB2 database on a i server you need to install IBM iAccess (http://www.ibm.com/systems/i/software/access/linux/index.html) and unixODBC. Just install the libraries (rpm) and modify configurations in /etc/odbcinst.ini (sample configuration in /opt/ibm/iSeriesAccess/unixodbcregistration) and /etc/odbc.ini.

To my experience this is much easier way than installing DB2 Connect.
up
5
ethan dot nelson at ltd dot org
16 years ago
Using SQL 2005, PDO_ODBC and datetime fields is a royal pain. MSDN documentation on CAST CONVERT shows that there is supposed to be an implicit convert between character types and datetime types. That's true... until you put it in a stored procedure and use variable declarations.

For instance this fails:

declare @date varchar;
SET @date = '20080101';
SELECT cast(@date AS datetime) AS poo

While this succeeds:
declare @date varchar(19);
SET @date = '20080101';
SELECT cast(@date AS datetime) AS poo

The PDO Driver appears to attempt an implicit conversion and so it fails whenever you try to insert data into datetime column types.

So to workaround this nuance in SQL, declare a character column type with explicit width. Then your implicit type conversion will work.
up
1
Ariz Jacinto
12 years ago
Using SQL Server Native Client 11.0 on Linux as a PDO_ODBC driver:

Download the SQL Server Native Client 11.0 on Linux ODBC Driver:
http://www.microsoft.com/download/en/details.aspx?id=28160

Configuration ODBC:

/usr/local/etc/odbcsys.ini
--
[SQL Server Native Client 11.0]
Description = Microsoft SQL Server ODBC Driver V1.0 for Linux
Driver = /opt/microsoft/sqlncli/lib64/libsqlncli-11.0.so.1720.0
UsageCount = 1

/usr/local/etc/odbc.ini
--
[MSSQLServer]
Driver = SQL Server Native Client 11.0
Description = Sample Database
Trace = Yes
Server =
Port = 1433
Database =

Test the connection:
mssqltest.php
--
<?php
putenv
('ODBCSYSINI=/usr/local/etc');
putenv('ODBCINI=/usr/local/etc/odbc.ini');
$username = "";
$password = "";
try {
$dbh = new PDO("odbc:MSSQLServer",
"$username",
"$password"
);
} catch (
PDOException $exception) {
echo
$exception->getMessage();
exit;
}
echo
var_dump($dbh);
unset(
$dbh);
?>
up
-1
harry dot forum at p-boss dot com
13 years ago
MSSQL - PHP on Apache - Linux Redhat

When using php 5.2.10 please beaware of this error:

http://bugs.php.net/bug.php?id=42068

Standard odbc_connect will not work, you must use pdo_odbc

Connecting to MSSQL using pdo odbc - walkthrough..

1. Download and configure FreeTDS with-unixodbc

./configure --prefix=/opt/SYSfreetds --with-unixodbc

make;make test; make install

2. install php-odbc and unixODBC

php-odbc-5.2.10-1.x86_64.rpm
unixODBC.x86_64.x86x64

3. Setup ODBC links

a)
Create a tds.driver file with the following contents

[FreeTDS]
Description = v0.63 with protocol v8.0
Driver = /opt/SYSfreetds/lib/libtdsodbc.so

Register the ODBC driver - the tds.driver file

odbcinst -i -d -f tds.driver

b)
Creating a tds.datasource file - ODBC Data Source with contents:

[SOURCENAME]
Driver=FreeTDS
Description=Test MS SQL Database with FreeTDS
Trace=No
Server=BobTheServer
Port=1433
TDS Version=8.0
Database=youDBname

Register the ODBC data source

odbcinst -i -s -f tds.datasource

Beware that the odbc.ini file will be installed in the current users home directory. This may need to be used if you are using a webserver as the apache home directory could be different.

Ensure .odbc.ini is in apaches home directory, possibly "/var/www"

4. Test the ODBC link on the command line

isql -v SOURCENAME 'username' 'password'

+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+
SQL>

5. Edit /etc/php.ini

Make sure the following is set:
mssql.secure_connection = On


6. Restart apache gracefully

7. PHP to run:

<?
$dbh= new PDO('odbc:SOURCENAME', 'username', 'password');
$stmt = $dbh->prepare("$query");
$stmt->execute();
while ($row = $stmt->fetch()) {
print_r($row);
}
unset($dbh); unset($stmt);
?>

Trouble-shooting:

Please try strace/ truss if you encounter issues. It could be you are referencing wrong libraries somewhere.

Ensure you have restarted apache once the odbc files are in place
To Top