在某个PHP类的每个实例化对象上执行一个方法

时间:2010-12-17 09:08:20

标签: php oop postgresql

所以我在PHP中遇到这个问题,我有一个名为unit的类,它是一个名为units的表的引用,所以当我在表单元上更新一行时,我必须更新我的对象单元,调用一个名为refresh(),如$ unit-> refresh()。这对我来说没问题,因为单行的所有更新都是从对象单元进行的。

当另一个类更新单位表时会出现问题。例如,假设我有一个叫做单位的类(复数形式)。此类对单位表进行大量更改,更改可能由单元类的对象引用的行。

所以我在想,如果单元类上的静态方法可以创建类型单元的所有创建对象,可以让它们调用它们的refresh()方法,或者可能有另一种方法来处理它(如ORM,或设计模式)。我有两个必备条件,1)我将在posgtres上工作,我不会改变它,2)我使用了很多用户函数和触发器以及复杂的SQL(大量的时间和日期计算,内部选择等等)。

那么在这种情况下有什么用呢?

3 个答案:

答案 0 :(得分:2)

你的单位听起来像ActiveRecord。理论上,你可以让你的Units集合做类似的事情:

public function refreshAll()
{
    foreach ($this->units as $unit) {
        if ($unit->isModified) {
            $unit->update()
        }
    }
}

我强烈不鼓励这样做,因为这会导致每Unit个实例进行一次查询。往返数据库往往是一个瓶颈。想象一下你必须更新几百甚至几千个实例。

更好的方法是只收集下一个交易中所需的所有查询,并在一个请求中发出,例如:

之类的东西
public function refreshAll()
{
    $sql = '';
    foreach ($this->units as $unit) {
        if ($unit->isModified) {
            $sql .= $unit->getSql();
        }
    }
    // these are dummy method calls. 
    // i dont know if postgres supports transactions or multiqueries
    $this->dbAdapter->startTransaction();
    $this->dbAdapter->multiQuery($sql);
    $this->dbAdapter->commitOrRollback();
}

另一种选择是使用专用的Unit of Work模式。

Google图书摘录:

请注意,在使用工作单元时,您可能还需要考虑从Unit个实例中删除数据库访问代码(删除ActiveRecord),因为您正在将责任转移到将其保存到其他课程(这很好)。

答案 1 :(得分:0)

为什么不创建对象池,然后在需要时对池中的每个对象调用refresh方法?它是迄今为止最简单,最优雅的解决方案。

答案 2 :(得分:0)

你已经说过了答案。我会选择ORM(因为使用PHP,你最好的选择是Doctrine。正如Gordon在评论中提到“单位的WorK”一样,Doctrine正是出于这个目的使用这种模式。举一个令人耳目一新的例子。 ,查看关于刷新对象/关系的DOctrine Docs

如果您的ORM很重,已经提到的Unit of Work就是您的答案,您可以为项目编写自己的轻量级UoW。这个例子解释了Doctrine 2.0 UoW以及如何处理它。