【第10回】Azureで社内システム再現（オンプレ編）｜WebアプリとSQL Serverを連携する

## 概要

「Azureで社内システム再現（オンプレ編）」では、  
Azure の IaaS サービスを使って簡単な社内システムを再現します。

機能としては、社員番号を入力して検索ボタンを押すと、  
対応する名前を表示するだけのシンプルなものです。

※詳しい全体構成については、[【第0回】Azureで社内システム再現（オンプレ編）｜構成図と動作の流れ](https://qiita.com/saba_infra/items/a5e58ded68973e4551ee) で紹介しています。

---

## システム構成（今回の対象範囲）
![azure_onpre_joutai_web連携.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/a04a26d9-6413-4fc2-8879-ca2635ab0bfb.png)


今回は、WEB-VM1（IIS + PHP）から DB-VM1（SQL Server）に接続し、  
社員番号に対応する名前を検索・表示する機能を構築します。

PHPでSQL Serverに接続するために、以下の準備を行いました。

- PHPのインストール（バージョン 8.3.19）
- SQL Server用ドライバの導入（`php_sqlsrv_83_nts_x64.dll` など）
- `php.ini` の編集（拡張モジュールの有効化、エラーログの設定など）
- IISのアプリケーションプールの実行ユーザーを、  
  ドメイン内で権限を持つユーザー（例：`adminuser@domain.local`）に変更
- PHPスクリプトからSQL Serverへの接続確認、および検索機能の動作確認

---

## サンプルコードについて

本記事で使用しているPHPコードや設定ファイルは、以下のGitHubリポジトリに公開しています。

- GitHubリポジトリ：  
  https://github.com/saba-infra/employee-app-onpre

コード全体を確認したい方は、上記のリポジトリをご参照ください。

---
## PHPのインストール

PHPスクリプトを実行するためには、PHPの実行環境をあらかじめWebサーバにインストールしておく必要があります。  
今回は、バックエンドにPHPを使用する構成としたため、IIS上で動作可能なPHPランタイムを導入します。

公式サイトから Windows 用の PHP をダウンロードします。

- ダウンロードURL：  
  https://www.php.net/downloads.php

- 今回使用したバージョン：  
  **PHP 8.3.19 (x64 / Non Thread Safe)**


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/fcd4635e-80a9-4b49-baea-5728c6f963a0.png)
今回は `C:\PHP`に展開しました。

---

## SQL Server用ドライバの導入

PHPからSQL Serverに接続するためには、専用の拡張モジュール（ドライバ）を別途インストールする必要があります。  
今回は `sqlsrv` 拡張モジュールを使用するため、Microsoftが提供しているドライバを導入します。

以下のページから、自分の環境に合ったバージョンをダウンロードします。

- ダウンロードURL：  
  https://github.com/Microsoft/msphpsql/releases

---

PHPのバージョンが 8.3 のため、対応する「8.3」向けのDLLを含む ZIP ファイルを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/0bae534f-3cda-4d54-9e98-c279cb999fed.png)

ダウンロード後、ZIPファイルを解凍し、以下のファイルを `C:\PHP\ext` フォルダにコピーします。

- `php_sqlsrv_83_nts_x64.dll`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/c53ba8c0-bf3b-493e-8805-16adf332af30.png)

---

## php.ini の編集

ドライバを配置しただけでは、PHPはそれらを認識しません。  
`php.ini` ファイルに追記することで、拡張機能を有効にする必要があります。

`php.ini` は PHP の設定ファイルであり、実行時の挙動や使用するモジュール、エラーログの出力先などを制御します。

以下の場所にある `php.ini` を、メモ帳などで開いて編集します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/be8ca929-14dd-4703-8932-540d82b06d45.png)

---

追記した内容は以下の通りです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/3883b608-230c-415b-b87b-e841dd8b0d31.png)

### それぞれの設定項目について

- `extension_dir = "C:\PHP\ext"`  
  拡張モジュール（`.dll`ファイル）が格納されているディレクトリを指定する。

- `extension=php_sqlsrv_83_nts_x64.dll`  
  SQL Server への接続に必要な拡張モジュール。`sqlsrv_connect()` などの関数を使用可能にする。

- `extension=php_pdo_sqlsrv_83_nts_x64.dll`  
  PDO経由でSQL Serverに接続する際に必要となるモジュール。  
  ※今回は使用していないため、不要でした。実際の処理では `sqlsrv_connect()` のみを使用しました。

- `log_errors = On`  
  実行時エラーをログに出力する設定。

- `error_log = "C:/PHP/logs/php_errors.log"`  
  エラーログの出力先。存在しないパスを指定するとログ出力に失敗するため、事前にディレクトリを作成しておく。

---

## IISの設定（実行ユーザーの変更）

今回は、SQL Server との接続に **Windows認証** を使用しています。  
そのため、PHPスクリプトが実行される際に使用されるアカウントに、  
SQL Server へアクセス可能な十分な権限が必要となります。

IISのアプリケーションプールでは、既定で `ApplicationPoolIdentity` という仮想アカウントが使用されますが、  
このままではSQL Serverへの接続時に「権限不足」により失敗するケースがあります。

以下は、既定状態での実行ユーザーの設定画面です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/95ce9a66-df54-429e-8d89-5760cf7b0af8.png)

---

アプリケーションプールの実行ユーザーを、  
SQL Server にアクセス可能な権限を持つローカル管理者アカウントに変更しました。

以下は変更後の設定画面です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/d5d06fae-2da0-4cf0-a125-24948ed4e07c.png)

この設定により、PHPスクリプトが実行される際の実行主体が、  
SQL Server のアクセス権を持ったユーザーとなり、接続が正常に行えるようになります。

---

## 動作確認とエラー対応

設定が完了した後、実際に社員検索アプリへアクセスして動作確認を行いました。

---

### 接続失敗時の表示
SQL Serverへの接続に失敗しましたと表示されました。

>アプリケーションからSQL Serverへの接続が失敗した場合、  
画面上には以下のようなエラーメッセージが表示されるようにしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/cfb9f4cb-478b-40e9-adb2-3873a8479793.png)


---

### エラーログの確認

ログファイルを確認したところ、以下のようなメッセージが出力されていました。

```text
This extension requires the Microsoft ODBC Driver for SQL Server.
Access the following URL to download: https://go.microsoft.com/fwlink/?LinkId=163712
```

---

### ODBCとは
ODBC（Open Database Connectivity）は、アプリケーションとデータベースの間をつなぐ共通のインターフェースです。
PHPの sqlsrv 拡張モジュールも、実際には内部でODBCドライバを使用してSQL Serverと通信しています。

そのため、ODBCドライバがインストールされていない環境では、PHPからSQL Serverへの接続ができず、
上記のようなエラーが発生します。

### 対応内容
Microsoft公式から ODBC Driver for SQL Server（x64）をインストールすることで、接続が正常に行えるようになりました。

ダウンロードURL：
https://go.microsoft.com/fwlink/?LinkId=163712

![スクリーンショット 2025-03-31 10.20.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/4e1f833a-d545-4628-ac1a-55a1be0baf54.png)


---

## 接続エラー解消後の動作確認

ODBCドライバをインストール後、再度社員検索アプリの動作確認を行いました。

以下の2つのケースで、期待通りの挙動が確認できました。

---

### 1. 該当する社員が存在する場合

社員番号「1001」を入力し検索すると、  
対応する社員名が画面上に表示されました。

![スクリーンショット 2025-04-08 13.43.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/bbb66eca-ef31-4aaa-a3ea-c85039f5aa81.png)

---

### 2. 該当する社員が存在しない場合

存在しない社員番号（例：1200）を入力すると、  
「該当する社員が見つかりませんでした」と表示されました。

![スクリーンショット 2025-04-08 13.43.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/5d4f190c-7590-4a6d-95ca-5821e3847393.png)

---

いずれのケースでも、PHPスクリプトが正常にSQL Serverへ接続し、  
データベースからの応答に応じた処理結果を返していることが確認できました。