问题描述
我有一个网站,用户可以在其中上传图像。该代码有效,它允许用户选择图像(是单独的代码),下面的代码将其保存在本地存储中。我的问题是,假设用户选择了10张图片,其中一张未上传(尺寸或扩展名不正确),其余则上传了。我怎么知道哪个图像没有上传到本地存储并向用户显示该错误,以便他们可以重新上传?
我的代码:
$file_array = reArrayFiles($_FILES['userImages']);
pre_r($file_array);
for($i=0;$i<count($file_array);$i++) {
$name = $file_array[$i]['name'];
$tmpName = $file_array[$i]['tmp_name'];
$size = $file_array[$i]['size'];
$error = $file_array[$i]['error'];
$type = $file_array[$i]['type'];
$fileExtension = explode('.',$name);
$actualExtension = strtolower(end($fileExtension));
$extensionAllowed = array('jpg','jpeg','png','pdf');
if(in_array($actualExtension,$extensionAllowed)) {
if ($error ===0) {
if (size < 1000000) {
$newFileName = uniqid('',true).".".$actualExtension;
$root = $_SERVER["DOCUMENT_ROOT"];
echo $_SERVER['DOCUMENT_ROOT'];
session_start();
$_SESSION['last_id'] = mysqli_insert_id($conn);
$dir = $root.'/userPos/'.$username.'/'.$_SESSION['last_id'].'/';
$_SESSION['dir_name'] = $dir;
if(!file_exists($dir) ) {
mkdir($dir,0755,true);
}
$fileDestionation = $dir.'/'.$newFileName;
move_uploaded_file($tmpName,$fileDestionation);
header("Location: ../profile.php?dirname=".$_SESSION['dir_name']);
} else {
echo "Your file is too big";
}
}else {
echo "There was an error uoloading your file";
}
} else {
echo "You cannot upload files of this type";
}
}
解决方法
以下内容未经测试,但基于我已经使用了几年的代码。我运行了一个版本进行测试,它似乎可以正常运行,但是尚不清楚它是否满足两个问题中提出的目标……但是您可能需要在代码中使用某些东西。
<?php
error_reporting( E_ALL );
session_start();
if( $_SERVER['REQUEST_METHOD']=='POST' ){
$fieldname='userImages'; # the name of the file field in the form.
$username='geronimo'; # test
#$username = $username = $_SESSION['userUsername'].$_SESSION['userId'];
function uploaderror( $error ){
/* utility function to return info about upload errors */
switch( $error ) {
case UPLOAD_ERR_INI_SIZE: return "The uploaded file exceeds the upload_max_filesize directive in php.ini";
case UPLOAD_ERR_FORM_SIZE: return "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form";
case UPLOAD_ERR_PARTIAL: return "The uploaded file was only partially uploaded";
case UPLOAD_ERR_NO_FILE: return "No file was uploaded";
case UPLOAD_ERR_NO_TMP_DIR: return "Missing a temporary folder";
case UPLOAD_ERR_CANT_WRITE: return "Failed to write file to disk";
case UPLOAD_ERR_EXTENSION: return "File upload stopped by extension";
default: return "Unknown upload error";
}
}
if( isset(
$_FILES[ $fieldname ],$_POST['_name'],$_POST['_desc'],$username
)){
/* do not have this... is it the db conn? */
#require '../testing.php';
# pertinent to my dev system
chdir('../../dbo');
require 'db-conn-details.php';
require 'mysqli-conn.php';
$extns = array( 'jpg','jpeg','png','pdf' );
$maxfs = pow( 1024,2 ) * 1; # 1Mb ~ MAX File Size
$root = $_SERVER['DOCUMENT_ROOT'];
$log = array();
$errors = array();
# If images should be deleted if SQL insert fails
# you can use a `transaction` based approach.
$conn->begin_transaction();
$conn->autocommit( false );
/*
seems peculiar having both table and column named `_desc`?
create the `prepared statement` & bind placeholders.
Execute stmt and find number of rows inserted.. should be 1
*/
$sql='insert into `_desc` ( `username`,`_name`,`_desc` ) values ( ?,?,? )';
$stmt=$conn->prepare( $sql );
if( !$stmt ){
/*
this should never be reached in production code...
if it is there is a problem with the table schema
*/
exit('Failed to prepare SQL statement. Check the table design and verify SQL statement is correct.');
}
$stmt->bind_param( 'sss',$username,$_POST['_desc'] );
$stmt->execute();
$rows=$stmt->affected_rows;
$lid=$stmt->insert_id ?: false;
/*
If one row was inserted then proceed to process
all files uploaded. If there is no valid $lid
variable ( Last Insert ID ) do not proceed as
it is used to generate folder structure for the
user.
*/
if( $rows > 0 && $lid ){
$files=(object)$_FILES[ $fieldname ];
foreach( $files->name as $i => $void ){
/* get properties for upload item */
$name = $files->name[$i];
$size = $files->size[$i];
$type = $files->type[$i];
$tmp = $files->tmp_name[$i];
$error= $files->error[$i];
/* find attributes for file */
$ext = pathinfo( $name,PATHINFO_EXTENSION );
list( $width,$height,$type,$attr ) = getimagesize( $tmp );
/* Some tests */
if( !$width or !$height )$errors[]=sprintf( 'The file "%s" does not appear to be a valid image.',$name );
if( !in_array( $ext,$extns ) )$errors[]=sprintf( 'Invalid file extension "%s" for file "%s"',$ext,$name );
if( $size > $maxfs )$errors[]=sprintf( 'File "%s" is too large! Size:"%s",Max:"%s"',$name,$size,$maxfs );
if( $error!==UPLOAD_ERR_OK )$errors[]=sprintf( 'Error:The file "%s" encountered problems. "%s"',uploaderror( $error ) );
if( !is_uploaded_file( $tmp ) )$errors[]=sprintf( 'Warning: The file "%s" might be part of an attack',$name );
/*
At this stage if there are no errors the file
should be moved to it's final location.
*/
if( empty( $errors ) ){
$dir = sprintf( '%s/userPos/%s/%s',$root,$lid );
if( !file_exists( $dir ) )mkdir( $dir,0777,true );
clearstatcache();
$filename=sprintf( '%s.%s',uniqid( '',true ),$ext );
$target=sprintf( '%s/%s',$dir,$filename );
$status=move_uploaded_file( $tmp,$target );
if( !$status ) $errors[]=sprintf('There was a problem saving "%s" as "%s"',$filename );
else{
$log[]=array(
'name' => $name,'size' => $size,'width' => $width,'height' => $height,'filename' => $filename,'folder' => $dir,'status' => $status,'details' => sprintf('"%s" renamed "%s",moved to "%s"',$filename,$dir )
);
}
}
}
}else{
$errors[]='SQL query failed.';
}
if( empty( $errors ) )$conn->commit();
$stmt->free_result();
$stmt->close();
$_SESSION['uploadinfo']=array(
'errors' => $errors,'log' => $log
);
exit( header( sprintf( 'Location: ?dirname=%s',$dir ) ) );
}else{
echo 'Error: initial criteria for processing have not been met';
}
}
?>
<!DOCTYPE html>
<html lang='en'>
<head>
<title>PHP: Multiple file uploads</title>
<meta charset='utf-8' />
<style>
fieldset{border:none;}
label{width:80%;display:block;padding:1rem;}
label > input{float:right;width:80%;}
.errors{color:red}
.info{color:green}
</style>
</head>
<body>
<form method='post' enctype='multipart/form-data'>
<fieldset>
<label>Name: <input type='text' name='_name' /></label>
<label>Description: <input type='text' name='_desc' /></label>
<label>Images:<input type='file' name='userImages[]' multiple /></label>
</fieldset>
<input type='submit' />
<?php
if( !empty( $_SESSION['uploadinfo'] ) ){
if( !empty( $_SESSION['uploadinfo']['errors'] ) ){
printf('
<h1>Errors</h1>
<pre class="errors">%s</pre>',print_r($_SESSION['uploadinfo']['errors'],true)
);
}
if( !empty( $_SESSION['uploadinfo']['log'] ) ){
printf('
<h1>Status</h1>
<pre class="info">%s</pre>',print_r($_SESSION['uploadinfo']['log'],true)
);
}
unset( $_SESSION['uploadinfo'] );
}
?>
</form>
</body>
</html>