由於項目需求,需要去其他項目組的oracle數據庫上面去定時的獲取一些數據,在本地配置了一下連接都oracle的方法,踩過windows上配置的一個又一個的坑,終於完成了配置,在此分享一下,希望能夠幫助到有需要的的人。
1.首先驗證一下他們給的只讀賬號是否能夠連接成功,需要在本地安裝連接工具(PLSQL Developer)
2.配置PLSQL Developer連接需要下載oracle即時客戶端(instantclient_11_2)工具,建立一個tnsnames.ora文件里面保存連接數據庫的信息,放到工具的目錄下。
oracle的客戶端最好要與oracle的版本一致(一般不一致也沒事兒的),問了dba,我們這里是11.2.0.4.0的版本,去oracle官網下載對應的client,由於本地的phpstudy里面帶的php都是32位版本的,擔心會出現問題,就下載了和php版本位數相同的客戶端(電腦系統是64的,和這個關系不大)。
解壓客戶端放到一個目錄下,新建tnsnames.ora放到客戶端文件夾的子目錄下。
里面放入以下內容
test_db= (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = IP)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = dbname) ) )
test_db是自己起的連接名字,IP替換為遠程oracle的IP,service_name放數據庫名字。
將客戶端的目錄加入到path路徑下,方便連接PLSQL Developer。
增加系統變量ORACLE_HOME,保存客戶端目錄。
增加系統變量NLS_lANG,保存為SIMPLIFIED CHINESE_CHINA.ZHS16GBK,為解決讀取編碼問題。
安裝PLSQL Developer后連接看看是否可以連接上即可。
3.開啟php的oci擴展或者pdo_oci擴展,連接測試。
php7因為沒有帶php_oci_11g的擴展,需要自己安裝獲取去下載對應版本的dll文件,放到php的ext目錄下,在php.ini中開啟擴展。
在開啟后可能會出現windows缺失oci.dll文件。
這時候將上面客戶端里面的oci.dll文件拷貝到php的目錄下即可。
啟動php,查看PHPinfo里面應該會出現如下擴展:
嘗試連接數據庫
try{ // $conn = new PDO("oci:dbname=//IP:1521/dbname",'username','password');// PDO方式 $conn = oci_connect('username','password',"(DEscriptION=(ADDRESS=(PROTOCOL =TCP)(HOST=IP)(PORT = 1521))(CONNECT_DATA =(SID=dbname)))"); var_dump($conn); echo "連接成功"; }catch(PDOException $e){ echo ("Error:".$e->getMessage()); }
- PDO方式會拋出如下的異常(SQLSTATE[]: pdo_oci_handle_factory: <<Unknown>> (ext\pdo_oci\oci_driver.c:642)2017-03-08+1)
- 普通連接會報錯(Warning: oci_connect(): OCIEnvNlsCreate() failed. There is something wrong with your system - please check that PATH includes the directory with Oracle Instant Client libraries)
在windows上遇上這些問題不要慌,這時候既然確定自己已經安裝好了擴展,那么肯定不是php的bug問題什么的(我看到有些去php官方提bug的)。
有些人說把dll文件全部拷貝到system32下或者全部拷貝到php下等等說法。首先,不建議拷貝任何東西到c盤的目錄下,本來就亂七八糟的,還因為自己一個小功能去里面放文件肯定是不合理的。哪里用到就放那里就好。
就像上面的缺失oci.dll文件,因為是php在用,所以php會先在自己的目錄下去搜索該文件,放到php目錄下就好(當然放到system32下可能也是可以的)
由於當時配置了好久,有點兒心煩,干脆我就直接把整個Client的文件拷貝到了php目錄下,測試不再出現上面的錯誤,那么證明就是因為缺少了上面的某個文件導致的。我這里是nginx+phpcgi的形式。這時候如果把剛才拷貝到php目錄下的文件刪除的話,有些被用到肯定就不能刪,經過測試,只有下面這個文件和剛才的oci.dll文件不能刪除。
這個文件還有個特點就是很大,里面封裝了很多函數擴展什么的。
現在就大功告成了,在此測試一下上面的PHP代碼:
- PDO形式打印連接類型(
object(PDO)#1 (0) {
)
} - 普通連接返回連接類型(resource(5) of type (oci8 connection))
總結:
不要輕信那些回答動輒拷貝到system32下,全部文件放到哪里哪里的,這樣會導致系統目錄混亂,到時候自己都找不到,即使解決了問題思路也不清晰,可能自己莫名其妙的解決了(其實沒啥用)
補充:
在用php連接數據庫的時候,使用到的是oracle的數據庫名字應該是配置的sid,而不是數據庫名字。有些配置的這倆是不一樣的,一定要注意,要不是連接不上的。