PHP 와 IBM DB2(ibm_db2) 연동하기

바이너리 설치

  1. IBM 사이트에서 cli 드라이버 다운로드 

    wget "https://iwm.dhe.ibm.com/sdfdl/v2/regs2/smkane/IDSDPDS/Xa.2/Xb.EjTAa9JmwNlCNC7gnLPVg7Gp95exzkos-UtV6N_Dla8/Xc.ibm_data_server_driver_package_linuxx64_v10.5.tar.gz/Xd./Xf.LPr.D1vk/Xg.8588547/Xi.swg-idsdpds/XY.regsrvs/XZ.jAfBeLngjvGdhTsGCmjRIWfWbRk/ibm_data_server_driver_package_linuxx64_v10.5.tar.gz"
  2. 압축 해제
  3. 이동

    cd dsdriver/php_driver/linuxamd64/php64
  4. ibm_db2 는 PHP 드라이버이고 pdo_ibm 은 PDO 드라이버임. nts 는 none thread safety 라이브러리

    $ ls -l
    
    total 676
    -r-xr-xr-x 1 vagrant vagrant 191903 May 30  2013 ibm_db2_5.3.6_nts.so
    -r-xr-xr-x 1 vagrant vagrant 197589 May 30  2013 ibm_db2_5.3.6_ts.so
    -r-xr-xr-x 1 vagrant vagrant 143721 May 30  2013 pdo_ibm_5.3.6_nts.so
    -r-xr-xr-x 1 vagrant vagrant 139900 May 30  2013 pdo_ibm_5.3.6_ts.so
    -r--r--r-- 1 vagrant vagrant   2148 May 30  2013 README
    -r--r--r-- 1 vagrant vagrant   1811 May 30  2013 validate_install.php
  5. php 드라비어를 php 의 모듈 디렉터리에 복사
  6. php.ini 에 추가

 

컴파일해서 설치

사전 작업

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

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

    yum install php56w-pear php56w-devel zlib zlib-devel bc libaio glibc
  3. IBM DB2 instance 설치
  4. IBM_DB_HOME 환경 변수를 db2 가 설치된 경로로 설정

    export IBM_DB_HOME=/opt/ibm/db2/V10.5/

lib_db2 PECL 빌드

  1. 다운로드

    pear download pecl/ibm_db2
  2. 압축해제

    ibm_db2-1.9.7.tgz 
  3. 이동

    cd ibm_db2-1.9.7
  4. autoconf 생성

    phpize
  5. Makefile 생성

    ./configure 
  6. 컴파일 & 설치

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

    echo "extension=ibm_db2.so"  > /etc/php.d/db2.ini 
  8. php.init 에 instance_name 추가

    [ibm_db2]
    ibm_db2.instance_name=db2inst1
  9. httpd 나 php-fpm 재구동

SELinux 차단 해결

DB2 라이브러리가 lib_t context 가 아니라 usr_t 가 붙어 있어서 PHP FPM 이 로딩을 못하는 문제가 있음

php-fpm (을)를 시작 중: [22-Mar-2016 11:25:47] NOTICE: PHP message: PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/ibm_db2.so' - libdb2.so.1: failed to map segment from shared object: Permission denied in Unknown on line 0

audit2why 로 자세한 에러 로그 확인

# audit2why  < /var/log/audit/audit.log
 
ype=AVC msg=audit(1458612943.721:23177): avc:  denied  { execute } for  pid=2701 comm="php-fpm" path="/opt/ibm/db2/V10.5/lib64/libdb2dascmn.so.1" dev=dm-0 ino=2238888 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:usr_t:s0 tclass=file
        Was caused by:
                Missing type enforcement (TE) allow rule.
                You can use audit2allow to generate a loadable module to allow this access.

chcon 으로 컨텍스트 변경

chcon -t lib_t /opt/ibm/db2/V10.5/lib64/*

 

동작 확인

phpinfo()

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

예제 코드

독트린 프로젝트(http://www.doctrine-project.org/) 가 IBM DB2 를 지원하므로(실험적인 기능임!) 먼저 doctrine 설치

$ composer require "laravel-doctrine/orm" "1.1.*"

 

 

oci-test.php
<?php

 
$config = new \Doctrine\DBAL\Configuration();
//..
$connectionParams = array(
    'dbname' => 'SAMPLE',
    'user' => 'db2inst1',
    'password' => 'secret',
    'host' => 'localhost',
    'port' => '50000',
    'driver' => 'ibm_db2',
);

$conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config);
$sql = "SELECT * FROM emp";
$stmt = $conn->query($sql); // Simple, but has several drawbacks
while ($row = $stmt->fetch()) {
  dump($row);
}
$conn->close();

Ref