GOTO是一个好习惯吗?(在这个特殊情况下?)

Dom*_*oSL 3 php generics algorithm

我在向用户提供错误的方式方面存在一些问题.我使用两个Goto指令"解决"了这个问题.请看一下代码:

<?php require_once("registration/include/membersite_config.php"); ?>
    <!DOCTYPE html>
    <html lang="en">
    <head><?php include_once("parts/head.php"); ?></head>
<body>
<div id="footerfix">
<?php include_once("parts/header.php"); ?>
    <div class="container">
        <div class="hero-unit">
<?php
if (isset($_GET['i'])) {
    unlink("users/thumbs/" . $_SESSION["user_code"] . ".jpg");
    header('Location: profile.php?i=mycv');
}
if (isset($_FILES['avatar']['tmp_name'])) {
    $file_ext = end(explode('.', $_FILES['avatar']['name']));
    if (in_array($file_ext, array('jpg', 'jpeg', 'png', 'gif')) == false) {
        echo("<h2>Error!</h2><p>Your profile photo have to be a picture file.</p>");
        goto nomore;
    }
    $src_size = getimagesize($_FILES['avatar']['tmp_name']);
    if ($src_size['mime'] == 'image/jpeg') {
        $src_img = imagecreatefromjpeg($_FILES['avatar']['tmp_name']);
    } elseif ($src_size['mime'] == 'image/png') {
        $src_img = imagecreatefrompng($_FILES['avatar']['tmp_name']);
    } elseif ($src_size['mime'] == 'image/gif') {
        $src_img = imagecreatefromgif($_FILES['avatar']['tmp_name']);
    } else {
        echo("<h2>Error!</h2><p>Incorrect file format.</p>");
        goto nomore;
    }
    $thumb_w = 150;
    if ($src_size[0] <= $thumb_w) {
        $thumb = $src_img;
    } else {
        $new_size[0] = $thumb_w;
        $new_size[1] = ($src_size[1] / $src_size[0]) * $thumb_w;
        $thumb = imagecreatetruecolor($new_size[0], $new_size[1]);
        imagecopyresampled($thumb, $src_img, 0, 0, 0, 0, $new_size[0], $new_size[1], $src_size[0], $src_size[1]);
    }
    imagejpeg($thumb, "users/thumbs/" . $_SESSION["user_code"] . ".jpg");
    //header('Location: profile.php?i=mycv');
    echo('<h2>Ready!</h2><p>Your profile picture is updated. <a href="profile.php">Go back</a>.</p>');
    nomore:
    echo "</div></div>";
    include_once("parts/footer.php");
    echo "</div></body></html>";
}
?>
Run Code Online (Sandbox Code Playgroud)

我从来没有理解为什么goto是代码中可能发生的最糟糕的想法(至少,每个人都这么说),我想听听你对此的看法,如果这真的是最糟糕的想法,我仍然如何使用我的代码他们呢?谢谢!

在此输入图像描述

小智 7

简短的回答为什么GOTO是一个坏主意:可读性受损.考虑一下:

<?php require_once("registration/include/membersite_config.php"); ?>
<!DOCTYPE html>
<html lang="en">
<head><?php include_once("parts/head.php"); ?></head>
  <body><div id="footerfix">
  <?php include_once("parts/header.php"); ?>
    <div class="container">
      <div class="hero-unit">
<?php
if(isset($_GET['i'])){ unlink("users/thumbs/".$_SESSION["user_code"].".jpg"); header('Location: profile.php?i=mycv');}
if(isset($_FILES['avatar']['tmp_name'])){
    $file_ext = end(explode('.',$_FILES['avatar']['name']));
    if(in_array($file_ext,array('jpg','jpeg','png','gif'))==false){
        echo("<h2>Error!</h2><p>Your profile photo have to be a picture file.</p>");
    }
    else {
        $src_size=getimagesize($_FILES['avatar']['tmp_name']);
        if($src_size['mime']=='image/jpeg') {
            $src_img=imagecreatefromjpeg($_FILES['avatar']['tmp_name']);
        } elseif($src_size['mime']=='image/png') {
            $src_img=imagecreatefrompng($_FILES['avatar']['tmp_name']);
        } elseif($src_size['mime']=='image/gif') {
            $src_img=imagecreatefromgif($_FILES['avatar']['tmp_name']);
        } else {
            echo("<h2>Error!</h2><p>Incorrect file format.</p>");
        }
        if(!empty($src_img)) {
            $thumb_w = 150;
            if($src_size[0]<=$thumb_w){
                $thumb=$src_img;
            }else{ 
                $new_size[0] = $thumb_w;
                $new_size[1] = ($src_size[1]/$src_size[0])*$thumb_w;
                $thumb=imagecreatetruecolor($new_size[0],$new_size[1]);
                imagecopyresampled($thumb,$src_img,0,0,0,0,$new_size[0],$new_size[1],$src_size[0],$src_size[1]);
            }
            imagejpeg($thumb,"users/thumbs/".$_SESSION["user_code"].".jpg");
            //header('Location: profile.php?i=mycv');
            echo('<h2>Ready!</h2><p>Your profile picture is updated. <a href="profile.php">Go back</a>.</p>');
        }
    }
}
?>
    </div></div>
    <?php include_once("parts/footer.php"); ?>
</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

无论如何,您应该考虑将模板与逻辑(谷歌"MVC")分开,并至少使用函数进行复杂的操作.


Ham*_*ite 5

你在这里使用goto对我来说似乎是合理的,因为你基本上使用以下模式:

if (error_condition_1) {
    goto handle_errors;
} else {
    // do stuff
}
if (error_condition_2) {
    goto handle_errors;
} else {
    // do stuff
}
// ...
if (last_error_condition) {
    goto handle_errors;
} else {
    // do stuff
}
// do stuff
handle_errors:
    // handling errors
Run Code Online (Sandbox Code Playgroud)

还有其他方法可以做到这一点,不涉及转到; 例如,您可以在适当的位置使用do ... while (false)带有break语句的循环.但是,这实际上只是模糊了你使用goto的事实.

goto在计算机程序员中具有贱民地位,这些日子在很大程度上是不公平的; 在某些情况下,使用goto是一个非常合理的选择(不是大多数情况,我赶紧补充),但一般来说,使用goto可能会让你被捕,无论它是否是一个有效的设计选择.

正如Daniel Brockman所说,你的主要问题是你的代码难以阅读.它似乎挤满了尽可能少的线条,而且非常密集.看看其他人如何在这个网站和其他地方展示他们的代码,看看你是否同意使用其他约定的代码更具可读性.

在PHP中,您需要记住goto仅在5.3版本中可用,因此如果您的代码需要可移植,您可能需要考虑其他选项.