You should mention the label can't be a variable
goto
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
El operador goto
puede ser usado para saltar a otra
sección en el programa. El punto de destino es especificado mediante una etiqueta
seguida de dos puntos y la instrucción es dada como
goto
seguida de la etiqueta del destino deseado. Este
goto
no es completamente sin restricciones. La etiqueta de
destino debe estar dentro del mismo fichero y contexto, lo que significa que no se puede saltar
fuera de una función o método, ni se puede saltar dentro de uno. Tampoco se
puede saltar dentro de cualquier clase de estructura de bucle o switch. Se puede saltar
fuera de estos y un uso común es utilizar un goto
en lugar de un break
multi-nivel.
Ejemplo #1 Ejemplo de goto
<?php
goto a;
echo 'Foo';
a:
echo 'Bar';
?>
El resultado del ejemplo sería:
Bar
Ejemplo #2 Ejemplo de goto
en un bucle
<?php
for($i=0,$j=50; $i<100; $i++) {
while($j--) {
if($j==17) goto end;
}
}
echo "i = $i";
end:
echo 'j alcanzó 17';
?>
El resultado del ejemplo sería:
j alcanzó 17
Ejemplo #3 Esto no funcionará
<?php
goto loop;
for($i=0,$j=50; $i<100; $i++) {
while($j--) {
loop:
}
}
echo "$i = $i";
?>
El resultado del ejemplo sería:
Fatal error: 'goto' into loop or switch statement is disallowed in script on line 2 (Error fatal: 'goto' hacia el interior de un bucle o sentencia switch no esta permitido en el script en la línea 2)
Nota:
El operador
goto
está disponible a partir de PHP 5.3.
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);