©
Ce document utilise Manuel du site Web PHP chinois Libérer
(PHP 5 >= 5.3.0)
goto 操作符可以用来跳转到程序中的另一位置。该目标位置可以用目标名称加上冒号来标记,而跳转指令是 goto 之后接上目标位置的标记。PHP 中的 goto 有一定限制,目标位置只能位于同一个文件和作用域,也就是说无法跳出一个函数或类方法,也无法跳入到另一个函数。也无法跳入到任何循环或者 switch 结构中。可以跳出循环或者 switch,通常的用法是用 goto 代替多层的 break。
Example #1 goto 示例
<?php
goto a ;
echo 'Foo' ;
a :
echo 'Bar' ;
?>
以上例程会输出:
Bar
Example #2 goto 跳出循环示例
<?php
for( $i = 0 , $j = 50 ; $i < 100 ; $i ++) {
while( $j --) {
if( $j == 17 ) goto end ;
}
}
echo "i = $i " ;
end :
echo 'j hit 17' ;
?>
以上例程会输出:
j hit 17
Example #3 以下写法无效
<?php
goto loop ;
for( $i = 0 , $j = 50 ; $i < 100 ; $i ++) {
while( $j --) {
loop :
}
}
echo " $i = $i " ;
?>
以上例程会输出:
Fatal error: 'goto' into loop or switch statement is disallowed in script on line 2
Note:
goto 操作符仅在 PHP 5.3及以上版本有效。
[#1] D. Kellner [2015-10-31 14:12:02]
However hated, goto is useful. When we say "useful" we don't mean "it should be used all the time" but that there are certain situations when it comes in handy.
There are times when you need a logical structure like this:
<?php
// ...
do {
$answer = checkFirstSource();
if(seemsGood($answer)) break;
$answer = readFromAnotherSource();
if(seemsGood($answer)) break;
// ...
}while(0);
$answer = applyFinalTouches($answer);
return $answer;
?>
In this case, you certainly implemented a goto with a "fake loop pattern". It could be a lot more readable with a goto; unless, of course, you hate it. But the logic is clear: try everything you can to get $answer, and whenever it seems good (e.g. not empty), jump happily to the point where you format it and give it back to the caller. It's a proper implementation of a simple fallback mechanism.
Basically, the fight against goto is just a side effect of a misleading article many decades ago. Those monsters are gone now. Feel free to use it when you know what you're doing.
[#2] ivan dot tc at gmail dot com [2015-10-23 02:10:34]
This works good:
<?php
goto start;
five:
echo $i;
goto end;
start:
echo 'I have ';
for ($i=0; $i < 10; $i++) {
if ($i == 5) {
goto five;
}
}
end:
echo ' apples';
?>
Output: I have 5 apples.
This don't work:
<?php
goto start;
five:
echo $i;
goto end;
start:
echo 'I have ';
$count();
end:
echo ' apples';
$count = function () {
for ($i=0; $i < 10; $i++) {
if ($i == 5) {
goto five; // line 18
}
}
}
?>
PHP Fatal error: 'goto' to undefined label 'five' on line 18
[#3] ivan dot sammartino at gmail dot com [2015-10-13 11:38:20]
I found it useful for switch statements:
<?php
$action = $_GET['action'];
switch ($action){
case('a'):
mylabel: {
doStuff();
break;
}
case('b'):
if (true){
doAnotherStuff();
} else {
goto mylabel;
}
break;
}
?>
[#4] ryan DOT jentzsch AT NOSPAM [G]mail com [2015-04-21 17:20:27]
Like the eval() function; if GOTO is the answer then you are definitely asking the wrong question.
GOTO is the daredevil of all programming languages. Like Evil Knievel the GOTO can jump from one place in your code to a completely different place with no return.
Knievel broke nearly every bone in his body making his jumps. GOTO will absolutely break your apps bones.
Google "Spaghetti code" for how GOTO is used. Like the eval() function; if GOTO is the answer then you are definitely asking the wrong question.
GOTO is the daredevil of all programming languages. Like Evil Knievel the GOTO can jump from one place in your code to a completely different place with no return.
Knievel broke nearly every bone in his body making his jumps. GOTO will absolutely break your apps bones.
Google "Spaghetti code" for how GOTO is used.
[#5] fff at hotmail dot com [2015-02-27 10:01:42]
goto is actually really sweet once you learn to use it correctly, it will give you a smaller object in the end, and less ascii code. Those who dont know what instruction the goto statement will be parsed into should probably stay away :P
[#6] sixoclockish at gmail dot com [2012-06-14 07:58:10]
You are also allowed to jump backwards with a goto statement. To run a block of goto as one block is as follows:
example has a prefix of iw_ to keep label groups structured and an extra underscore to do a backwards goto.
Note the `iw_end_gt` to get out of the labels area
<?php
$link = true;
if ( $link ) goto iw_link_begin;
if(false) iw__link_begin:
if ( $link ) goto iw_link_text;
if(false) iw__link_text:
if ( $link ) goto iw_link_end;
if(false) iw__link_end:
goto iw_end_gt;
if (false) iw_link_begin:
echo '<a href="#">';
goto iw__link_begin;
if (false) iw_link_text:
echo 'Sample Text';
goto iw__link_text;
if (false) iw_link_end:
echo '</a>';
goto iw__link_end;
iw_end_gt:
?>
[#7] f at francislacroix dot info [2011-11-30 13:11:48]
The goto operator CAN be evaluated with eval, provided the label is in the eval'd code:
<?php
a: eval("goto a;"); // undefined label 'a'
eval("a: goto a;"); // works
?>
It's because PHP does not consider the eval'd code, containing the label, to be in the same "file" as the goto statement.
[#8] Ray dot Paseur at Gmail dot com [2011-10-27 06:59:03]
You cannot implement a Fortran-style "computed GOTO" in PHP because the label cannot be a variable. See: http://en.wikipedia.org/wiki/Considered_harmful
<?php // RAY_goto.php
error_reporting(E_ALL);
// DEMONSTRATE THAT THE GOTO LABEL IS CASE-SENSITIVE
goto a;
echo 'Foo';
a: echo 'Bar';
goto A;
echo 'Foo';
A: echo 'Baz';
// CAN THE GOTO LABEL BE A VARIABLE?
$a = 'abc';
goto $a; // NOPE: PARSE ERROR
echo 'Foo';
abc: echo 'Boom';
?>
[#9] chrisstocktonaz at gmail dot com [2009-08-07 15:03:50]
Remember if you are not a fan of wild labels hanging around you are free to use braces in this construct creating a slightly cleaner look. Labels also are always executed and do not need to be called to have their associated code block ran. A purposeless example is below.
<?php
$headers = Array('subject', 'bcc', 'to', 'cc', 'date', 'sender');
$position = 0;
hIterator: {
$c = 0;
echo $headers[$position] . PHP_EOL;
cIterator: {
echo ' ' . $headers[$position][$c] . PHP_EOL;
if(!isset($headers[$position][++$c])) {
goto cIteratorExit;
}
goto cIterator;
}
cIteratorExit: {
if(isset($headers[++$position])) {
goto hIterator;
}
}
}
?>