根据你的说法,PHP中最好的解决方案是什么来确保几个php函数的过程? 例如,函数A必须返回True才能启动B函数,B函数必须返回True才能启动另一个函数...
是否有像SQL中的Rollback / Commit这样的系统来确保在PHP中使用?
谢谢。
答案 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
}