(Mac ARM) ODBCドライバーを利用してPHPでSnowflakeに接続する

# ODBCドライバーについて

Snowflakeへの接続方法としては下記の選択肢があります。

https://docs.snowflake.com/ja/developer-guide/php-pdo/php-pdo-driver

https://docs.snowflake.com/ja/developer-guide/odbc/odbc-mac

私がPHPでSnowflakeに接続しようとした当時（2023-04-13）は、M1 MacでPDOドライバーを利用するにはバグがり、M1 MacユーザーはODBCドライバーを使ってアクセスする必要がありました。
ただし、現在では[release 2.0.0からはARM Macにも対応しているとのこと](https://github.com/snowflakedb/pdo_snowflake/issues/308#issuecomment-1748833910)です！（まだ試していませんが）

ですので、通常はPHP　PDOドライバーを利用すれば良いと思いますが、本記事は備忘録として残したいと思います。


# ODBCドライバーでの接続例

💡 作業環境は以下のとおりです。
- チップ Apple M1
- macOS Ventura 13.3
- PHP8.1

## ODBCドライバーのインストール

### iODBCとODBCマネージャーのインストール

[Snowflakeのドキュメント](https://docs.snowflake.com/ja/user-guide/odbc-mac#iodbc)に従うとiODBCとODBCマネージャーをインストールすることになっています。

iODBCの方はもしかすると不要（使っていなそう）かもしれませんが、一応Snowflakeのドキュメントの手順に従ってインストールします。
また、ODBCマネージャーもインストールします。（こちらもなくても設定可能ですが、あったほうが設定しやすいです。）

### ODBCドライバーのインストール

ODBCドライバーをダウンロードする際には、下記過去記事に注意点記載しているので、自身のアーキテクチャに合わせたものをダウンロードしてください。

https://qiita.com/se_yataro/items/21a7fcac1adcbc6ddd6b


インストールはダウンロードしたpkgファイルをダイアログどおりに進めていけば良いです。

## ODBCドライバーの設定

ODBCマネージャーをインストールした場合、アプリのユーティリティからODBCマネージャーを起動します。

![ユーティリティ画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2930990/014d39da-1914-7de9-ea2b-52683387b07f.png)

ドライバタブからSnowflakeのドライバがインストールされていることを確認する。

![ODBC_Manager.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2930990/e5b3285c-a9ff-9b58-5c6c-8bcfe896bbf4.png)

システムDSNタブを開いてドライバの設定を行う。

追加をクリックして、表示されるダイアログで Snowflake のドライバを選択する。

下記の画面になるので各情報を入力する。

- server: Snowflakeのサーバー名
- uid: ユーザーネーム
- pwd: ログインパスワード
- roll: ロール
- warehouse: ウェアハウス

![設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2930990/174da64e-32f8-7540-3598-fbf4387f1d89.png)

設定が完了したら接続テストを行います。

ターミナルを起動して、下記のコマンドを実行します。（iODBC に付属の `iodbctest` コマンドラインユーティリティを使用したテスト）

`"/Library/Application Support/iODBC/bin/iodbctest"`

`SQL>`　が表示されれば接続完了です。

![macOS用_ODBC_ドライバーのインストールと構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2930990/82acfee8-1f17-17f3-0de8-441d16796b78.png)

## PHPが参照しているODBCを確認する

下記コマンドでPHPが参照しているODBCの状況を確認します。

`php -i | grep -i odbc`

下記の画像例だと、ODBCは有効化されており、unixODBCが使われていることが分かる。（iODBCをインストールしたけれど、unixODBCを使っているようです（？））

![odbcの確認.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2930990/d7fd665e-9472-b3ef-3c2c-f3bd78b24349.png)


unixODBCの情報を下記のコマンドで確認します。

`odbcinst -j`

下記画像例でいくと、
DRIVERS（ドライバーの情報を設定しているファイル）はhomebrewのフォルダ内にある。
SYSTEM DATA SOURCES（システムDSN設定）もhomebrewの中にある。
→つまり、ODBCマネージャーを使って作成したiniファイルを参照しておらず、homebrew内のiniファイルを参照している事がわかる。
※ODBCマネージャーを使用して作成したiniファイルは `/Library/ODBC/odbc.ini` にある。

![unixodbc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2930990/629bf33f-78a1-a43b-377b-b0e07cfee26a.png)

## ODBCマネージャーで作成したodbc.iniとodbcinst.iniファイルを上記で確認したフォルダ内のiniファイルに上書きする

![設定上書き.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2930990/07211d31-4a98-b761-60e7-b4079623773b.png)


## PHPからの接続テスト

下記のコードを参考に接続テストをします。
※`odbc_connect()`関数ではuser名とパスワードが引数として必須（？）のようで、iniファイルで設定しているものの、こちらでも入力している。
※下記のコードではtestdbというテスト用のデータベースを作ってある場合のクエリになっています。

```php
<?php
// ODBCデータソース名
$dsn = 'snowflake';

// ユーザー名とパスワード
$user = 'ユーザーネーム';
$password = 'パスワード';

// SnowflakeへのODBC接続を確立する
$conn = odbc_connect($dsn, $user, $password);

if ($conn) {
  echo "ODBC connection successful!\n";
} else {
  echo "ODBC connection failed!\n";
}

// $tables = odbc_tables($conn);
// while (($row = odbc_fetch_array($tables))) {
//     print_r($row);
//     break; // further rows omitted for brevity
// }

// ロールやウェアハウス、テーブルなど変更可能
// odbc_exec($conn, "use role accountadmin");
// odbc_exec($conn, "use warehouse compute_wh");
// odbc_exec($conn, "use citibike");


// クエリを実行する testｄｂ用
$query = "SELECT * FROM testschema.test_table";
$result = odbc_exec($conn, $query);

// 結果を出力する
while ($row = odbc_fetch_array($result)) {
    echo $row['COL1'] . " " . $row['COL2'] . "\n";
}

// ODBC接続を切断する
odbc_close($conn);
echo "connection closed!";
?>
```

上記コードによる出力結果

![odbc_test_php.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2930990/8f2aa761-0345-301d-ab6f-4a99cdd12c3a.png)

以上で接続完了です！