我使用本地PHP 5.3安装编写了一个脚本,其中使用了goto
语句。把它上传到我的服务器上,我不得不发现我的主机仍然安装了PHP 5.2,因此不支持goto
。因此,我的问题是如何在以下上下文中模拟goto
的功能:
foo();
iterator_start:
foreach ($array as $array_item) {
switch ($array_item) {
case A:
foo();
break;
case B:
// Substitute
array_splice($array, offset($array_item), 1, array(A, A, B, C));
// Restart iterator
goto iterator_start;
break;
}
}
这个想法是数组必须根据一组替换规则进行修改。一旦执行了规则(可以修改任何位置的任意数量的数组项,替换它们,甚至删除它们),一切都必须从零开始,因为整个数组可能以不可预测的方式发生了变化(因此也允许递归替换规则)。我使用的解决方案,goto
在每次替换后简单地跳到循环的开始,对我来说似乎非常直接,甚至非常干净,但正如我提到的,我不能在我的web服务器上使用它。
这里是否有goto
的替代品,或者可以用完全不同的方式完成相同的任务(最好不改变太多代码)?
欢迎大家多多指教。
一个礼貌的请求:请不要再给我讲goto
的有用性或危险了。我读过PHP和将要在PHP 5.3中添加的goto语句,也知道意大利面条式代码和所有那些从20世纪80年代开始流行的"被认为有害的"字母。讨论goto
的所谓邪恶与我的问题无关,将任何程序结构视为"坏风格"本身只是教条,在我的编程思想中没有地位。
可以在while循环中使用each()
。它使用内部数组游标检索数组中的当前元素,并将游标移动到下一个元素。在对数组进行切片时,重置为游标,以便在下一个while循环迭代时从数组的起点重新开始。调用reset()
可能不是必需的,它可能是array_splice()
的副作用,因为它改变了数组。
foo();
while (list($key, $array_item) = each($array)) {
switch ($array_item) {
case A:
foo();
break;
case B:
// Substitute
array_splice($array, offset($array_item), 1, array(A, A, B, C));
// Reset array cursor, this is probably not necessary
reset($array);
break;
}
}
递归?与goto iterator_start
不同,您将这个循环包装在一个函数中,并递归地调用它。
嗯,据说任何goto
都可以用for
和while
之类的控制结构或函数来代替。
在你的例子中,我会使用一个函数:
function goto_substitute($array){
foreach ($array as $array_item) {
switch ($array_item) {
case A:
foo();
return $array;
case B:
// Substitute
array_splice($array, offset($array_item), 1, array(A, A, B, C));
// Restart iterator
return goto_substitute($array) ;
}
}
}
编辑(处理注释)
Functions使代码更易读。编程最佳实践说,一个函数应该做一个单一的事情和不超过一个屏幕的大小(大约80-90行)-你有多个替代块-似乎有多个函数是合乎逻辑的-如果你直观地命名它们,那么任何人都能理解那里发生了什么
是否尝试使用include?比如你把foreach代码写在
文件中foreach。php不使用goto而是使用include('foreach。php')
foreach ($array as $array_item) {
switch ($array_item) {
case A:
foo();
break;
case B:
// Substitute
array_splice($array, offset($array_item), 1, array(A, A, B, C));
// Restart iterator
include('foreach.php');
break;
}
}
goto是远古时代的邪恶神器。没有人知道为什么在PHP 5.3中引入它。不要用它。。
这是Dijkstra的一个很好的解释,甚至表明自1959年以来它一直被一些人皱眉。随着越来越多的控制流语句出现,goto的需求就更少了。在优化一些低级的、时间关键的代码时,它可能有特定的用途,但绝对没有理由在PHP中使用它,而且我还没有看到goto比其他任何解决方案都更好的第一个例子。
对于您的情况,递归可能是最好的解决方案。