实例化新的Obj或创建重置/清除方法以允许一个Obj重用

时间:2014-11-30 02:50:22

标签: php oop

我正在 PHP 中创建一个QueryBuilder,数据库事务要求我创建多个查询,这会导致问题,因为第一个查询之后的任何查询都会被追加并堆叠到 $ query < / em>该类中的属性。

为了解决这个问题,我可以为每个查询创建新的QueryBuilder对象,如下所示

$QB1 = new QB()
$QB1->select()
    ->from()
    ->where()
    ...

doSomething($QB1);

$QB2 = new QB()
$QB2->join()
    ->where()
    ...

doSomething($QB2);

我还可以创建一个方法来重置当前类属性,这将删除第一个查询。

$QB = new QB();
$QB->select()
    ->from()
    ->where()
    ...

doSomething($QB);

$QB->reset();

$QB->join()
    ->where()
    ...

doSomething($QB);

我确定此类问题出现在许多 OOP 应用程序中,在这种情况下,一般情况下,正确的做法是什么?重置/清除还是新建? - 也许还有另一种方法可以解决它?

期待任何回复。

1 个答案:

答案 0 :(得分:2)

这取决于对象的创建方式,但重置对象的主要思想是清除其内部状态

例如。

  1. 如果您实例化了注入特定初始状态的对象,则重置方法可能需要接受构造函数参数
  2. 或者使用默认值填充初始状态时,reset方法应该能够将它们设置为默认值
  3. 但在php clone中,关键字恰好存在于此目的。 您应该使用__clone()魔法来重置对象的内部状态,例如

    class QB {
    
        protected $sql;
        protected $params;
    
        public function __construct(){};
    
        public function select(){};
    
        function __clone(){
            $this->sql = NULL;
            $this->params = NULL;
        }
    }
    
    $qb = new QB()
    $qb->select()
        ->from()
        ->where()
        ...
    
    doSomething($qb);
    
    $qb2 = clone $qb; // you'll get the shallow copy of the $qb, with it initial state
    

    或者,如果您想要重置方法,

    class QB {
    
        protected $sql;
        protected $params;
    
        public function __construct(){};
    
        public function select(){};
    
        public function reset(){
            $this->sql = NULL;
            $this->params = NULL;
            return $this;
        }
    } 
    
    $qb = new QB()
    $qb->select()
        ->from()
        ->where()
        ...
    
    doSomething($qb);
    
    $qb2 = $qb->reset()->select()->from()->where();
    doSomething($qb2);
    

    修改

    正如我所提到的,clone将创建原始对象的浅表副本,因此

    $qb = clone $qb; // creates a new copy and assign it to $qb
    

    然而,这将涉及新的对象实例化

    但是在 reset 方法中,不会有新的对象实例化,而是要设置内部状态。您实际上并不需要将其分配给新变量,您可以

    $qb->reset()->select()->from()->where();
    
    doSomething($qb);
    

    希望这有帮助