默认情况下,Phalcon的model名就是表名,这种约定对开发和代码都是有一定的帮助,但是很多情况下我们需要用到多表,甚至多库,这里先不讨论多库,仅记录下使用多表出现的问题。

Phalcon框架提供了getSource方法可映射到其他表名。这个方法是model自动调用的,我们只需要声明。

public function getSource()
{
 return "the_robots";
}

由于这个方法是不接受参数的,所以没法通过参数指定表名。基于这种情况,再model里声明一个变量,

  private $_table;

在确定表名后,添加setTable方法,把表名赋给变量

public function setTable($tb)
{
 $this->_table = $tb;
}

然后修改getSource方法,动态指定表名

public function getSource()
{
   return $this->_table;
}

这样乍一看,一点问题都没有,但是,当程序运行时,就会报错

Table '' doesn't exist in database when dumping meta-data for models\OrderCallback

从错误显示可以看到,最后指定的表名是空的,也就是说getSource没起作用,为什么呢?

是这个方法使用错误?又看了几遍官方文档,不是!
$_table变量赋值的时候就是空的?打印出来,不是!
….
作了各种假设,并一一去验证,结果还是失败,百思不得其解,而且更麻烦的是由于Phalcon是用C编写的PHP扩展,没法跟其他框架一样看到底层源码的实现。

最后孤注一掷,直接把不调用setTable方法,在getSource中指定表名,结果是OK的!
而且通过在getSource中设置断点,可以看到在执行数据库查询的时候,getSource被调用了三次!

那么,$_table和”表名”有什么区别?
前者是类的私有属性,后者是字符串,这个字符串是固定的,不会随着调用而发生变化,但是私有变量是会随着不同实例调用而变化的,也就是不能多实例共享!

知道这点后,其实解决方法也就出来了,既然$_table不能多实例共享,那么让它能多实例共享即可。

 private static $_table;

static数据成员由类的所有对象共享访问。

发表评论

电子邮件地址不会被公开。 必填项已用*标注