ConFoo Montreal 2017 Calling for Papers

goto

(PHP 5 >= 5.3.0, PHP 7)

What's the worse thing that could happen if you use goto?
Image courtesy of » xkcd

The goto operator can be used to jump to another section in the program. The target point is specified by a label followed by a colon, and the instruction is given as goto followed by the desired target label. This is not a full unrestricted goto. The target label must be within the same file and context, meaning that you cannot jump out of a function or method, nor can you jump into one. You also cannot jump into any sort of loop or switch structure. You may jump out of these, and a common use is to use a goto in place of a multi-level break.

Example #1 goto example

<?php
goto a;
echo 
'Foo';
 
a:
echo 
'Bar';
?>

The above example will output:

Bar

Example #2 goto loop example

<?php
for($i=0,$j=50$i<100$i++) {
  while(
$j--) {
    if(
$j==17) goto end
  }  
}
echo 
"i = $i";
end:
echo 
'j hit 17';
?>

The above example will output:

j hit 17

Example #3 This will not work

<?php
goto loop;
for(
$i=0,$j=50$i<100$i++) {
  while(
$j--) {
    
loop:
  }
}
echo 
"$i = $i";
?>

The above example will output:

Fatal error: 'goto' into loop or switch statement is disallowed in
script on line 2

Note:

The goto operator is available as of PHP 5.3.

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
9 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
2 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
7 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
-28
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
10 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
-50
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
up
-19
ivan dot sammartino at gmail dot com
10 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;
}
?>
To Top