文件上传验证问题 PHP
Issue with file uploads validation PHP
我在这方面一直遇到断断续续的问题。这是非常不一致的。我有一个表格,其中有标题(输入)、简短描述(输入)、完整描述(文本区域)和图像上传。 (以下所有相关代码)。
在表单上按下提交后,PHP 脚本会 运行 处理文件上传。在将每个文件从其临时位置移动之前,它会通过一系列 if 语句进行验证。如果验证阶段失败,则应用该条件的 else 语句,并根据问题将 PHP session、'reason' 设置为一个词。 (即 $_SESSION['reason']="invalidfile')。然后用户将被重定向回表单页面,根据 'reason' 的设置,用户会看到一个特定的错误。该第一个验证条件有效(检查所有字段是否已填写)。但是,none 其中在那个之后有效。除了有时它们确实有效。
如能就此问题提供任何帮助,我们将不胜感激。了解有时在 Chrome 中上传图像但页面永远不会进一步重定向到确认页面也可能很有用。这在 Microsoft Edge 中永远不会发生。
HTML 表格 - 标题、简短说明、完整说明、图像文件
// If there is a file uploaded when you redirect back from the confirm page and 'return' is set in the header.
if(isset($_SESSION['file'])){
// For every image uploaded:
for($i = 0; $i < count($_SESSION['file']['destination']); $i++){
// Delete the image because the user is forced to reupload them anyway.
unlink($_SESSION['file']['destination'][$i]);
}
// Unset the 'file' session now we don't need it anymore
unset($_SESSION['file']);
header("Location: index.php?page=createproject");
}
?>
<h1>Create Project</h1>
<p><a href="index.php?page=admin">Go back</a></p>
<form action="index.php?page=createprojectstorefiles" method="post" enctype="multipart/form-data">
<p>Project Title: <input type="text" name="title" maxlength="35" autocomplete="off"
<?php
if(isset($_SESSION['project_details'])){
echo "value='".$_SESSION['project_details']['title']."'";
}
?>
/></p>
<p>Project Images: <input type="file" name="file[]" accept=".png, .jpg, .jpeg" multiple/></p>
<p><label for="textarea" style="vertical-align: top; margin-right: 5px;">Short Descritption: </label><textarea name="short_description" rows="4" cols="60" maxlength="80" style="resize: none;"><?php
if(isset($_SESSION['project_details'])){
echo $_SESSION['project_details']['short_description'];
}
?></textarea></p>
<p><label for="textarea" style="vertical-align: top; margin-right: 5px;">Full Story: </label><textarea name="long_description" rows="15" cols="125" maxlength="5000" style="resize: none;"><?php
if(isset($_SESSION['project_details'])){
echo $_SESSION['project_details']['long_description'];
}
?></textarea></p>
<?php
// If a reason has been sent for the form not working and the user hasn't been logged out.
if(isset($_SESSION['reason'])){
// If a 'reason' has been sent for not logging in.
if(isset($_SESSION['reason'])){
// Tell the user the reason.
if($_SESSION['reason']=="noinput"){
echo "<p><font color='red'><span class='error'>You can't leave any boxes blank</span></font></p>";
} elseif($_SESSION['reason']=="invalidfile"){
echo "<p><font color='red'><span class='error'>The file must be a '.jpg', '.jpeg' or '.png'</span></font></p>";
} elseif($_SESSION['reason']=="uploaderror"){
echo "<p><font color='red'><span class='error'>There was an error uploading your image!</span></font></p>";
} elseif($_SESSION['reason']=="filetoolarge"){
echo "<p><font color='red'><span class='error'>Your file is too large. The max file size is 500MB</span></font></p>";
} elseif($_SESSION['reason']=="success"){
header("Location: index.php?page=createprojectconfirm");
} else{
echo "<p><font color='red'><span class='error'>Something went wrong in validation, contact a network administrator</span></font></p>";
}
// Once the user has been told, unset the session.
unset($_SESSION['reason']);
// Otherise, presume that it's due to an incorrect username or password.
} else{
echo "<p><font color='red'><span class='error'>Something went wrong in validation, contact a network administrator</span></font></p>";
}
}
?>
<p><button type="reset">Reset Form</button> <button type="submit" name="createproject">Preview Project</button></p>
</form>
PHP 脚本 - 验证并从临时文件夹移动上传的文件
// Make sure no reason is set.
if(isset($_SESSION['reason'])){
unset($_SESSION['reason']);
}
if(isset($_SESSION['file'])){
unset($_SESSION['file']);
}
// If the create project form has been submitted:
if(isset($_POST['createproject'])){
// Set all of the variables for the other text boxes in a session called 'project_details'.
$_SESSION['project_details']['title'] = $_POST['title'];
$_SESSION['project_details']['short_description'] = $_POST['short_description'];
$_SESSION['project_details']['long_description'] = $_POST['long_description'];
// If all of the fileds have been filled in:
if(!empty($_POST['title']) && $_FILES['file']['error'][0]=='UPLOAD_ERR_OK' && !empty($_POST['short_description']) && !empty($_POST['long_description'])){
// Count the number of files uploaded.
$fileCount = count($_FILES['file']['name']);
$_SESSION['file']['count'] = $fileCount;
// Do for every uploaded file.
for($i = 0; $i < $fileCount; $i++){
// Set all of the variables for the file upload (file $i).
$file = $_FILES['file'];
$_SESSION['file']['name'] = $_FILES['file']['name'][$i];
$_SESSION['file']['tmpName'] = $_FILES['file']['tmp_name'][$i];
$_SESSION['file']['size'] = $_FILES['file']['size'][$i];
$_SESSION['file']['error'] = $_FILES['file']['error'][$i];
$_SESSION['file']['type'] = $_FILES['file']['type'][$i];
$fileExt = explode(".", $_SESSION['file']['name']);
$_SESSION['file']['actualExt'] = strtolower(end($fileExt));
$allowed = array("jpg", "jpeg", "png");
// If the file type is allowed:
if(in_array($_SESSION['file']['actualExt'], $allowed)){
// If there was no error uploading the file:
if($_SESSION['file']['error'] == 0){
// If the file isn't too large:
if($_SESSION['file']['size'] < 500000){
// Move the file from the temporary location to the new destination and set $_SESSION['reason'] to success so the page redirects to the confirm page. This shouldn't have to be neccesary to make it work but it is. No body on earth knows why.
$fileNameNew = uniqid("", true).".".$_SESSION['file']['actualExt'];
$_SESSION['file']['destination'][$i] = "projects/uploads/".$fileNameNew;
move_uploaded_file($_SESSION['file']['tmpName'], $_SESSION['file']['destination'][$i]);
// Otherwise, inform the user.
} else{
for($i = 0; $i < count($_SESSION['file']['destination']); $i++){
// Delete the image because the user is forced to reupload them anyway.
unlink($_SESSION['file']['destination'][$i]);
}
$_SESSION['reason']="filetoolarge";
header("Location: index.php?page=createproject");
exit();
}
// Otherwise, inform the user.
} else{
for($i = 0; $i < count($_SESSION['file']['destination']); $i++){
// Delete the image because the user is forced to reupload them anyway.
unlink($_SESSION['file']['destination'][$i]);
}
$_SESSION['reason']="uploaderror";
header("Location: index.php?page=createproject");
exit();
}
// Otherwise, inform the user.
} else{
for($i = 0; $i < count($_SESSION['file']['destination']); $i++){
// Delete the image because the user is forced to reupload them anyway.
unlink($_SESSION['file']['destination'][$i]);
}
$_SESSION['reason']="invalidfile";
header("Location: index.php?page=createproject");
exit();
}
}
// After all the files have been uploaded, if the header function doesn't work, use the session method to redirect to the complete page.
if(!header("Location: index.php?page=createprojectconfirm")){
$_SESSION['reason']="success";
exit();
}
// Otherwise, inform the user.
} else{
$_SESSION['reason']="noinput";
header("Location: index.php?page=createproject");
exit();
}
} else{
header("Location: index.php?page=admin");
exit();
}
问题出在第一段代码上。如果用户从预览页面 returned,顶部有一个 if 语句来取消设置会话 'file'。这包含加载页面时设置 if 'file' 的条件。这种情况也可能不仅存在于用户 return 从预览页面编辑时,因为他们选择这样做,而且如果出现错误。此 if 语句然后重新加载页面,从而清除 'reason' 会话并且错误不显示。
我通过编辑 if 语句的条件修复了它。通过添加检查以确保未设置 'reason' 会话,即没有错误,但用户选择了 return:
if(isset($_SESSION['file']) && !isset($_SESSION['reason'])){
// For every image uploaded:
for($i = 0; $i < count($_SESSION['file']['destination']); $i++){
// Delete the image because the user is forced to reupload them anyway.
unlink($_SESSION['file']['destination'][$i]);
}
// Unset the 'file' session now we don't need it anymore
unset($_SESSION['file']);
header("Location: index.php?page=createproject");
}
我在这方面一直遇到断断续续的问题。这是非常不一致的。我有一个表格,其中有标题(输入)、简短描述(输入)、完整描述(文本区域)和图像上传。 (以下所有相关代码)。
在表单上按下提交后,PHP 脚本会 运行 处理文件上传。在将每个文件从其临时位置移动之前,它会通过一系列 if 语句进行验证。如果验证阶段失败,则应用该条件的 else 语句,并根据问题将 PHP session、'reason' 设置为一个词。 (即 $_SESSION['reason']="invalidfile')。然后用户将被重定向回表单页面,根据 'reason' 的设置,用户会看到一个特定的错误。该第一个验证条件有效(检查所有字段是否已填写)。但是,none 其中在那个之后有效。除了有时它们确实有效。
如能就此问题提供任何帮助,我们将不胜感激。了解有时在 Chrome 中上传图像但页面永远不会进一步重定向到确认页面也可能很有用。这在 Microsoft Edge 中永远不会发生。
HTML 表格 - 标题、简短说明、完整说明、图像文件
// If there is a file uploaded when you redirect back from the confirm page and 'return' is set in the header.
if(isset($_SESSION['file'])){
// For every image uploaded:
for($i = 0; $i < count($_SESSION['file']['destination']); $i++){
// Delete the image because the user is forced to reupload them anyway.
unlink($_SESSION['file']['destination'][$i]);
}
// Unset the 'file' session now we don't need it anymore
unset($_SESSION['file']);
header("Location: index.php?page=createproject");
}
?>
<h1>Create Project</h1>
<p><a href="index.php?page=admin">Go back</a></p>
<form action="index.php?page=createprojectstorefiles" method="post" enctype="multipart/form-data">
<p>Project Title: <input type="text" name="title" maxlength="35" autocomplete="off"
<?php
if(isset($_SESSION['project_details'])){
echo "value='".$_SESSION['project_details']['title']."'";
}
?>
/></p>
<p>Project Images: <input type="file" name="file[]" accept=".png, .jpg, .jpeg" multiple/></p>
<p><label for="textarea" style="vertical-align: top; margin-right: 5px;">Short Descritption: </label><textarea name="short_description" rows="4" cols="60" maxlength="80" style="resize: none;"><?php
if(isset($_SESSION['project_details'])){
echo $_SESSION['project_details']['short_description'];
}
?></textarea></p>
<p><label for="textarea" style="vertical-align: top; margin-right: 5px;">Full Story: </label><textarea name="long_description" rows="15" cols="125" maxlength="5000" style="resize: none;"><?php
if(isset($_SESSION['project_details'])){
echo $_SESSION['project_details']['long_description'];
}
?></textarea></p>
<?php
// If a reason has been sent for the form not working and the user hasn't been logged out.
if(isset($_SESSION['reason'])){
// If a 'reason' has been sent for not logging in.
if(isset($_SESSION['reason'])){
// Tell the user the reason.
if($_SESSION['reason']=="noinput"){
echo "<p><font color='red'><span class='error'>You can't leave any boxes blank</span></font></p>";
} elseif($_SESSION['reason']=="invalidfile"){
echo "<p><font color='red'><span class='error'>The file must be a '.jpg', '.jpeg' or '.png'</span></font></p>";
} elseif($_SESSION['reason']=="uploaderror"){
echo "<p><font color='red'><span class='error'>There was an error uploading your image!</span></font></p>";
} elseif($_SESSION['reason']=="filetoolarge"){
echo "<p><font color='red'><span class='error'>Your file is too large. The max file size is 500MB</span></font></p>";
} elseif($_SESSION['reason']=="success"){
header("Location: index.php?page=createprojectconfirm");
} else{
echo "<p><font color='red'><span class='error'>Something went wrong in validation, contact a network administrator</span></font></p>";
}
// Once the user has been told, unset the session.
unset($_SESSION['reason']);
// Otherise, presume that it's due to an incorrect username or password.
} else{
echo "<p><font color='red'><span class='error'>Something went wrong in validation, contact a network administrator</span></font></p>";
}
}
?>
<p><button type="reset">Reset Form</button> <button type="submit" name="createproject">Preview Project</button></p>
</form>
PHP 脚本 - 验证并从临时文件夹移动上传的文件
// Make sure no reason is set.
if(isset($_SESSION['reason'])){
unset($_SESSION['reason']);
}
if(isset($_SESSION['file'])){
unset($_SESSION['file']);
}
// If the create project form has been submitted:
if(isset($_POST['createproject'])){
// Set all of the variables for the other text boxes in a session called 'project_details'.
$_SESSION['project_details']['title'] = $_POST['title'];
$_SESSION['project_details']['short_description'] = $_POST['short_description'];
$_SESSION['project_details']['long_description'] = $_POST['long_description'];
// If all of the fileds have been filled in:
if(!empty($_POST['title']) && $_FILES['file']['error'][0]=='UPLOAD_ERR_OK' && !empty($_POST['short_description']) && !empty($_POST['long_description'])){
// Count the number of files uploaded.
$fileCount = count($_FILES['file']['name']);
$_SESSION['file']['count'] = $fileCount;
// Do for every uploaded file.
for($i = 0; $i < $fileCount; $i++){
// Set all of the variables for the file upload (file $i).
$file = $_FILES['file'];
$_SESSION['file']['name'] = $_FILES['file']['name'][$i];
$_SESSION['file']['tmpName'] = $_FILES['file']['tmp_name'][$i];
$_SESSION['file']['size'] = $_FILES['file']['size'][$i];
$_SESSION['file']['error'] = $_FILES['file']['error'][$i];
$_SESSION['file']['type'] = $_FILES['file']['type'][$i];
$fileExt = explode(".", $_SESSION['file']['name']);
$_SESSION['file']['actualExt'] = strtolower(end($fileExt));
$allowed = array("jpg", "jpeg", "png");
// If the file type is allowed:
if(in_array($_SESSION['file']['actualExt'], $allowed)){
// If there was no error uploading the file:
if($_SESSION['file']['error'] == 0){
// If the file isn't too large:
if($_SESSION['file']['size'] < 500000){
// Move the file from the temporary location to the new destination and set $_SESSION['reason'] to success so the page redirects to the confirm page. This shouldn't have to be neccesary to make it work but it is. No body on earth knows why.
$fileNameNew = uniqid("", true).".".$_SESSION['file']['actualExt'];
$_SESSION['file']['destination'][$i] = "projects/uploads/".$fileNameNew;
move_uploaded_file($_SESSION['file']['tmpName'], $_SESSION['file']['destination'][$i]);
// Otherwise, inform the user.
} else{
for($i = 0; $i < count($_SESSION['file']['destination']); $i++){
// Delete the image because the user is forced to reupload them anyway.
unlink($_SESSION['file']['destination'][$i]);
}
$_SESSION['reason']="filetoolarge";
header("Location: index.php?page=createproject");
exit();
}
// Otherwise, inform the user.
} else{
for($i = 0; $i < count($_SESSION['file']['destination']); $i++){
// Delete the image because the user is forced to reupload them anyway.
unlink($_SESSION['file']['destination'][$i]);
}
$_SESSION['reason']="uploaderror";
header("Location: index.php?page=createproject");
exit();
}
// Otherwise, inform the user.
} else{
for($i = 0; $i < count($_SESSION['file']['destination']); $i++){
// Delete the image because the user is forced to reupload them anyway.
unlink($_SESSION['file']['destination'][$i]);
}
$_SESSION['reason']="invalidfile";
header("Location: index.php?page=createproject");
exit();
}
}
// After all the files have been uploaded, if the header function doesn't work, use the session method to redirect to the complete page.
if(!header("Location: index.php?page=createprojectconfirm")){
$_SESSION['reason']="success";
exit();
}
// Otherwise, inform the user.
} else{
$_SESSION['reason']="noinput";
header("Location: index.php?page=createproject");
exit();
}
} else{
header("Location: index.php?page=admin");
exit();
}
问题出在第一段代码上。如果用户从预览页面 returned,顶部有一个 if 语句来取消设置会话 'file'。这包含加载页面时设置 if 'file' 的条件。这种情况也可能不仅存在于用户 return 从预览页面编辑时,因为他们选择这样做,而且如果出现错误。此 if 语句然后重新加载页面,从而清除 'reason' 会话并且错误不显示。
我通过编辑 if 语句的条件修复了它。通过添加检查以确保未设置 'reason' 会话,即没有错误,但用户选择了 return:
if(isset($_SESSION['file']) && !isset($_SESSION['reason'])){
// For every image uploaded:
for($i = 0; $i < count($_SESSION['file']['destination']); $i++){
// Delete the image because the user is forced to reupload them anyway.
unlink($_SESSION['file']['destination'][$i]);
}
// Unset the 'file' session now we don't need it anymore
unset($_SESSION['file']);
header("Location: index.php?page=createproject");
}