본문 바로가기

프로그램 경험/운영체제

[맥 Mac] MAC + PHP + OCI8 연동 대서사시

몇일동안 정말 이거 하느라 미쳐버릴것 같았다.
무슨 데이터베이스 연동하는게 이렇게 어려운가?!
별것도 아닌 이딴것이 나를 괴롭히는가?!!! 잠깐이나마 고통의 시간을 맛보았다...

*사양 
 - Mac OS X 10.6.8
 - Apache/2.2.21 (Unix)
 - PHP 5.3.8 (cli)

우선 오라클 연동을 하려면 instantclient-basic, sdk 가 필요하다.
 -instantclient-basic-10.2.0.4.0-macosx-x64.zip
 -instantclient-sdk-10.2.0.4.0-macosx-x64.zip

아래 경로로 들어가서 64비트용을 다운 받는다. 
http://www.oracle.com/technetwork/topics/intel-macsoft-096467.html 

처음에 32비트용 으로 받아서 설치하고 연동 했고 phpinfo() 호출 해보니까 아래와 같은 오류가 발생했다.
(오류 내용은 /var/log/apache2/error_log)

dyld: lazy symbol binding failed: Symbol not found: _OCIClientVersion
  Referenced from: /usr/lib/php/extensions/no-debug-non-zts-20090626/oci8.so
  Expected in: flat namespace

dyld: Symbol not found: _OCIClientVersion
  Referenced from: /usr/lib/php/extensions/no-debug-non-zts-20090626/oci8.so
  Expected in: flat namespace

그래서 64비트용을 다운받고 instantclient-basic-10.2.0.4.0-macosx-x64.zip 압축을 해제 해서
/usr/local/oracle/instantclient_64 경로로 이동 시켰다.
그리고 해당 경로에 가서 링크를 만든다.

$> ln -s libclntsh.dylib.10.1 libclntsh.dylib

그리고  instantclient-sdk-10.2.0.4.0-macosx-x64.zip 압축 해제 하면 sdk라는 폴더 안에 내용물이 
있는데 sdk 폴더를 /usr/local/oracle/instantclient_64 하위로 이동 시켰다.

이렇게 했으면 이제 oci8이 필요 하다.

$> pecl install oci8

이렇게 실행하면 instantclient 경로를 입력하라고 나온다.

instantclient,/usr/local/oracle/instantclient_64 

이렇게 입력하고 엔터를 치면 설치를 시작한다.

만약 pecl install oci8 이 명령이 실행 안된다면 직접 다운받아 설치 해야 한다.
http://pecl.php.net/package/oci8

여기 가서 최신버전 다운 받고 압축을 해제 한다.
해당 경로로 이동해서 아래와 같이 한다.

$> phpize
이렇게 하면 configure 파일이 생성된다.

$>./configure --with-oci8=instantclient,/usr/local/oracle/instantclient_64 
$>make
$>make install

이렇게 설치 한다.

php.ini 파일을 수정하라고 하면서 설치가 끝난다.

vi /etc/php.ini

extension 단어가 많은곳에 가서 마지막 줄에 아래 한줄 입력해주고 저장한다.
extension=oci8.so

그리고 아파치 재실행(apachectl restart) 하고 test.php 파일 하나 만들어서 아래와 같은 내용을 한줄 써주고
<?php
  phpinfo();
?>

웹브라우저에서 실행하면 

oci8

OCI8 Support enabled
Version 1.4.7
Revision $Revision: 321634 $
Active Persistent Connections 0
Active Connections 0
Oracle Run-time Client Library Version 10.2.0.4.0
Oracle Instant Client Version 10.2
Temporary Lob support enabled
Collections support enabled

DirectiveLocal ValueMaster Value
oci8.connection_class no value no value
oci8.default_prefetch 100 100
oci8.events Off Off
oci8.max_persistent -1 -1
oci8.old_oci_close_semantics Off Off
oci8.persistent_timeout -1 -1
oci8.ping_interval 60 60
oci8.privileged_connect Off Off
oci8.statement_cache_size 20 20
 
이런게 나온다... 라고 모든 문서들이 말해주지만... 나오지 않는다...
대체 왜 안나오는가!!!

3일간 구글링 하다 찾아낸 방법이 아래와 같다.

$> mkdir -p /b/227/rdbms
$> ln -s /usr/local/oracle/instantclient_64 /b/227/rdbms/lib

이렇게 해주고 아파치 재시작 하니 위의 oci8 항목을 보게 되었다..ㅜㅜ

이제 테스트를 해볼 시간이다. test_oracle.php 파일을 만들었다.

<?php
//test_oracle.php

ini_set('display_errors', 'on');
 
echo "start\n";
$conn = oci_connect('user', 'password', '아이피/SID');
echo "oci_conn\n";

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

$stid = oci_parse($conn, "SELECT * FROM table");

echo "connect success!\n";

if (!$stid) {
    $e = oci_error($conn);
    trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}
echo "parse!\n";
// Perform the logic of the query
$r = oci_execute($stid);
if (!$r) {
    $e = oci_error($stid);
    trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

echo "execute!\n";

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

oci_free_statement($stid);
oci_close($conn);

?>

다 된줄 알았더니... 이번엔...

Warning: oci_connect(): OCIEnvNlsCreate() failed. There is something wrong with your system - please check that DYLD_LIBRARY_PATH includes the directory with Oracle Instant Client libraries in /Users/mins/WorkSpace/WWW/test_oracle.php on line 41 Call Stack: 0.0008 635992 1. {main}() /Users/mins/WorkSpace/WWW/test_oracle.php:0 0.0012 636584 2. oci_connect() /Users/mins/WorkSpace/WWW/test_oracle.php:41

아... 정말...ㅜㅜ
내용만 보면 환경변수 DYLD_LIBRARY_PATH 가 안잡혀서 그런것이다.

info.php 파일을 생성하고 내용은 아래처럼 했다.
<?php
  exec("export", $output);
  print "<pre>";
  var_dump($output);
  print "</pre>";
?>

이렇게 하면 현재 잡혀 있는 환경변수를 확인해 볼수 있다. 
역시 지금은 DYLD_LIBRARY_PATH 변수가 없다.

아래와 같은 방법을 통해서 환경변수를 생성해봤다.

~/.bash_profile 생성해서 export 해봤지만 실패...
/etc/profile 에 export 해봐도 실패...
/etc/apache2/httpd.conf에 SetEnv DYLD_LIBRARY_PATH /usr/local/oracle/instantclient_64 넣어도 실패...
test_oracle.php 내용에 putenv("DYLD_LIBRARY_PATH=/usr/local/oracle/instantclient_64"); 넣어도 실패...

별별 방법을 사용해봐도 info.php 실행해보면 DYLD_LIBRARY_PATH 변수가 나타나지 않는다.
거의 미칠지경이 되었다...
구글신과 5시간의 접신후 뭔가 실마리를 발견했다.

맥의 아파치 환경변수 설정 파일이 따로 있다는 것이다.
/System/Library/LaunchDaemons/org.apache.httpd.plist
이 파일이란다!!!

열어보니 아래와 같이 되어 있다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Disabled</key>
        <true/>
        <key>Label</key>
        <string>org.apache.httpd</string>
        <key>ProgramArguments</key>
        <array>
                <string>/usr/sbin/httpd</string>
                <string>-D</string>
                <string>FOREGROUND</string>
        </array>
        <key>OnDemand</key>
        <false/>
        <key>SHAuthorizationRight</key>
        <string>system.preferences</string>
<key>EnvironmentVariables</key>
    <dict>
        <key>DYLD_LIBRARY_PATH</key>
        <string>/usr/local/oracle/instantclient_64</string>
   </dict> 
</dict>
</plist>

빨간 부분을 추가 하고 아파치를 재시작 하면... 드디어 된다...^__________________________^
 

이제 Navicat에서 접속 하려고 하니까... 오류 메시지... 
ORA-12737: Instant Client Light: unsupported server character set KO16MSWIN949

이건 instantclient 32비트용을 다운받아 설치 하고 아래와 같이 Navicat 설정을 잡아주면 된다.
  *주의:아래 설정은 저의 설정입니다. 각자 자신의 설정에 맞게 변경하세요.




*참고
http://wiki.apache.org/httpd/DistrosDefaultLayout