同一框架多库选择与查询

#1 redguan

问题在这里:
http://speedphp.com/bbs/viewthread.php?tid=187&page=1&extra=pid648

一、修改 spmodel.php


 /**
  * 表名称
  */
public $table;


下面增加两个接入口

 /**
  * 库名称 => 2010-02-27 扩充
  */
public $database;
/**
  * 表名前缀 => 2010-02-27 扩充
  */
public $prefix;


构造函数增加:

if语句上边

 
  $GLOBALS['G_SP']['db']['database'] = !empty($this->database) && $this->database!='' ? $this->database : $GLOBALS['G_SP']['db']['database'];
  $GLOBALS['G_SP']['db']['prefix'] = !empty($this->prefix) && $this->prefix!='' ? $this->prefix : $GLOBALS['G_SP']['db']['prefix'];


完成。

使用方法:

用户APP中的model目录中,建立MODEL时,增加两个变量。

如果你不增加,那么就默认读APP默碎的库名和表前缀。已存在程序不需要重写。

 
class uc extends spModel
{

public $prefix = 'uc_';
public $pk = 'uid';  
public $table = 'members';
public $database = 'ucenter';

}
?>


其它一样。

2010-02-27 10:54:58

#2 jake

呵呵,不需要修改spModel的构造函数,只是在spModel的子类中覆盖构造函数就可以实现了,这是OOP的实现方法。

而且,也不是每个子类都要做这种覆盖,这些子类Cs都继承与B,然后B再继承于spModel就可以。

这些覆盖的操作都在B类上面实现,包括换数据库地址和设置,或是读写分库,甚至把findAll改成create都可以:lol

---------------PS:帖子移动到交流板块

2010-02-27 13:15:03

#3 redguan

以前一直重写,然后复盖类。但现在无法实现了。

错误:
Table 'ss.rg_search_key' doesn't exist

这个是因为
$GLOBALS['G_SP']['db']['database']

虽然重写了,但是却没有改变。

测试了一下:
spError($GLOBALS['G_SP']['db']['database']. "
{$sql}
执行错误: " . mysql_error());
显示 redguan 。说明到这里能正确识别。但是却出错?难道需要先MYSQL_CLOSE() ?


 
class lib_key extends spModel
{
public $pk = 'keyid';  
public $table = 'search_key';

public $database = 'redguan';
public $prefix = 'rg_';
/**
  * 构造函数
  */
public function __construct()
{
  $GLOBALS['G_SP']['db']['database'] = !empty($this->database) && $this->database!='' ? $this->database : $GLOBALS['G_SP']['db']['database'];
  $GLOBALS['G_SP']['db']['prefix'] = !empty($this->prefix) && $this->prefix!='' ? $this->prefix : $GLOBALS['G_SP']['db']['prefix'];
  if( null == $this->tbl_name )$this->tbl_name = $GLOBALS['G_SP']['db']['prefix'] . $this->table;
  $this->_db = spClass($GLOBALS['G_SP']['db']['driver'], $GLOBALS['G_SP']['db'], $GLOBALS['G_SP']['sp_core_path'].$GLOBALS['G_SP']['db_driver_path']);
  echo $GLOBALS['G_SP']['db']['database'];
}
}
?>

2010-04-12 16:29:08

#4 jake

建议你这样测试一下,把上面的 __construct()内全部的$GLOBALS['G_SP']['db']['xxx']直接替换成你本来要的值,再进行测试。

2010-04-12 16:44:08

#5 redguan

现象:
在同一个c中,不能同时存在两个不同的M请求。

关键是MYSQL.PHP 文件中的构造函数只运行一次?
增加一句,完全不起作用。

/**
  * 构造函数
  *
  * @param dbConfig  数据库配置
  */
public function __construct($dbConfig)
{
  $this->conn = mysql_connect($dbConfig['host'].":".$dbConfig['port'], $dbConfig['login'], $dbConfig['password']) or spError("数据库链接错误 : " . mysql_error());
$dbConfig['database'] = $dbConfig['database']==$GLOBALS['G_SP']['db']['database'] ? $dbConfig['database'] : $GLOBALS['G_SP']['db']['database'];
  mysql_select_db($dbConfig['database'], $this->conn) or spError("无法找到数据库,请确认数据库名称正确!");
  $this->exec("SET NAMES UTF8");
}

2010-04-12 16:59:13

#6 redguan

这个应用的流程:

 
class aa extends spController {

//数据库BBS,表A1
$db1 = spClass("lib1");
//热行数据库操作...

//数据库SHOP,表B1
$db2 = spClass("lib2");
//执行数据为操作...


//数据库名,前缀已经重新复盖加载
//这个时候,$db2 中的 ['database'] 还是 $db1 的。所以出错了。

//我怀颖是MYSQL.PHP 只执行一次。当有新库名时,public function __construct($dbConfig) 这句没有重新执行。
//所以 $this->conn 是DB1的,而不是DB2的。

2010-04-12 17:07:11

#7 redguan

建议你这样测试一下,把上面的 __construct()内全部的$GLOBALS['G_SP']['db']['xxx']直接替换成你本来要的 ...
jake 发表于 2010-4-12 16:44
这个正确啊。如例。库DB1能有正确结果。

但复盖 db 后。MYSQL没有用新的配置从新打开。

我看到mysql.php 里的是 $this->conn = mysql_connect 而不是 $this->conn = mysql_pconnect

理论应该执行一次,自动关闭一次才对啊。

2010-04-12 17:10:19

#8 jake

你可以在aa内建立一个切换的方法,用类似__construct内的写法来改变__db的值即可。

目前spModel的__db是protected,在下一个版本中,__db将是public,这样切换起来更方便了。

2010-04-12 17:13:43

#9 怀念曾经

出现上面同样的问题怎么处理!!!

连接库1时再连接库2就不行,切换不到库2,还是在库1上做操作!!!

Jake怎么处理!!

2010-11-27 22:49:35

#10 怀念曾经

Jake 不在了吗?

2010-11-27 23:08:25