PHP 8.1.20 Released!

goto

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Что наихудшее может случиться, если используется goto?
Изображение предоставлено » xkcd

Оператор goto используется для перехода в другую часть программы. Место, куда необходимо перейти указывается с помощью чувствительный к регистру метки, за которой ставится двоеточие, после оператора goto указывается желаемая метка для перехода. Оператор не является неограниченным "goto". Целевая метка должна находиться в том же файле, в том же контексте. Имеется в виду, что вы не можете ни перейти за границы функции или метода, ни перейти внутрь одной из них. Вы также не можете перейти внутрь любой циклической структуры или оператора switch. Но вы можете выйти из них, и обычным применением оператора goto является использование его вместо многоуровневых break.

Пример #1 Пример использования goto

<?php
goto a;
echo
'Foo';

a:
echo
'Bar';
?>

Результат выполнения данного примера:

Bar

Пример #2 Пример использования goto в цикле

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

Результат выполнения данного примера:

j hit 17

Пример #3 Это не сработает

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

Результат выполнения данного примера:

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

add a note

User Contributed Notes 6 notes

up
34
Lollo
2 years ago
You should mention the label can't be a variable
up
12
devbyjesus at example dot com
1 year ago
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 .
up
0
BPI
8 months ago
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);
}
?>
up
-11
firstbitrix at ya dot ru
1 year ago
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!";
    }
}
up
-29
PHP_is_still_great
2 years ago
// 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.
*/
up
-50
instatiendaweb at gmail dot com
2 years ago
$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);
To Top