goto

(PHP 5 >= 5.3.0, PHP 7)

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及以上版本有效。

xkcd-goto.png
此漫画鸣谢 » xkcd

add a note add a note

User Contributed Notes 11 notes

up
48
chrisstocktonaz at gmail dot com
7 years ago
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;
        }
    }
}
?>
up
33
Ray dot Paseur at Gmail dot com
4 years ago
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';
?>
up
6
D. Kellner
10 months ago
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.
up
9
sixoclockish at gmail dot com
4 years ago
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:
?>
up
5
f at francislacroix dot info
4 years ago
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.
up
-1
kle at lekhoi dot com
3 months ago
Goto can also go into an infinite loop as the example below.

<?php

goto start;

start: echo 'start';

working: {
    echo
'working';
    ...
    goto
start;
    echo
'never executed';
}
?>

Output
startworkingstartworking ...
up
-11
robert
8 months ago
goto is not evil because it can break your code , it's evil because it's unpredictable for the CPU , so it will be a lot inefficient because that mean your processor will likely pre-load wrong code and will have to reload the code every time goto is used
it's what i had learned in the computer architecture course
up
-29
ryan DOT jentzsch AT NOSPAM [G]mail com
1 year ago
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.
up
-8
ivan dot tc at gmail dot com
11 months ago
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
up
-19
ivan dot sammartino at gmail dot com
11 months ago
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;
}
?>
up
-51
fff at hotmail dot com
1 year ago
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
To Top