You should mention the label can't be a variable
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
O operador goto
pode ser usado para pular para outra
seção do programa. O ponto de destino é definido por um rótulo sensível a maiúsculas e minúsculas
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 produzirá:
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 produzirá:
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 produzirá:
Fatal error: 'goto' into loop or switch statement is disallowed in script on line 2
the problem of goto is that it is a good feature but in a large codebase it reduces the readability of the code . that's all . i try to not use it to think about the person who is going to read after me .
You can jump inside the same switch. This can be usefull to jump to default
<?php
$x=3;
switch($x){
case 0:
case 3:
print($x);
if($x)
goto def;
case 5:
$x=6;
default:
def:
print($x);
}
?>
I found a good way to use goto for walking through a foreach iteration one another time in order not to walk through whole array once again or not to use special and mostly complex if...else constructions.
But don't forget to make an exit from the goto loop if the iteration of rewalking reaches to many attemptions.
Brief example:
foreach ($fooArray as $foo) {
$attemptionLimit = 0;
restartIteration:
if (++$attemptionLimit > 10) {
continue;
}
$result = $foo->doSomething();
if (!$result) {
$foo->doSomethingElse($attemptionLimit);
goto restartIteration;
} else {
echo "Done!";
}
}
// goto is STILL a good feature if you know how to use it.
// Just don't use it in loops.
// Example:
$sql = "DELETE FROM sometable WHERE id=?;";
$stmt = $conn->prepare($sql);
if (!$stmt) {
echo "ERR prepare_fail";
goto End;
}
$bind = $stmt->bind_param('i', $id);
if (!$bind) {
echo "ERR bind_fail";
goto End;
}
$exec = $stmt->execute();
if (!$exec) {
echo "ERR exec_fail";
goto End;
}
if (isset($_POST['file'])) {
$file = "../" . $_POST['file'];
if (is_file($file)) { unlink($file); }
}
echo "OK delete_success" ;
End:
$stmt->close();
$conn->close();
exit;
/*
instead of repeating the $stmt->close() and $conn->close(),
we save a few lines by adding a goto and just close everything at the end.
*/
$array = array();
for ($i = 0; $i <= 10; (int)$array[] = $i, $i++);
var_dump($array );
$countarray = (count($array) - 2) ;
var_dump($countarray);
static $goto = 0;
/***************************************************************************************************/
b:
$array[$goto] = $array[$goto] * 2;
if ($goto <= $countarray){
$goto++;
goto b;
}else{
goto a;}
a:
/***************************************************************************************************/
var_dump($array);