我在向用户呈现错误的方式存在一些问题。我使用两个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>";
}
?>
我从来没有理解为什么goto是代码中可能发生的最糟糕的想法(至少,每个人都这么说),我想听听你对此的看法,如果这真的是最糟糕的想法,那么怎么样?使用我的代码whitout他们?谢谢!
答案 0 :(得分: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>
无论如何,您应该考虑将模板与逻辑(谷歌“MVC”)分开,并至少使用函数进行复杂的操作。
答案 1 :(得分: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
还有其他方法可以做到这一点,不涉及转到;例如,您可以在适当的位置使用do ... while (false)
循环和break
语句。但是,这实际上只是模糊了你使用goto的事实。
goto在计算机程序员中具有贱民地位,这些日子在很大程度上是不公平的;在某些情况下,使用goto是一个完全合理的选择(不是大多数情况,我赶紧补充),但一般来说,使用goto可能会让你陷入困境,无论它是否是一个有效的设计选择。
正如Daniel Brockman所说,你的主要问题是你的代码难以阅读。它似乎挤满了尽可能少的线条,而且非常密集。看看其他人如何在他们的网站和其他地方展示他们的代码,看看你是否同意使用其他约定的代码更具可读性。
在PHP中,您需要记住goto仅在5.3版本中可用,因此如果您的代码需要可移植,您可能需要考虑其他选项。
答案 2 :(得分:2)
Goto通过创建意大利面条代码来介绍问题!换句话说,您将很难理解代码块中代码的流程!总是可以使用结构化控制结构并完全消除gotos!正如着名的计算机科学家Edsger W. Dijkstra所暗示的“Goto”在他1968年的文章“反对GO TO声明的案例”中被认为是有害的(文章由编辑Niklaus Wirth重新命名为“Go To Statement Considered Harmful”)。以控制结构的维基百科条目http://en.wikipedia.org/wiki/Control_structures为出发点。
这个概念适用于所有编程语言!
答案 3 :(得分:2)
你的代码很乱。实施GOTO声明会让它成为一场噩梦。 像XKCD节目一样,会发生可怕的事情。我记得当我开始学习C ++时,术语“Spaghetti代码”经常提到goto用法。它总会搞砸你的执行流程。更不用说它破坏了可读性。
无论如何,我已经为你重组了这个程序,现在应该可以了。
脚本
<?php require_once("registration/include/membersite_config.php");
//redirect user if i is defined
if(isset($_GET['i'])){ unlink("users/thumbs/".$_SESSION["user_code"].".jpg"); header('Location: profile.php?i=mycv');}
?>
<!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
check_file();
function check_file(){
//check for file
if(isset($_FILES['avatar']['tmp_name'])){
//get the file extension
$file_ext = end(explode('.',$_FILES['avatar']['name']));
//validate extension
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>";
return -1;
}
//get the image dimensions
$src_size = getimagesize($_FILES['avatar']['tmp_name']);
switch($src_size['mime']){
case 'image/jpeg':
$src_img=imagecreatefromjpeg($_FILES['avatar']['tmp_name']); break;
case 'image/png':
$src_img=imagecreatefrompng($_FILES['avatar']['tmp_name']); break;
case 'image/gif':
$src_img=imagecreatefromgif($_FILES['avatar']['tmp_name']); break;
default:
echo("<h2>Error!</h2><p>Incorrect file format.</p>");
return -1;
}
$thumb_w = 150;
//if image is within allowed dimensions, set thumbnail as image
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]);
}
//create the updated image
imagejpeg($thumb,"users/thumbs/".$_SESSION["user_code"].".jpg");
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>
如您所见,我将整个过程封装在一个函数中。这样,每当遇到错误时,您都可以执行return
语句。使其成为一种功能还可以实现快速重用。您可以添加一些参数以使其更具动态性。
答案 4 :(得分:0)
GOTO在任何地方都不是一个好习惯。
答案 5 :(得分:0)