在php中执行几个动作

时间:2011-03-17 08:47:15

标签: php transactions

根据你的说法,PHP中最好的解决方案是什么来确保几个php函数的过程? 例如,函数A必须返回True才能启动B函数,B函数必须返回True才能启动另一个函数...

是否有像SQL中的Rollback / Commit这样的系统来确保在PHP中使用?

谢谢。

5 个答案:

答案 0 :(得分:2)

做一系列功能看起来像这样:

try {
    if(!functionA()) {
        throw new Exception("Error message here", 100); // 100 can be any code, as long as it's unique to the other throw exception codes
    }

    if(!functionB()) {
        throw new Exception("Error message here", 101);
    }

    if(!functionC()) {
        throw new Exception("Error message here", 102);
    }
} catch(Exception $e) { 
    /**
     * Do some actions depending on the error code of the exception (100, 101, 102)
     */
}

但是如果我理解正确你想要执行一系列操作,并且只有当它们都成功时你才希望它们是最终的,否则你想撤消所有的操作?

在这种情况下,很难说你应该如何实现这一点,因为你不知道你想要实现什么。

但我可以给你一些建议。大多数不可逆的操作都有很多可能的检查。例如,如果要确保从文件系统中删除文件,可以先检查文件是否可写(is_writable),甚至是否存在(file_exists)。如果您首先对所有操作进行所有检查,然后执行操作,则可以确定它们将成功执行。当然,你可能会忘记检查,或者某些事情无法检查,但我没有看到其他选项来解决这个问题。

答案 1 :(得分:2)

php没有“回滚”。

但是,如果您使用异常,则可以尝试使用代码,并在获得异常时立即调用catch部分中的回滚函数。

伪代码:

try {
  your_function_1(); // must throw exceptions on error
  your_function_2(); // must throw exceptions on error
} catch(Exception $e){
  your_rollback_code();
}

答案 2 :(得分:1)

关于“启动功能”,基于其他功能的结果 - 取决于功能的上下文。几个选项:

if ( A() ) {
    if ( B() ) {
        anotherFunction();
    }
}

if ( A() && B() && anotherFunction() ) {
}

if ( A() && B() ) {
    anotherFunction();
}

在大多数情况下,我会做最后一个(if ( a and b ) { do c })。

答案 3 :(得分:0)

如果您有很多事情需要运行,那么最好使用状态机。

最简单的就是循环而“状态”变量没有“完成”状态。每当其中一个功能报告完成时,您就可以升级到下一个状态。

简单示例:

$nState = 0;
while ($nState != 3)
{
   switch ($nState)
   {
      case 0 : if (function1()) $nState = 1; break;
      case 1 : if (function2()) $nState = 2; break;
      case 2 : if (function3()) $nState = 3; break;
   }
}

增加的优势是你也可以回去。 显然,为了清楚起见,你可以使状态常量等等。

状态机的优势在于即使有很多功能,它也能保持整洁清晰。

我在这里假设这些功能在第一次尝试时不一定成功,有时你必须多次运行它们。如果情况并非如此,Stegeman的答案就更容易了。

答案 4 :(得分:0)

您可以拥有一个定义数组:

$callbacks = array
(
    array
    (
        'function' => 'function_1',
        'rollback' => 'function_r1',
        'arguments' => array(1),
    ),

    array
    (
        'function' => 'function_2',
        'rollback' => 'function_r2',
        'arguments' => array(1, 2),
    ),

    array
    (
        'function' => 'function_3',
        'rollback' => 'function_r3',
        'arguments' => array(1, 2, 3),
    ),
);

做这样的事情:

$callbacks = array_values($callbacks);

foreach ($callbacks as $key => $callback)
{
    if (call_user_func_array($callback['function'], $callback['arguments']) !== true)
    {
        // failed, calling necessary rollbacks in reverse order

        foreach (array_reverse(array_slice($callbacks, 0, $key)) as $rollback)
        {
            if (is_callable($rollback['rollback']) === true)
            {
                call_user_func_array($rollback['rollback'], $rollback['arguments']);
            }
        }

        break;
    }

    // success
}