PHPでOracle Autonomous Databaseにネットワーク経由で接続してみた

Database

こんにちは、先日の記事ではOracle Cloudで作成したVMインスタンスからOracle Autonomous Databaseに接続しました。今日はPHPを使いネットワーク経由でOCIから作成したOracle Databaseに接続しデータを取り出し表示してみたいと思います。(実はこの記事は昨日上げる予定でしたが、php接続にてこずってしまい今日になりました)

本記事は、30日毎日投稿するチャレンジの7日目の記事です。チャレンジ期間内にWebアプリを作成しますが、いまだ構想段階なのでそろそろ形にしていきたいと思います。

PHPとOracle Databaseの下準備・つまずき

先日の記事でOracle Instant ClientとOCI8のインストールは完了しています。また、同記事でSQLPlusを使用してデータベース接続を確認しました。

しかし…

PHPを記述したファイルを公開ディレクトリに保存しても読み込みがされず、”データベースに接続できません”というエラーが出てしまいました。SQLPlusにて接続を確認しているので、Instant Clientは正常に動作しているし、oci8の入れ直し、PHPに関連するライブラリやモジュールの見直しをしましたが、全く解決されませんでした

一日トライアンドエラーを繰り返しても解決しませんでしたが、夜なんとなくネットの記事を見ていると。どうやらSELinuxが悪さをしているようだ…と

SELinuxと検索すると、非常にたくさんの記事が出てきます。しかもそのほとんどが、無効化の方法や起動しないなどといったものでした。SELinuxとはアクセス制御を行い、セキュリティ機能を強化するもの“だそうです、確かに公開ディレクトリのファイルにアクセスできなかった…

SELinuxのログはausearchコマンドで確認できるようです。以下のようなログがありました。

[opc@miyacle-vm ~]$ sudo ausearch -m avc

type=AVC msg=audit(1587048778.755:113524): avc:  denied  { name_connect } for  pid=23662 comm="httpd" dest=1522 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket permissive=0

name_connectがdeniedとなっています。データベースに接続できなかったのはここが原因だったのですね。何か問題が起きたら、エラーとログを確認する癖をつけるようにします。

では何が悪かったのか、どこを直せば良かったのかということですが、

Apacheで動作するHTTPモジュールから外部への通信が無効化されていたようです(参考)。これを有効化してあげることで無事に通信がされ、データベースに接続されます。実行したのは以下のコマンドです。

sudo setsebool -P httpd_can_network_connect on

ここまで辿りつくのにかなり時間をかけてしまいましたが、これでPHP-データベースへの接続が可能となりました。ついでにhtml内でphpが動くようにhttp.confに以下を追加しました。

AddType application/x-httpd-php .html

PHPを書いてみる・公開

やっと下準備が整いましたので、PHPを書いてOracle Databaseに接続・データ表示を行なってみます。(実際は先にPHPを書いて、vmインスタンス上にあげてから接続エラーになっているので本記事の流れとは逆です)

OCI8関数を用いて接続します。過去記事で、Oracle Databaseにネットワーク経由で接続したので、資格証明ウォレットの配置や接続記述子は準備できています。

データベースへの接続はoci_connect()を使用し、oci_parse()でステートメントを作成、oci_execute()で実行します。すでにデータベースに登録されているemployeesテーブルをSELECTしてみます。SQL文を記述する際は「;」をSLQ文末に付けないようです。

$c = oci_connect('DBユーザー名', 'パスワード ', '接続記述子');
$s = oci_parse($c, "SELECT * FROM employees");
$r = oci_execute($s);

実行したSQLの結果をhtmlのテーブルに表示してみます。oci_fetch_array()でSQL結果を連想配列として受け取ります。modeと呼ばれる引数には連想配列を返すOCI_ASSOCとNULL値を扱う、OCI_RETURN_NULLSを使用します(参考)。

while文でフェッチした連想配列が変数に入る限りループが続きます。foreach文でそれぞれの列を表示します。null値を扱うので、nullの箇所には”null”と表示させます。こちらを参考にさせていただきました。

echo "<table border='1'>n";
echo "<tr><th>empno</th><th>name</th><th>salary</th><th>comm</th><th>hiredate</th><th>manager</th><th>dept_id</th></tr>";

while ($row = oci_fetch_array($s, OCI_ASSOC+OCI_RETURN_NULLS)) {
 echo "<tr>n";
 foreach ($row as $item) {
 	echo " <td>" . ($item !== null ? htmlentities($item, ENT_QUOTES) : "null") . "</td>n";
 	}
 echo "</tr>n";
}

echo "</table>n";

これを公開ディレクトリ内に保存して、割り当てられたパブリックIPアドレスにアクセスすると…

VMインスタンスにアクセス

表示された!!

すごく嬉しいです、これでやっとスタートラインに立つことができたのですが、何かすごく達成感があります笑

これでひとまず安心です。

*こちらのQiitaの記事でSELinuxに気づくことができ、ここまで来られました。ありがとうございます。

おわりに

今日は昨日つまずいてしまい投稿できなかったPHPとOracle Databaseの接続そしてweb上で表示を行いました。

エラーが出てしまい解決できないと、すごく不安になったり焦りが出たりしてしまうのですが、これを解決したときは非常に感動します。

プログラムの面白さは、”自分で書いたコード、プログラムが正常に動く”ことの気持ちよさにあると思います。引き続き頑張りたいと思います。

本日も最後まで見ていただきありがとうございました。

コメント

タイトルとURLをコピーしました