setup IIS + PHP + Oracle


Outline

今回、windows server上でOracleに接続するWEBアプリを作る機会がありました。
Oracleに接続するにあたり、多少設定などに苦労したことがあるため、自分の構築メモふくめて、手順を残しておく

Environment

Item Version Memo
OS Windows Server 2019 Standard
DB Oracle 12.1.0.2.0
PHP 7.4.14 (32bit)
Instant Client 19.8.0.0.0

Instant Client

Download

ここから、Basicパッケージをdownloadする

なお、bit数(x86=32bit)は後述するPHPのbit数と合わせる必要がある

今回、Microsoft Windows 32ビット用 19.8.0.0.0 を使用した

Setup

zipを解凍後、C:\instantclientに配置した

PHP setup

Download

ここから、環境等に合わせて、phpをdownloadする
今回、stable、performanceを考慮して、VC15 x86 Non Thread Safe (2021-Jan-05 18:10:14)を使用した。

set file

zipファイルを解凍し、任意のパスに置く
今回は "C:\php"に配置した

iniの設定

php.ini-development もしくは php.ini-productionを php.iniに変更orコピーする
IIS環境が、開発向けか公開向けかによってどっちのtemplateを使用するか決める。
今回、社内向けツールのため、DEBUGのしやすさを考慮してphp.ini-developmentを用いた

php.iniを開き、必要個所を編集する

extensionのpathの設定

extension_dir がdefaultコメントアウトされている。
こちらを有効にし、適切なパスを設定する

oracle系のextension

oci8_12c , pdo_oci が oci_connection等、oracle DBに接続するためのextension
こちらを、有効にする

Instant Client dll 配置

先ほど設定した、instant clientのC:\instantclient 配下にある、dllを"C:\php"以下にコピーする

その後、extensionが正しく稼働するかをコマンドで確認する。
oci8 , PDO_OCIがmodule listに表示され、かつエラーが表示されないことを確認する。
ただしくdllが読み込まれないと、エラーが表示される

php.exe -m

IIS setup

Add Role in Server Manager

Server Managerを起動し、"Add roles and features" を選択する

Server Rolesにて、Web Server(IIS)を選択する

Role Servicesにて、CGIを少なくとも追加する。
それ以外に、ASP等必要に応じて追加する

Configration

IIS Managerを起動する
対象のserverを選択し、"Handler Mapping"を選択する

Add Module Mappingを選択し、PHPの定義を追加する

※ Module にてFastCgiModuleが表示されない場合、Server Roleの Role Servicesで CGIを追加していない可能性がある。改めて、Server Roleの設定を見直す必要がある

PHP 動作確認
下記、phpinfo.phpを作成し、IISのroot directoryに配置する (Default C:\inetpub\wwwroot)
そして、アクセスして確認する

<?php
phpinfo();
?>

動作確認例

Oracle 接続サンプルphp

今回、tnsnames.oraを直接phpに記載した例。

oracleの環境によって$ORAの必要項目はことなるため、カスタマイズする必要がある。
今回、SERVER、INSTANCE_NAMEに関して設定が不要のため、コメントアウトしている。

<?php

    $dbhost = "oracle-host";
    $dbport = "1521";
    $dbname = "dbname";

    $user = 'USER-NAME';
    $pass = 'PASSWORD';

    $ORA = "(DESCRIPTION= "
         ." (ADDRESS=(PROTOCOL=tcp)(HOST=$dbhost)(PORT=$dbport)) "
         ."  (CONNECT_DATA= "
         ." (SERVICE_NAME=$dbname) "
//         ." (SERVER=server) "
//         ." (INSTANCE_NAME=instance_name)"
         ." )) "
         ;

    $conn = oci_connect($user, $pass, $ORA );

    if (!$conn) {
        $e = oci_error();
        trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
    }

    $stid = oci_parse($conn, "SELECT * FROM XXX WHERE ID = '12345' ");
    oci_execute($stid);


    echo "<table border='1'>\n";
    while ($row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS)) {
        echo "<tr>\n";
        foreach ($row as $item) {
            echo "    <td>" . ($item !== null ? htmlentities($item, ENT_QUOTES) : "&nbsp;") . "</td>\n";
        }
        echo "</tr>\n";
    }
    echo "</table>\n";

?>