PHP中的GOTO是否有害?[关闭]


72

我最近发现PHP 5.3支持名为的新语言构造GOTO。每个人都知道它在做什么。但是,它不完全是传统的GOTO,只是一个跳转标签。我很想知道这GOTO是否有害并暗示错误代码?


2
GOTO就像用于HTML解析的regexp一样;codinghorror.com/blog/archives/001311.html
鲁本斯·法里亚斯

5
在大学里,当我想惹恼我的教授时,我总是使用goto语句,muahahaha ....该程序当然仍然可以正常运行,但是当他们遇到这些小语句时,我总能看到他们的视线在颤抖
the_e

16
>“但是,这不完全是传统的GOTO,只是一个跳转标签。” 这与“传统”GOTO有何不同?
Anon。

3
经常性GOTOStackOverflow上的问题被认为是有害的。
rsenna

5
goto根本不是邪恶的..但这确实是邪恶的:eval("foo: goto foo;");
CodeBrauer 2015年

Answers:


153

除非您使用汇编程序进行编程,否则应始终将GOTO与飞机的救生背心以相同的方式对待:可以使用它们是一件好事,但是如果您需要使用它们,则意味着您会遇到很大的麻烦。


65
我宁愿说:“如果您需要使用它们而又没有它们,那您就麻烦很大”。支持进入编程语言是一个强项。
Remo.D

20
@ Remo.D是的,因为救生衣在飞机失事中挽救了许多生命!
Buttle Butkus

13
@ButtleButkus不在飞机失事中,但他们在水(海洋,湖泊,河流)紧急降落中挽救了许多生命。
Remo.D

3
实际上,我确实遇到过一种情况,goto确实救了我们。我们开始使用MVC,并且由于其具有非常成熟的类加载系统,因此我们将MVC用于依赖性管理。好吧,突然之间,在使用传统header()的旧文件中;死; 构造后,APC开始随机抛出分段错误。Goto成为使原有代码保持浮动的救生衣,直到所有这些代码都可以重构为控制器为止。通过避免压倒性的深度条件,它还提供了改进的性能
彼得

很好解释。我真的很喜欢这个答案。:D
xZero 2015年

103

我不敢相信没有人张贴这个:)

xkcd - goto

当然,PHP尚未编译...也许猛禽会在每次访问您的网站时追逐您?


20
最有趣的一点是,他的漫画在goto的php手册参考中:es.php.net/manual/en/control-structures.goto.php,所以是的,猛禽也会追你,即使在PHP中也是如此;)也很棒文字:“尼尔史蒂文森(Neal Stephenson)认为给自己的唱片公司
定名

2
如果可以的话,我会给您+2(一个是对的,一个是漫画的)
TheHippo

1
猛禽每次通过非Mozilla浏览器访问您的网站时都会追捕您:)
userlond

81

无论使用哪种控制结构,不良的代码结构都是有害的。

我个人更喜欢goto,它使程序的流程更清楚地显示为“控制变量”,并嵌套了“ if”,这将间接导致代码中的同一分支。

因此,只需编写两个版本(带有和不带有GOTO),然后看看哪个版本更容易理解。那么选择就很容易。


6
前两段为+1。为什么这不是公认的答案?:-)
MattBianco 2010年

2
嗯...这很合理,但是我们都知道,从头至尾,我们进入此页面是因为对使用感到内goto x;。这绝不是一个人理想的工作流程,只是生活支持,我们知道我们永远也不会重写,相反,我们可悲地会留给下一个可怜的家伙处理。
Alastair

2
+1我用它跳转到内联代码的末尾,以避免嵌套丑陋的if()。它还可以避免不必要的代码执行-例如,您正在if-elseif-elseif-else块之前执行的代码,该代码可能在第二个elseif之后被“释放”。
Anthony Scaife 2014年

如果在您的PHP版本中不可用,则出现“中断”;在do {...} while(0)中间可能适合您。我曾经这样做过(自然而然地带有文档)。
Anthony Scaife 2014年

1
这是一个很老的帖子-但我必须在这里同意...这是一个与其他任何控件一样的控制结构,如果您是狗屎编码器,则将编写带有或不带有goto的狗屎控制结构。我已经看过代码嵌入并嵌套了5/6级别,其中包含控制变量if($ somePass):实际上,每遍过程只是在检查是否具有所需的内容,并想去其他地方完成工作。去GOTO你好东西吧!
特伦特(Trent)

23

我认为这是PHP手册页中最重要的部分,在这里缺少:

不是完全不受限制的goto。目标标签必须在同一文件和上下文中,这意味着您不能跳出一个函数或方法,也不能跳入一个。您也不能跳入任何形式的循环或开关结构。您可能会跳过这些,通常的用法是使用goto代替多级中断。

恕我直言,这使其与以往的BASIC风格完全不同。


谢谢-喜爱BASIC。在PHP中避免使用它-但是当它限于功能或文件时,我发现它更易于管理。真正的PHP手册不能很好地解释它。
路加

这是一个很酷的例子goto在PHP BTW github.com/schmunk42/retry/blob/master/src/retry.php -学分去igorw
schmunk

... use a goto in place of a multi-level break.考虑到PHP实际上有一个多级中断,这是一个有趣的陈述。break 2;例如将打破两个循环。只是把这个留在这里给任何人。您可能需要多层次的休息。
Yay295 '19

18

我目前只是少数派,但我相信对PHP的goto构造施加的限制使之成为一个非常有益的工具:

http://adamjonrichardson.com/2012/02/06/long-live-the-goto-statement/

我实际上浏览了一个箭头代码示例(深层嵌套的条件),并在一个版本中使用标准实践(保护子句,分组条件,提取函数)对其进行了重构,而在另一版本中使用了基于goto的版本进行重构,实际上,我更喜欢使用基于goto的重构。


10

枪是邪恶的吗?两者都可以用于善恶。我想说,没有goto编写好的代码要比使用goto编写容易。


22
枪不杀人。魔法导弹可以。
2009年

1
在加拿大,我们的枪支更少,枪支暴力更少。因此,我建议不要使用goto语句。
antoineMoPa

3
@antoineMoPa因此,请不要在加拿大使用goto。
userfuser

1
显然,后藤是善良的。我们只需要经过过安全
培训的

@antoineMoPa冒着我被SO禁止的危险,此评论就像是说刚果共和国的汽车死亡人数有所减少,因为他们的汽车较少。在某些情况下,汽车以及goto语句都具有经过验证的实用程序。因此,也许我们可以要求“转到许可证”?
UncaAlby

7

在给定情况下可以使代码更具可读性的任何语言功能都是一件好事。即使这些情况很少且相差甚远,GOTO也是其中一种语言功能。如果我们禁止任何语法使贫穷的程序员能够编写糟糕的,无法维护的代码,那么我们的工作将变得非常困难。


糟糕的程序员无论如何都可以编写糟糕的程序。如果我们禁止任何允许不良程序员编写不良程序的语法,那么就什么也没写
。– UncaAlby

5

作为一名软件工程师,我主要从事“大型机”和“大型公司服务器”的工作...而我们的日常语言(我的意思是基本代码中95%的一种)是Cobol,它广泛使用GOTO。

这种用法并不意味着代码是错误的。这只是意味着在编写程序时,此工具(GOTO)是正确的工具。

为了回答Kaitsuli的问题,我认为它在编写PHP脚本时可能是有用的工具。另一方面,到现在为止,已经有近十年的时间,很多脚本没有使用它。此外,它还具有更多面向对象的功能,与PHP的发展背道而驰。

恕我直言,代码的生产既不是好事也不是坏事:好的程序仍然会是好的,而“恐怖程序”会变得更糟……唯一的问题是:“为什么在证明没有必要10年后添加GOTO呢? ”。


真是

4

GOTO通常是邪恶的,因为它使您可以构建非结构化代码。通过通常的循环,您可以构建易于遵循的良好结构化代码,因为它是结构化的。

当您有非结构化代码从此处跳到那里时,您刚刚发现邪恶来自GOTO语句。几乎总是最好避免这种情况。也许每100.000行中有一个GOTO语句可以简化很多代码的地方,因此代码并不有害,但是如果不确定,则应避免使用GOTO。

希望这可以帮助。

编辑:好吧,只是在这里添加我自己的意见,还有其他一些指令可以让您创建非结构化代码,并且在我认为应该使用时不认为是有害的。

例如,函数中间的返回是转到该函数结尾的位置,因此我避免使用它们,并且在每个函数的末尾仅使用一个返回。

像Vb.Net这样的其他语言(也许还有其他语言)也可以执行Exit For,Exit While,breaks和类似的事情,这些事情也会使代码的结构变得混乱,我认为应该避免。


9
我不敢使用goto,因为任何阅读我的代码的人都可能完全对我失去信心
Carson Myers

我已经有近20年没有使用goto了(组装除外)。即使在我编写(DEC)Fortran时也没有。
Alnitak

1
我的车让我在大街上90度行驶。那不会使它变得邪恶。如果这让我开车90岁,那一定会。在大街上沿着90号行驶会很邪恶,而没有这种能力。
尼克·赖斯

如果您的汽车在不需要90度行驶时让您以90度行驶,那么您的汽车就是邪恶的,因为它为您提供了一些只会伤害您的功能。
Ignacio Soler Garcia

@IgnacioSolerGarcia,如果我所在地区的最高速度限制是70,而每个人都在开车70,并且我需要加速以避免撞车,我衷心希望我的汽车不会达到70。因此,这仍然是问题用过的。枪支,快车和GOTO ...
TecBrat

2

有时(在0.01%的情况下,我的意思是)它很有用,例如当您的脚本很长并且想要测试某些块时。但切勿将其保留在最终脚本中


1

编写用于在cli模式下工作的脚本时,我使用了GOTO。它救了我的命。


我在编写的这个微型框架中使用了goto。CLI的CLI框架。正确的是,goto不能跨文件使用,但是您可以在1个文件上使用它,并将其用作类或函数来控制编程流程。我希望这可以帮助人们思考替代方案。PHP不仅仅是Web编程。
EThaizone Jo

除非在糟糕的Windows Bat文件中调用过函数,否则我从未使用过GOTO甚至continue。请说明为什么需要它。
Mike Q

@MikeQ有时我需要编写守护程序软件来完成一些后台工作。它必须监视来自许多来源的输入并执行我为其分配的任务。对于守护进程,很多人都会使用while(true)它进行编写,因此它可以永远执行下去,直到您将其杀死为止,但这只是肮脏的方式。
EThaizone

有人可能认为GOTO会中断登录流程,因为此命令只能跳过代码中的顺序,但是我认为由开发人员引起的此问题不会因语言而失败。即使您拥有更好的语言,也可以使用simple使其崩溃while()。如果您不使用GOTO,那并不意味着它应该从语言中删除。
EThaizone
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.