You should mention the label can't be a variable
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
Karikatür, » xkcd'nin izniyle.
goto
işleci betik içinde başka bir komuta atlamak için
kullanılabilir. Hedefin yeri, harf büyüklüğüne duyarlı
bir yafta ve iki nokta imi ile belirtilebilir.
goto
bu yaftaya göre hedefi bulur. Bu,
goto
deyiminin tamamen sınırsız olduğu anlamına gelmez.
Hedef yaftasının aynı dosya ve aynı bağlam içinde kalması gerekir, yani
bir işlev veya yöntemin dışına atlayamayacağınız gibi bir başka işlev veya
yöntemin içine de atlayamazsınız. Ayrıca bir switch veya döngünün içine de
atlayamazsınız, fakat bunların dışına atlayabilirsiniz, yani çok seviyeli
bir break
yerine bir goto
kullanabilirsiniz.
Örnek 1 - goto
örneği
<?php
goto a;
echo 'Foo';
a:
echo 'Bar';
?>
Yukarıdaki örneğin çıktısı:
Bar
Örnek 2 - Döngüden goto
ile çıkma örneği
<?php
for($i=0,$j=50; $i<100; $i++) {
while($j--) {
if($j==17) goto end;
}
}
echo "i = $i";
end:
echo 'j hit 17';
?>
Yukarıdaki örneğin çıktısı:
j hit 17
Örnek 3 - Bu çalışmaz
<?php
goto loop;
for($i=0,$j=50; $i<100; $i++) {
while($j--) {
loop:
}
}
echo "$i = $i";
?>
Yukarıdaki örneğin çıktısı:
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 .
Example to exit loops:
for ($i = 0; $i < 10; $i++) {
for ($j = 0; $j < 10; $j++) {
if ($condition) {
goto exit;
}
}
}
exit:
echo "Out of the loop.";
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);
}
?>
// 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.
*/
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!";
}
}