Child pages
  • RHEL/CentOS/Ubuntu 와 Windows 에 오라클 DB 드라이버(OCI8/PDO_OCI) PHP extension 설치하기
Skip to end of metadata
Go to start of metadata

Windows

  1. 오라클 사이트에 연결하여 인스턴스 클라이언트 설치. 
  2. php.ini 에서 다음 항목 주석 해제
    Use with Oracle 10gR2 Instant Client

    extension=php_oci8.dll
    extension=php_pdo_oci.dll

    Use with Oracle 11gR2 Instant Client

    extension=php_oci8_11g.dll
    extension=php_pdo_oci.dll
  3. 웹 서버 재구동
  4. 제대로 로딩되었는지 phpinfo() 를 통해 확인

    <?php
    phpinfo();
    ?>


RHEL/CentOS

CentOS 에 포함된 PHP 는 Oracle driver(OCI8) 가 포함되어 있지 않으므로 PHP 에서 오라클과 연동하려면 드라이버를 직접 빌드해야 한다.


사전 작업

  1. gcc 컴파일러와 개발 도구 설치

    yum groupinstall "Development Tools"
  2. PHP 를 빌드하기 위한 개발 패키지 설치

    WebTatic 저장소에서 PHP 5.5 를 설치했을 경우이며 CentOS 기본 PHP(php) 패키지나 PHP 5.4(php54w) 의 경우 패키지명을 다르게 적어 줘야 한다.

    yum install php55w-pear php55w-devel zlib zlib-devel bc libaio glibc
  1. 패키지를 설치한다.

    yum localinstall oracle-instantclie*rpm
  2. autoconf가 찾을 수 있도록 심볼릭 링크를 생성한다.

    ln -s /usr/include/oracle/12.1/client64/  /usr/include/oracle/12.1/client
    ln -s /usr/lib/oracle/12.1/client64/  /usr/lib/oracle/12.1/client

PDO_OCI 빌드

PDO_OCI 는 안정화 되어 있지 않고 업데이트가 오래된 드라이버이므로 사용하지 않는 게 좋습니다.

대신 OCI8 을 래핑한 https://github.com/yajra/pdo-via-oci8 를 사용하여 PDO 를 에뮬레이션할 수 있습니다.

OCI 빌드

  1. 다운로드

    pear download pecl/oci8
  2. 압축해제

    tar zxvf oci8-2.0.8.tgz 
  3. 이동

    cd oci8-2.0.8
  4. autoconf 생성

    phpize
  5. Makefile 생성

    ./configure --with-oci8=shared,instantclient,/usr/lib/oracle/12.1/client64/lib
  6. 컴파일 & 설치

    make && make install
  7. oci 모듈을 로딩하도록 설정

    echo "extension=oci8.so"  > /etc/php.d/oci8.ini 
  8. httpd 재구동

SELinux 차단 해결

Port

PHP 는 웹 서버의 권한을 상속받으므로 SELinux port 정책때문에 오라클 DB 에 연결할 수 없다. 다음 명령어로 http 가 oracle의 tns listener(port 1521) 에 연결할 수 있도록 port 정책을 추가해야 한다. 

semanage port -a -p tcp -t http_port_t 1521

SELinux 설정을 변경하지 않으면 아래와 같이 ORA-12546 에러가 발생한다.

An Error occured! SQLSTATE[HY000]: pdo_oci_handle_factory: ORA-12546: TNS:permission denied (/home/lesstif/ora-client/PDO_OCI-1.0/oci_driver.c:463)


Exec Stack 

OCI 가 참고하는 오라클의 libclntsh  라이브러리내에서 stack 에서 실행되는 코드가 있어서 다음과 같은 에러가 발생한다.

PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/pdo_oci.so' - libclntsh.so.12.1: cannot enable executable stack as shared object requires: Permission denied in Unknown on line 0

audit2why 명령어로 자세한 원인을 파악할 수 있다.

audit2why  < /var/log/audit/audit.log
 
type=AVC msg=audit(1422000769.943:40975): avc:  denied  { execstack } for  pid=27369 comm="httpd" scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:system_r:httpd_t:s0 tclass=process
        Was caused by:
        The boolean httpd_execmem was set incorrectly. 
        Description:
        Allow httpd scripts and modules execmem/execstack
        Allow access by executing:
        # setsebool -P httpd_execmem 1

execstack 유틸로 clntsh 라이브러리가 stack 에서 실행되도록 flag 를 설정한다. (execstack 는 ELF prelinking utility 패키지에 포함되어 있다.)

yum install prelink
oracle 12.1
execstack -c /usr/lib64/php/modules/oci8.so
execstack -c /usr/lib64/php/modules/pdo_oci.so
execstack -c /usr/lib/oracle/12.1/client/lib/libclntsh.so.12.1 



Ubuntu

vagrant 기준


  1. 컴파일러 설치

    apt-get install gcc make autoconf
  2. instant client 다운로드
  3. 복사

    sudo mkdir -p /usr/local/oracle
    sudo mv instantclient_11_2/  /usr/local/oracle
    sudo ln -s /usr/local/oracle/instantclient_11_2 /usr/local/oracle/instantclient
  4. oci 다운로드 및 컴파일

    pear download pecl/oci8
    tar zxvf oci8-2.0.8.tgz 
    cd oci8-2.0.8
    ./configure --with-oci8=shared,instantclient,/usr/lib/oracle/12.1/client64/lib
    sudo make install
  5. oci 로딩하도록 php 설정

    sudo echo 'extension=oci8.so' >> /etc/php5/mods-available/oci.ini 
    sudo ln -s /etc/php5/mods-available/oci.ini /etc/php5/fpm/conf.d/20-oci.ini
    sudo ln -s /etc/php5/mods-available/oci.ini /etc/php5/cli/conf.d/20-oci.ini

    PHP7

    sudo echo 'extension=oci8.so' >> /etc/php/7.0/mods-available/oci.ini
    ln -s /etc/php/7.0/mods-available/oci.ini /etc/php/7.0/fpm/conf.d/20-oci.ini
    ln -s /etc/php/7.0/mods-available/oci.ini /etc/php/7.0/cli/conf.d/20-oci.ini
  6. 재구동

    sudo service php5-fpm restart

    PHP7

    sudo service php7.0-fpm restart

PHP-FPM 연동

php-fpm 을 사용하는 경우 다음과 같이 Oracle 관련 환경 변수를 여러 파일에 설정해 주어야 정상적으로 동작한다.


  1. /etc/profile.d/oracle.sh 를 만들고 다음 내용 추가

    #!/bin/bash
    #This is the lib path were the instantclient is installed
    ORACLE_HOME=/usr/lib/oracle/11.2/client64
    #This locates C headers from your instantclient
    C_INCLUDE_PATH=/usr/include/oracle/11.2/client64
    #I've never had trouble with that but it might save you a couple debugging hours
    LD_LIBRARY_PATH=$ORACLE_HOME/lib
    NLS_LANG=KOREAN_KOREA.AL32UTF8
    export ORACLE_HOME LD_LIBRARY_PATH NLS_LANG
  2. php-fpm 의 설정 파일(/etc/php-fpm.d/www.conf)에 추가

    env[ORACLE_HOME] =/usr/lib/oracle/12.1/client64
    env[NLS_LANG] = KOREAN_KOREA.AL32UTF8
    env[LD_LIBRARY_PATH] = /usr/include/oracle/12.1/client64/lib:$LD_LIBRARY_PATH

     

  3.  /etc/init.d/php-fpm  에서 oracle 변수를 로딩하도록 변경

    # Additional environment file
    if [ -f /etc/sysconfig/php-fpm ]; then
          . /etc/sysconfig/php-fpm
    fi
     
    ## 오라클 설정 추가
    . /etc/profile.d/oracle.sh
  4. php-fpm 재구동

    service php-fpm restart

     

 

 

동작 확인

phpinfo()

phpinfo 를 호출하는 php script 를 호출한 후에 oci 관련 내용이 있는지 확인한다.

OCI

다음 코드를 사용 환경에 맞게 수정한 후에 실행해서 정상 동작 여부를 확인한다.

oci-test.php
<?php
$srv = 'oracle.host';
$sid = 'SID';
$port = 1521;
$conn = oci_connect('username', 'password', "${srv}:${port}/${sid}", 'AL32UTF8');
if (!$conn) {
    $e = oci_error();
    echo "An Error occured! " .  $e['message'] . "\n";
    exit(1);
}   
$stid = oci_parse($conn, 'SELECT * FROM emp');
if (!oci_execute($stid)) {
    $e = oci_error($stid);
    echo "An Error occured! " .  $e['message'] . "\n";
    exit(1);
}
while ($row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS)) {
   var_dump($row) . "\n";
}
?> 

 

OCI-PDO

OCI-PDO대신 https://github.com/yajra/pdo-via-oci8 를 사용하는 것을 권장하며 라라벨에서 오라클을 사용하기 위해 필요한 yajra/laravel-oci8 를 설치하면 pdo-via-oci8도 자동 설치됩니다.

 Click here to expand...

 

 같이 보기

Ref


  • No labels