CentOSのサーバ立ててPHPからOracleに接続するまでにやったこと
LinuxでとかWindowsでとかPHPからOracleに接続する環境を構築するために、
なんかバラバラと役に立つ記事はあったけど一つにまとまった記事がなかったのでないなら作ってしまえと思い立ち、ブログを書こうと思いました。
2016年11月ごろに作った環境です。Oracleとか最新のバージョンとか出てて食い違う部分あるかもしれないですが、そこは柔軟に対応してください。
ずっと下書きで眠ってたのを公開したのでちょい古いです。
CentOSとApacheのインストールは完了している前提で話を進めます。
前提条件
- CentOS6.8 64bit
- Apache2.2
- PHP5.5
- Oracle12.1.0.2.0-1
上記のバージョンの組み合わせで構築した際のログです。
読まれてる方によって微妙に違う箇所があると思いますが柔軟に対応してください。
Table of Contents
Toggle1.Oracle Instant Clientのインストール
Instant Client Downloads for Linux x86-64から必要なファイルを取得。
- oracle-instantclient12.1-basic-12.1.0.2.0-1.x86_64.rpm
- oracle-instantclient12.1-devel-12.1.0.2.0-1.x86_64.rpm
sqlplusが必要ならsqlplusも
/usr/local/src/上にダウンロードしたファイルを移動させといて、カレントディレクトリ変更
cd /usr/local/src/
インストール
rpm -ivh oracle-instantclient12.1-*.rpm
確認
rpm -qa | grep oracle
tnsnames.oraを作成 ※「HOST」、「PORT」、「SID」については、環境に合わせてください。
mkdir -p /usr/lib/oracle/12.1/client64/network/admin
vi /usr/lib/oracle/12.1/client64/network/admin/tnsnames.ora
ORCL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = Oracleサーバのアドレス)(PORT = 1521))
(CONNECT_DATA =
(SID = orcl)
)
)
権限の変更
chmod 644 /usr/lib/oracle/11.2/client/network/admin/tnsnames.ora
環境変数追加→/etc/profileの最後に以下4行を追加。
vi /etc/profile
export ORACLE_HOME=/usr/lib/oracle/12.1/client64/lib
export NLS_LANG=Japanese_Japan.AL32UTF8
export LD_LIBRARY_PATH=$ORACLE_HOME:$LD_LIBRARY_PATH
export PATH=$ORACLE_HOME:$PATH
2.php-oci8のインストール
最初、PHPでOracleを使う為に必要な5つのことを参考に進めていた。
1.Oracle InstantClientの導入
2.php-oci8のインストール
3.環境変数の設定
4.DB名はグローバルデータベース名
5.めげない気持ち
しかし、2でどうしてもエラーが出る。。めげそう。。。
ということで基本に立ち返ってOracleのページを参考にすることに
Installing PHP and the Oracle Instant Client for Linux and Windows
PHP5.5インストール
最初、PHP5.3をyumで適当にインストールしてたので、
php5.3.3アンインストール→Remiパッケージからphp5.5をインストール(手順はphp5.5とかphp5.6をインストールするを参考にさせてもらいました。)
OCI8インストール
pecl install oci8-2.0.8
↑バージョン指定しないとPHPとの整合性でエラー出る
途中で
instantclient,/usr/lib/oracle/12.1/client64/lib
を入力します
downloading oci8-2.0.8.tgz ...
Starting to download oci8-2.0.8.tgz (190,854 bytes)
.........................................done: 190,854 bytes
11 source files, building
running: phpize
Configuring for:
PHP Api Version: 20121113
Zend Module Api No: 20121212
Zend Extension Api No: 220121212
Please provide the path to the ORACLE_HOME directory. Use 'instantclient,/path/to/instant/client/lib' if you're compiling with Oracle Instant Client [autodetect] :
instantclient,/usr/lib/oracle/12.1/client64/lib←途中で入力(中略)
See any operating system documentation about shared libraries for more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------Build complete.
Don't forget to run 'make test'.running: make INSTALL_ROOT="/var/tmp/pear-build-root3gXC7i/install-oci8-2.0.8" install
Installing shared extensions: /var/tmp/pear-build-root3gXC7i/install-oci8-2.0.8/usr/lib64/php/modules/
running: find "/var/tmp/pear-build-root3gXC7i/install-oci8-2.0.8" | xargs ls -dils
1047547 4 drwxr-xr-x 3 root root 4096 11月 15 15:39 2016 /var/tmp/pear-build-root3gXC7i/install-oci8-2.0.8
132624 4 drwxr-xr-x 3 root root 4096 11月 15 15:39 2016 /var/tmp/pear-build-root3gXC7i/install-oci8-2.0.8/usr
132625 4 drwxr-xr-x 3 root root 4096 11月 15 15:39 2016 /var/tmp/pear-build-root3gXC7i/install-oci8-2.0.8/usr/lib64
132626 4 drwxr-xr-x 3 root root 4096 11月 15 15:39 2016 /var/tmp/pear-build-root3gXC7i/install-oci8-2.0.8/usr/lib64/php
132627 4 drwxr-xr-x 2 root root 4096 11月 15 15:39 2016 /var/tmp/pear-build-root3gXC7i/install-oci8-2.0.8/usr/lib64/php/modules
132623 492 -rwxr-xr-x 1 root root 500755 11月 15 15:39 2016 /var/tmp/pear-build-root3gXC7i/install-oci8-2.0.8/usr/lib64/php/modules/oci8.soBuild process completed successfully
Installing '/usr/lib64/php/modules/oci8.so'
install ok: channel://pecl.php.net/oci8-2.0.8
configuration option "php_ini" is not set to php.ini location
You should add "extension=oci8.so" to php.ini
その後php.iniにextension=oci8.so追加
vi /etc/php.ini
extension=oci8.so
pdo_ociインストール
ここが難関だった。。
pecl install pdo_oci
WARNING: "pear/PDO_OCI" is deprecated in favor of "channel://http://www.php.net/pdo_oci/ext/pdo_oci"
downloading PDO_OCI-1.0.tgz ...
Starting to download PDO_OCI-1.0.tgz (13,679 bytes)
.....done: 13,679 bytes
7 source files, building
running: phpize
Cannot find config.m4.
Make sure that you run '/usr/bin/phpize' in the top level source directory of the moduleERROR: `phpize' failed
普通にやったら失敗する。。。
CentOS:PHPからOracleを使えるようにするを参考にして
wget https://pecl.php.net/get/PDO_OCI-1.0.tgz
tar xzf PDO_OCI-1.0.tgz
cd PDO_OCI-1.0
config.m4を修正
どうやらOracle12cには対応していないようなので頑張って修正。config.m4をそのまま載せときます。
このまま動くかどうかは保証してませんので、元ファイルのバックアップを取りつつ、エラーが出たら逐次対処してください。
dnl $Id: config.m4,v 1.14.2.1 2005/09/24 23:23:24 sniper Exp $
if test "$PHP_PDO" != "no"; then
AC_DEFUN([AC_PDO_OCI_VERSION],[
AC_MSG_CHECKING([Oracle version])
if test -s "$PDO_OCI_DIR/orainst/unix.rgs"; then
PDO_OCI_VERSION=`grep '"ocommon"' $PDO_OCI_DIR/orainst/unix.rgs | sed 's/[ ][ ]*/:/g' | cut -d: -f 6 | cut -c 2-4`
test -z "$PDO_OCI_VERSION" && PDO_OCI_VERSION=7.3
elif test -f $PDO_OCI_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME.12.1; then
PDO_OCI_VERSION=12.1
elif test -f $PDO_OCI_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME.11.2; then
PDO_OCI_VERSION=11.2
elif test -f $PDO_OCI_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME.10.1; then
PDO_OCI_VERSION=10.1
elif test -f $PDO_OCI_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME.9.0; then
PDO_OCI_VERSION=9.0
elif test -f $PDO_OCI_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME.8.0; then
PDO_OCI_VERSION=8.1
elif test -f $PDO_OCI_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME.1.0; then
PDO_OCI_VERSION=8.0
elif test -f $PDO_OCI_DIR/lib/libclntsh.a; then
if test -f $PDO_OCI_DIR/lib/libcore4.a; then
PDO_OCI_VERSION=8.0
else
PDO_OCI_VERSION=8.1
fi
else
AC_MSG_ERROR(Oracle-OCI needed libraries not found under $PDO_OCI_DIR)
fi
AC_MSG_RESULT($PDO_OCI_VERSION)
])
PHP_ARG_WITH(pdo-oci, Oracle OCI support for PDO,
[ --with-pdo-oci[=DIR] PDO: Oracle-OCI support. Default DIR is ORACLE_HOME.
You may also use --with-pdo-oci=instantclient,prefix,version to use
the InstantClient SDK. For Linux with 10.1.0.3 rpms (for example) use:
--with-pdo-oci=instantclient,/usr,10.1.0.3])
if test "$PHP_PDO_OCI" != "no"; then
AC_MSG_CHECKING([Oracle Install-Dir])
if test "$PHP_PDO_OCI" = "yes" -o -z "$PHP_PDO_OCI"; then
PDO_OCI_DIR=$ORACLE_HOME
else
PDO_OCI_DIR=$PHP_PDO_OCI
fi
AC_MSG_RESULT($PDO_OCI_DIR :$PHP_PDO_OCI:)
AC_MSG_CHECKING([if that is sane])
if test -z "$PDO_OCI_DIR"; then
AC_MSG_ERROR([You need to tell me where to find your oracle SDK, or set ORACLE_HOME.])
else
AC_MSG_RESULT([yes])
fi
if test "instantclient" = "`echo $PDO_OCI_DIR | cut -d, -f1`" ; then
PDO_OCI_IC_PREFIX="`echo $PDO_OCI_DIR | cut -d, -f2`"
PDO_OCI_IC_VERS="`echo $PDO_OCI_DIR | cut -d, -f3`"
AC_MSG_CHECKING([for oci.h])
if test -f $PDO_OCI_IC_PREFIX/include/oracle/$PDO_OCI_IC_VERS/client/oci.h ; then
PHP_ADD_INCLUDE($PDO_OCI_IC_PREFIX/include/oracle/$PDO_OCI_IC_VERS/client)
PDO_OCI_LIB_DIR="$PDO_OCI_IC_PREFIX/lib/oracle/$PDO_OCI_IC_VERS/client/lib"
AC_MSG_RESULT($PDO_OCI_IC_PREFIX/include/oracle/$PDO_OCI_IC_VERS/client)
elif test -f $PDO_OCI_IC_PREFIX/lib/oracle/$PDO_OCI_IC_VERS/client/include/oci.h ; then
PHP_ADD_INCLUDE($PDO_OCI_IC_PREFIX/lib/oracle/$PDO_OCI_IC_VERS/client/include)
PDO_OCI_LIB_DIR="$PDO_OCI_IC_PREFIX/lib/oracle/$PDO_OCI_IC_VERS/client/lib"
AC_MSG_RESULT($PDO_OCI_IC_PREFIX/lib/oracle/$PDO_OCI_IC_VERS/client/include)
elif test -f $PDO_OCI_IC_PREFIX/sdk/include/oci.h ; then
PHP_ADD_INCLUDE($PDO_OCI_IC_PREFIX/sdk/include)
AC_MSG_RESULT($PDO_OCI_IC_PREFIX/sdk/include)
PDO_OCI_LIB_DIR="$PDO_OCI_IC_PREFIX"
else
AC_MSG_ERROR([I'm too dumb to figure out where the include dir is in your instant client install])
fi
PDO_OCI_VERSION="`echo $PDO_OCI_IC_VERS | cut -d. -f1-2`"
else
if test -d "$PDO_OCI_DIR/rdbms/public"; then
PHP_ADD_INCLUDE($PDO_OCI_DIR/rdbms/public)
PDO_OCI_INCLUDES="$PDO_OCI_INCLUDES -I$PDO_OCI_DIR/rdbms/public"
fi
if test -d "$PDO_OCI_DIR/rdbms/demo"; then
PHP_ADD_INCLUDE($PDO_OCI_DIR/rdbms/demo)
PDO_OCI_INCLUDES="$PDO_OCI_INCLUDES -I$PDO_OCI_DIR/rdbms/demo"
fi
if test -d "$PDO_OCI_DIR/network/public"; then
PHP_ADD_INCLUDE($PDO_OCI_DIR/network/public)
PDO_OCI_INCLUDES="$PDO_OCI_INCLUDES -I$PDO_OCI_DIR/network/public"
fi
if test -d "$PDO_OCI_DIR/plsql/public"; then
PHP_ADD_INCLUDE($PDO_OCI_DIR/plsql/public)
PDO_OCI_INCLUDES="$PDO_OCI_INCLUDES -I$PDO_OCI_DIR/plsql/public"
fi
if test -d "$PDO_OCI_DIR/include"; then
PHP_ADD_INCLUDE($PDO_OCI_DIR/include)
PDO_OCI_INCLUDES="$PDO_OCI_INCLUDES -I$PDO_OCI_DIR/include"
fi
if test -f "$PDO_OCI_DIR/lib/sysliblist"; then
PHP_EVAL_LIBLINE(`cat $PDO_OCI_DIR/lib/sysliblist`, PDO_OCI_SYSLIB)
elif test -f "$PDO_OCI_DIR/rdbms/lib/sysliblist"; then
PHP_EVAL_LIBLINE(`cat $PDO_OCI_DIR/rdbms/lib/sysliblist`, PDO_OCI_SYSLIB)
fi
PDO_OCI_LIB_DIR="$PDO_OCI_DIR/lib"
AC_PDO_OCI_VERSION($PDO_OCI_DIR)
fi
case $PDO_OCI_VERSION in
8.0)
PHP_ADD_LIBRARY_WITH_PATH(nlsrtl3, "", PDO_OCI_SHARED_LIBADD)
PHP_ADD_LIBRARY_WITH_PATH(core4, "", PDO_OCI_SHARED_LIBADD)
PHP_ADD_LIBRARY_WITH_PATH(psa, "", PDO_OCI_SHARED_LIBADD)
PHP_ADD_LIBRARY_WITH_PATH(clntsh, $PDO_OCI_LIB_DIR, PDO_OCI_SHARED_LIBADD)
;;
8.1)
PHP_ADD_LIBRARY(clntsh, 1, PDO_OCI_SHARED_LIBADD)
;;
9.0)
PHP_ADD_LIBRARY(clntsh, 1, PDO_OCI_SHARED_LIBADD)
;;
10.1)
PHP_ADD_LIBRARY(clntsh, 1, PDO_OCI_SHARED_LIBADD)
;;
11.2)
dnl PHP_ADD_LIBRARY(clntsh, 1, PDO_OCI_SHARED_LIBADD)
;;
12.1)
dnl PHP_ADD_LIBRARY(clntsh, 1, PDO_OCI_SHARED_LIBADD)
;;
*)
AC_MSG_ERROR(Unsupported Oracle version! $PDO_OCI_VERSION)
;;
esac
PHP_ADD_LIBPATH($PDO_OCI_LIB_DIR, PDO_OCI_SHARED_LIBADD)
PHP_CHECK_LIBRARY(clntsh, OCIEnvCreate,
[
AC_DEFINE(HAVE_OCIENVCREATE,1,[ ])
], [], [
-L$PDO_OCI_LIB_DIR $PDO_OCI_SHARED_LIBADD
])
PHP_CHECK_LIBRARY(clntsh, OCIEnvNlsCreate,
[
AC_DEFINE(HAVE_OCIENVNLSCREATE,1,[ ])
], [], [
-L$PDO_OCI_LIB_DIR $PDO_OCI_SHARED_LIBADD
])
dnl
dnl Check if we need to add -locijdbc8
dnl
PHP_CHECK_LIBRARY(clntsh, OCILobIsTemporary,
[
AC_DEFINE(HAVE_OCILOBISTEMPORARY,1,[ ])
], [
PHP_CHECK_LIBRARY(ocijdbc8, OCILobIsTemporary,
[
PHP_ADD_LIBRARY(ocijdbc8, 1, PDO_OCI_SHARED_LIBADD)
AC_DEFINE(HAVE_OCILOBISTEMPORARY,1,[ ])
], [], [
-L$PDO_OCI_LIB_DIR $PDO_OCI_SHARED_LIBADD
])
], [
-L$PDO_OCI_LIB_DIR $PDO_OCI_SHARED_LIBADD
])
dnl
dnl Check if we have collections
dnl
PHP_CHECK_LIBRARY(clntsh, OCICollAssign,
[
AC_DEFINE(HAVE_OCICOLLASSIGN,1,[ ])
], [], [
-L$PDO_OCI_LIB_DIR $PDO_OCI_SHARED_LIBADD
])
dnl Scrollable cursors?
PHP_CHECK_LIBRARY(clntsh, OCIStmtFetch2,
[
AC_DEFINE(HAVE_OCISTMTFETCH2,1,[ ])
], [], [
-L$PDO_OCI_LIB_DIR $PDO_OCI_SHARED_LIBADD
])
dnl ifdef([PHP_CHECK_PDO_INCLUDES],
dnl [
dnl PHP_CHECK_PDO_INCLUDES
dnl ],[
AC_MSG_CHECKING([ PDO includes])
if test -f $prefix/include/php/ext/pdo/php_pdo_driver.h; then
pdo_inc_path=$prefix/include/php/ext
elif test -f $prefix/include/php5/ext/pdo/php_pdo_driver.h; then
pdo_inc_path=$prefix/include/php5/ext
elif test -f $abs_srcdir/include/php/ext/pdo/php_pdo_driver.h; then
pdo_inc_path=$abs_srcdir/ext
elif test -f $abs_srcdir/ext/pdo/php_pdo_driver.h; then
pdo_inc_path=$abs_srcdir/ext
else
AC_MSG_ERROR([Cannot find php_pdo_driver.h.])
fi
AC_MSG_RESULT($pdo_inc_path)
dnl ])
PHP_NEW_EXTENSION(pdo_oci, pdo_oci.c oci_driver.c oci_statement.c, $ext_shared,,-I$pdo_inc_path)
PHP_SUBST_OLD(PDO_OCI_SHARED_LIBADD)
PHP_SUBST_OLD(PDO_OCI_DIR)
PHP_SUBST_OLD(PDO_OCI_VERSION)
ifdef([PHP_ADD_EXTENSION_DEP],
[
PHP_ADD_EXTENSION_DEP(pdo_oci, pdo)
])
fi
fi
シンボリックリンク作成
ln -s /usr/lib/oracle/12.1/client64 /usr/lib/oracle/12.1/client
ln -s /usr/include/oracle/12.1/client64 /usr/include/oracle/12.1/client
pdo_oci.c修正
phpize
./configure --with-pdo-oci=instantclient,/usr,12.1
make
エラー。。。
Installing PDO_OCI and OCI8 PHP extensions on CentOS 6.4 64bitを参考
To solve it just change function_entry to zend_function_entry @pdo_oci.c file.
pdo_oci.cの
function_entryのところをzend_function_entryに変更して・・
make
通った!!!
make install
/etc/php.iniにextension=pdo_oci.soを書き込む
vi /etc/php.ini
extension=pdo_oci.so
httpdリスタート
しかし、
php -i | grep oci
でエラーが出る。。。
PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/pdo_oci.so' - /usr/lib64/php/modules/pdo_oci.so: undefined symbol: php_pdo_register_driver in Unknown on line 0
どうやらダイナミックリンクライブラリの参照の順番の問題なので
pdo.ini内のextension=pdo.soをコメントアウト
vi /etc/php.d/pdo.ini
# extension=pdo.so
php.iniを編集して、pdo_oci.soの上にextension=pdo.soを追加
vi /etc/php.ini
extension=pdo.so
extension=pdo_oci.so
httpdリスタートしてエラーでないことを確認!
3.テスト
test.phpを作ってテスト
<?php
define("DB_HOST", "ホスト");
define("DB_PORT", "1521"); // デフォルト1521
define("DB_USERNAME", "ユーザ");
define("DB_PASSWORD", "パスワード");
define("DB_SID", "SID");
try {
$dbh = new PDO("oci:dbname=//".DB_HOST.":".DB_PORT."/".DB_SID, DB_USERNAME, DB_PASSWORD);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e){
die($e->getMessage());
}
echo 'OK';
exit(0);
しかし、エラー。。。
「ERROR:ORA-21561: OID生成に失敗しました」
「/etc/hosts」に自ホスト名を追加
vi /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 自ホスト名を追加`
そしてついにテスト成功しました。
長くなりましたがこんな感じです。書き方こんなんでいいんかなってとこですが。
最初に見てた記事の「めげない気持ち」がほんとに重要でしたw
誰かの役に立てばいいなと思います。