thinkphp讨论区给大家提供一个技术圈交流的平台,您可以在这求助各种技术难题,发布关于thinkphp的招聘,吐槽闲聊心情,分享IT生活的各种欢乐与小烦恼,快来加入我们把!让我们大家共创TP和谐新社区!
来源: ThinkPHP3.2.3 连接oracle 教程 – ThinkPHP框架
一、 操作环境
系统: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 下载:188 次 )