PHP: 如何正确地使用这个 "wrapper" 方法?

PHP: How to make this "wrapper" methods properly?

我需要做这样的事情,但要避免重复调用 startTransactionstopTransaction:

<?php 
//parent: let's supply transactions!
class MegaParent {

    public $__started;
    //code inside this method must be executed only once - at first call
    public function startTransaction()
    {
        if (!$this->__started) {
            echo "Transaction Started\n";
            $this->__started = true;
        }
    }
    //code inside this method must be executed only once - at last call
    public function stopTransaction()
    {
        if ($this->__started) {
            echo "Transaction Stopped\n";
            $this->__started = null;
        }
    }
}
//Child 1: I do something wrapped in transaction 
class ChildOne extends MegaParent {

    public function doer()
    {
        $this->startTransaction();
        echo "Doing ChildOne\n";
        $this->stopTransaction();
    }
}
//Child 2: I do something in transaction too but I need no nested transactions
class ChildTwo extends ChildOne {

    public function doer()
    {
        $this->startTransaction();
        parent::doer();
        parent::doer();
        echo "Doing ChildTwo\n";
        $this->stopTransaction();
    }
}

(new ChildTwo)->doer();

结果:

Transaction Started
Doing ChildOne
Transaction Stopped
Transaction Started
Doing ChildOne
Transaction Stopped
Doing ChildTwo

如何得到这样的结果:

Transaction Started
Doing ChildOne
Doing ChildOne
Doing ChildTwo
Transaction Stopped

?

当您想要嵌套事务时,仅使用二进制标志就很难知道有多少事务已经开始和停止。此代码将其替换为 $transactionLevel,每次调用都会递增和递减。

class MegaParent {
    protected $transactionLevel = 0;
    //code inside this method must be executed only once - at first call
    public function startTransaction()
    {
        if ( $this->transactionLevel == 0 ) {
            echo "Transaction Started\n";
        }
        $this->transactionLevel++;
    }
    //code inside this method must be executed only once - at last call
    public function stopTransaction()
    {
        if ( $this->transactionLevel > 0 )  {
            $this->transactionLevel--;
            if ( $this->transactionLevel == 0 ) {
                echo "Transaction Stopped\n";
            }
        }
    }
}