PHP 7.0.6 Released

goto

(PHP 5 >= 5.3.0, PHP 7)

Qual é a pior coisa que pode acontecer ao se utilizar o goto?
Imagem cortesia do » xkcd

O operador goto pode ser usado para pular para outra seção do programa. O ponto de destino é definido por um rótulo seguido de dois pontos, e a instrução é usada como goto seguida do rótulo de destino desejado. O uso do goto não é completamente irrestrito. O rótulo de destino deve estar no mesmo arquivo e contexto, significando que não se pode pular para fora ou para dentro de uma função ou método. Também não pode-se saltar para dentro de um laço ou estrutura switch. Pode-se saltar para fora deles, e um uso comum é usar o goto no lugar de um break multi-nível.

Exemplo #1 Exemplo da estrutura de controle goto

<?php
goto a;
echo 
'Foo';

a:
echo 
'Bar';
?>

O exemplo acima irá imprimir:

Bar

Exemplo #2 Exemplo da estrutura de controle goto em um laço

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

O exemplo acima irá imprimir:

j hit 17

Exemplo #3 Isto não irá funcionar

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

O exemplo acima irá imprimir:

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

Nota:

O operador goto está disponível desde o PHP 5.3.

add a note add a note

User Contributed Notes 10 notes

up
39
chrisstocktonaz at gmail dot com
6 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
5
D. Kellner
5 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
26
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
9
sixoclockish at gmail dot com
3 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
4
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
-16
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
robert
3 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
-13
ivan dot sammartino at gmail dot com
6 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
-47
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
-5
ivan dot tc at gmail dot com
6 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
To Top