系统:Windows7 旗舰版 64位
PHP环境:WampServer Version 2.5
ThinkPHP:3.2.3 正式版
Oracle:Orcale_10g 64位版
二、 环境配置
1.打开如图的PHP扩展菜单,在绿色图标上,左键->PHP->PHP扩展,点击php_pdo_oci的扩展,这时候这个WAMP会重启,等待重启后变绿,就表示OK。

2, 再次打开刚才的localhost页面,如果找到如图4的显示,就表示目前PHP已经支持Oracle了。

三、 ThinkPHP配置
1, 把下载好的3.2.3正式版解压,项目中只需要ThinkPHP文件夹,这是核心。

2, 使用IDE新建一个项目,项目的文件夹为刚才的Wamp下的www文件夹,如果个人需要自定义别的文件夹,需要修改apache的配置文件,这里我不修改。
3, 将Thinkphp文件夹拷贝到项目文件夹中,新建一个php文件,命名index.php。
4, IDE中已经有这些文件的显示了,打开index.php,编写如下内容:
. 代码如下:
<?php
define('APP_DEBUG', true);
require './ThinkPHP/ThinkPHP.php';5, 在浏览器中打开localhost/项目名/index.php,Thinkphp会帮你生成好相关文件和文件夹。6, 对配置文件进行操作,找到:Conf文件夹下config.php文件,修改如下:
. 代码如下:
'DB_TYPE' => 'oracle', // 数据库类型
'DB_HOST' => 'localhost', // 服务器地址
'DB_NAME' => 'test', //这个是我自己后来建的数据库
'DB_USER' => 'test', // 用户名
'DB_PWD' => 'orcl', // 密码
'DB_PORT' => '1521', // 端口
'DB_CASE_LOWER' => true,
'DB_PREFIX' => 'ccthink_', // 数据库表前缀
'DB_CHARSET'=> 'utf8',
'DB_SEQUENCE_PREFIX' => 'SEQ_',Oracle数据库和mysql 的结构不同,一般默认安装的数据库名是orcl,如果你使用了多个数据库监听,那么就要根据具体的监听字段来设置。比如:我本机数据库坚挺是Orcl,同时监听另外一个外网的数据库,监听字符串为Orcl2,那么如果你需要连接这个外网数据库,那么需要写的数据库名就是orcl2。7, 经过以上的配置,是已经可以连接oracle数据库了,但是在thinkphp的实际操作中有什么注意的地方,且接着往下看。
修改oracle驱动文件 ThinkPHP\Library\Think\Db\Driver\Oracle.class.php
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace Think\Db\Driver;
use Think\Db\Driver;
use PDO;
/**
* Oracle数据库驱动
*/
class Oracle extends Driver{
private $table = '';
protected $selectSql = 'SELECT * FROM (SELECT thinkphp.*, rownum AS numrow FROM (SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%) thinkphp ) %LIMIT%%COMMENT%';
/**
* 解析pdo连接的dsn信息
* @access public
* @param array $config 连接信息
* @return string
*/
protected function parseDsn($config){
$dsn = 'oci:dbname=//'.$config['hostname'].($config['hostport']?':'.$config['hostport']:'').'/'.$config['database'];
if(!empty($config['charset'])) {
$dsn .= ';charset='.$config['charset'];
}
return $dsn;
}
/**
* 执行语句
* @access public
* @param string $str sql指令
* @param boolean $fetchSql 不执行只是获取SQL
* @return integer
*/
public function execute($str,$fetchSql=false) {
$bind = $this->bind; //TODO 新增 修复bug 修复及支持获取自增Id的上次记录 by czw
$this->initConnect(true);
if ( !$this->_linkID ) return false;
$this->queryStr = $str;
if(!empty($this->bind)){
$that = $this;
$this->queryStr = strtr($this->queryStr,array_map(function($val) use($that){ return '\''.$that->escapeString($val).'\''; },$this->bind));
}
if($fetchSql){
return $this->queryStr;
}
$flag = false;
if(preg_match("/^\s*(INSERT\s+INTO)\s+(\w+)\s+/i", $str, $match)) {
//$this->table = C("DB_SEQUENCE_PREFIX").str_ireplace(C("DB_PREFIX"), "", $match[2]);
$this->table = C("DB_SEQUENCE_PREFIX").str_ireplace(C("DB_PREFIX"), "", $match[2]).C("DB_SEQUENCE_SUFFIX");//TODO 新增 扩展队列名加后缀 修复bug 修复及支持获取自增Id的上次记录 by czw
$flag = (boolean)$this->query("SELECT * FROM user_sequences WHERE sequence_name='" . strtoupper($this->table) . "'");
}
//释放前次的查询结果
if ( !empty($this->PDOStatement) ) $this->free();
$this->executeTimes++;
N('db_write',1); // 兼容代码
// 记录开始执行时间
$this->debug(true);
$this->PDOStatement = $this->_linkID->prepare($str);
if(false === $this->PDOStatement) {
$this->error();
return false;
}
$this->bind = $this->bind ? $this->bind : $bind;//TODO 新增 修复bug 修复及支持获取自增Id的上次记录 by czw
foreach ($this->bind as $key => $val) {
if(is_array($val)){
$this->PDOStatement->bindValue($key, $val[0], $val[1]);
}else{
$this->PDOStatement->bindValue($key, $val);
}
}
$this->bind = array();
$result = $this->PDOStatement->execute();
$this->debug(false);
if ( false === $result) {
$this->error();
return false;
} else {
$this->numRows = $this->PDOStatement->rowCount();
if($flag || preg_match("/^\s*(INSERT\s+INTO|REPLACE\s+INTO)\s+/i", $str)) {
//$this->lastInsID = $this->_linkID->lastInsertId(); //
$this->lastInsID = $this->lastInsertId($this->table);//TODO 修复bug 修复及支持获取自增Id的上次记录 by czw
}
return $this->numRows;
}
}
/**
* TODO
* 2016-05-09 新增方法 修复bug 修复及支持获取自增Id的上次记录 by czw
* 取得Oracle最近插入的ID
* @access public
*/
public function lastInsertId($sequence = '') {
try {
$lastInsID = $this->_linkID->lastInsertId();
} catch(\PDOException $e) {
//对于驱动不支持PDO::lastInsertId()的情况
try {
$lastInsID = 0;
$seqPrefix = C("DB_SEQUENCE_PREFIX") ? C("DB_SEQUENCE_PREFIX") : 'seq_';
$seqSuffix = C("DB_SEQUENCE_SUFFIX") ? C("DB_SEQUENCE_SUFFIX") : '';
$sequence = strtoupper($sequence ? $sequence : $seqPrefix.$this->table.$seqSuffix);
$q = $this->query("SELECT {$sequence}.CURRVAL as t FROM DUAL");
if($q) {
$lastInsID = $q[0]['t'];
}
} catch(\Exception $e) {
//print "Error!: " . $e->getMessage() . "</br>";
//exit;
}
}
return $lastInsID;
}
/**
* 取得数据表的字段信息
* @access public
*/
public function getFields($tableName) {
list($tableName) = explode(' ', $tableName);
$result = $this->query("select a.column_name,data_type,decode(nullable,'Y',0,1) notnull,data_default,decode(a.column_name,b.column_name,1,0) pk "
."from user_tab_columns a,(select column_name from user_constraints c,user_cons_columns col "
."where c.constraint_name=col.constraint_name and c.constraint_type='P'and c.table_name='".strtoupper($tableName)
."') b where table_name='".strtoupper($tableName)."' and a.column_name=b.column_name(+)");
$info = array();
if($result) {
foreach ($result as $key => $val) {
$info[strtolower($val['column_name'])] = array(
'name' => strtolower($val['column_name']),
'type' => strtolower($val['data_type']),
'notnull' => $val['notnull'],
'default' => $val['data_default'],
'primary' => $val['pk'],
'autoinc' => $val['pk'],
);
}
}
return $info;
}
/**
* 取得数据库的表信息(暂时实现取得用户表信息)
* @access public
*/
public function getTables($dbName='') {
$result = $this->query("select table_name from user_tables");
$info = array();
foreach ($result as $key => $val) {
$info[$key] = current($val);
}
return $info;
}
/**
* SQL指令安全过滤
* @access public
* @param string $str SQL指令
* @return string
*/
public function escapeString($str) {
return str_ireplace("'", "''", $str);
}
/**
* limit
* @access public
* @return string
*/
public function parseLimit($limit) {
$limitStr = '';
if(!empty($limit)) {
$limit = explode(',',$limit);
if(count($limit)>1)
$limitStr = "(numrow>" . $limit[0] . ") AND (numrow<=" . ($limit[0]+$limit[1]) . ")";
else
$limitStr = "(numrow>0 AND numrow<=".$limit[0].")";
}
return $limitStr?' WHERE '.$limitStr:'';
}
/**
* 设置锁机制
* @access protected
* @return string
*/
protected function parseLock($lock=false) {
if(!$lock) return '';
return ' FOR UPDATE NOWAIT ';
}
/**
* 随机排序
* @access protected
* @return string
*/
protected function parseRand(){
return 'DBMS_RANDOM.value';
}
/**
* 执行查询 返回数据集
* @access public
* @param string $str sql指令
* @param boolean $fetchSql 不执行只是获取SQL
* @return mixed
*/
public function query($str,$fetchSql=false) {
$this->initConnect(false);
if ( !$this->_linkID ) return false;
$this->queryStr = $str;
if(!empty($this->bind)){
$that = $this;
$this->queryStr = strtr($this->queryStr,array_map(function($val) use($that){ return '\''.$that->escapeString($val).'\''; },$this->bind));
}
if($fetchSql){
return $this->queryStr;
}
//释放前次的查询结果
if ( !empty($this->PDOStatement) ) $this->free();
$this->queryTimes++;
N('db_query',1); // 兼容代码
// 调试开始
$this->debug(true);
$this->PDOStatement = $this->_linkID->prepare($str);
if(false === $this->PDOStatement){
$this->error();
return false;
}
foreach ($this->bind as $key => $val) {
if(is_array($val)){
$this->PDOStatement->bindValue($key, $val[0], $val[1]);
}else{
$this->PDOStatement->bindValue($key, $val);
}
}
$this->bind = array();
$result = $this->PDOStatement->execute();
// 调试结束
$this->debug(false);
if ( false === $result ) {
$this->error();
return false;
} else {
return $this->getResult();
}
}
/**
* TODO 修复资源(clob)的查找 by czw
* 获得所有的查询数据
* @access private
* @return array
*/
private function getResult() {
//返回数据集
// $result = $this->PDOStatement->fetchAll(PDO::FETCH_ASSOC);
while($row=$this->PDOStatement->fetch(PDO::FETCH_ASSOC)){
$clobFields=$this->detectResource($row);
if(count($clobFields)>0){
$this->retriveResourceRow($row,$clobFields);
}
$result[]=$row;
}
$this->numRows = count( $result );
return $result;
}
//将资源转换成内容 TODO 修复资源(clob)的查找 by czw
protected function retriveResourceRow(&$row,$clobFields){
if(count($clobFields)>0){
foreach($clobFields as $colName){
$row[$colName] =stream_get_contents($row[$colName]);
}
}
}
//查找资源的字段 TODO 修复资源(clob)的查找 by czw
protected function detectResource($row){
$colNames = array();
foreach ($row as $key=>$val){
if(is_resource($val)){
$colNames[] = $key;
}
}
return $colNames;
}
}所有表字段通过pdo连接,被thinkphp已经强制转小写了!!其他的使用方式和之前都一样。
test.zip
( 1.1 MB 下载:353 次 )
最佳答案