php - 将多张照片上传(并重命名)到服务器
问题描述
即使我不擅长开发,我也在尝试创建一个表单,允许将多张照片上传到服务器并将文本上传到数据库。
对于文本,没有问题。也上传一张照片,这很好。
我不能做的是在一个表单提交中上传几张照片。 我应该使用while还是for或foreach循环?如果是这样,我如何检索照片信息?我指定我不尝试使用“Multiple”功能。即使文件以相同的形式上传,用户也必须使用单独的“文件上传”字段。
我指定要在上传期间重命名文件。 使用下面的代码,上传工作,但只有第一个文件的重命名工作。第二个(当然还有以下几个)被严重重命名。第二个例子:
78_One Plus_Nouveau test_FaceProduct_pic03.jpgpic04.jpg
我需要一些帮助来创建上传图像过程的循环并正确重命名图像文件吗?
error_reporting(E_ALL);
// Then retrieve all the other information from the form:
$productname = isset($_POST['productname']) ? $_POST['productname'] : NULL;
$productbrand = isset($_POST['productbrand']) ? $_POST['productbrand'] : NULL;
$addername = isset($_POST['addername']) ? $_POST['addername'] : NULL;
$adderemail = isset($_POST['adderemail']) ? $_POST['adderemail'] : NULL;
// paramètres de connexion
$cbnserver = "xxxxxx";
$cbnuser = "xxxxxxxxx";
$cbnpass = "xxxxxxxxx";
$cbndbname = "xxxxxxxxxxxxx";
// Requête d'insertion dans la base
$dbco = new PDO("mysql:host=$cbnserver;dbname=$cbndbname", $cbnuser, $cbnpass);
$dbco->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$req = $dbco->prepare('INSERT INTO `cbnadd_newproduct` (productname, productbrand, addername, adder_email) VALUES(:productname,:productbrand,:addername,:adder_email)');
$req->execute(array(
'productname' => $productname,
'productbrand' => $productbrand,
'addername' => $addername,
'adder_email' => $adderemail
));
$lineid = $dbco->lastInsertId() ;
// Designate the directory where the images will be saved with this code:
$targetFA = "images/". $lineid ."_". $productbrand ."_". $productname ."_FaceProduct_";
$targetFA = $targetFA . basename( $_FILES['photoFA']['name']);
$targetNV = "images/". $lineid ."_". $productbrand ."_". $productname ."_FaceProduct_";
$targetNV = $targetFA . basename( $_FILES['photoNV']['name']);
// This writes the photo to the server
$namefileFA = basename( $_FILES['photoFA']['name']);
$namefileFA = $lineid ."_". $productbrand ."_". $productname ."_". $namefileFA;
$namefileNV = basename( $_FILES['photoFA']['name']);
$namefileNV = $lineid ."_". $productbrand ."_". $productname ."_". $namefileNV;
if(move_uploaded_file($_FILES['photoFA']['tmp_name'],$targetFA) & move_uploaded_file($_FILES['photoNV']['tmp_name'],$targetNV)) {
// This code tells you if it is all ok or not.
echo "<br><br>The file ". $namefileFA. " and has been uploaded, and your information has been added to the directory<br>";
echo "<br><br>The file ". $namefileNV. " has been uploaded, and your information has been added to the directory<br>";
} else {
echo "<br><br>Sorry, there was a problem uploading your file.";
}
这里是照片字段的 HTML 代码:
<form enctype="multipart/form-data" action="../add.php" method="POST">
<!--Product Name: --><input type="text" name="productname"><br>
<h3>Brand</h3>
<!--Brand: --><input type="text" name = "productbrand"><br>
Importer les photos du produit:
<label for="fileFA" class="label-file" style="cursor:pointer; color:#00b1ca; font-weight:bold;">Couverture/face du produit</label>
<input id="fileFA" class="input-file" type="file" name="photoFA" style="display: none;">
<!--<input type="file" name="photo"><br>-->
<label for="fileNV" class="label-file" style="cursor:pointer; color:#00b1ca; font-weight:bold;">Tableau nutritionnel du produit</label>
<input id="fileNV" class="input-file" type="file" name="photoNV" style="display: none;">
Your name: <input type="text" name = "addername"><br>
Adder email: <input type="text" name = "adderemail"><br>
<input type="submit" value="Add" class="centered">
</form>
解决方案
谢谢@Professor 我创建了表格,测试了页面,但有两件事很奇怪:
- 消息有问题,照片的名称没有出现。
- 即使我插入一张照片,系统也会在数据库中更新 4 行。
这是我收到的消息:
文件“130_Candy_Produit_FaceProduct_pic01.jpg”已上传成功。信息已添加到目录中:True 保存“130_Candy_Produit_NutritionValue_”时出现问题。记录到 db 的信息:True 保存“130_Candy_Produit_Ingredients_”时出现问题。记录到 db 的信息:True 保存“130_Candy_Produit_Labels_”时出现问题。记录到 db 的信息:真
这里的代码:
error_reporting( E_ALL );
class PostException extends Exception {
public function __construct( $msg=null, $code=null ){
parent::__construct( $msg, $code );
}
public function geterror(){
return $this->getMessage();
}
}
if( $_SERVER['REQUEST_METHOD']=='POST' ){
try{
#look at the form - see how it is using this for image name
$field='productimage';
if( isset(
$_FILES[ $field ],
$_POST['productname'],
$_POST['productbrand'],
$_POST['addername'],
$_POST['adder_email']
) ){
$errors=array();
$uploads=array();
$files=array();
$lineid=false;
$dbstatus=false;
#################################
# edit this as appropriate...
$dir=__DIR__ . '/imagesStack';
# the names of the various fields in the form - not images
$args=array(
'productname',
'productbrand',
'addername',
'adder_email'
);
/*
loop through the `$args` array - if a field in the FORM
is not set or empty throw & catch a custom exception -
the errors will be displayed later.
If no errors, generate the variables based upon the name of
the field using variable variables.
*/
foreach( $args as $fieldname ){
try{
if( !isset( $_POST[ $fieldname ] ) or empty( $_POST[ $fieldname ] ) )throw new PostException( sprintf( 'Missing data: The field "%s" is required.', $fieldname ) );
else{
${$fieldname}=$_POST[ $fieldname ];
}
}catch( PostException $e ){
$errors[]=$e->geterror();
continue;
}
}
if( empty( $errors ) ){
$args=array(
'host' => 'localhost',
'user' => 'FFFFF',
'pwd' => 'EEEEEEEE',
'db' => 'GGGGGGGGGG'
);
mysqli_report( MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT );
$db=new mysqli( ...array_values( $args ) );
$db->set_charset('utf8');
$db->begin_transaction();
#create the basic sql and prepared statement
$sql='insert into `cbnadd_newproduct`
( `productname`, `productbrand`, `addername`, `adder_email` )
values
( ?,?,?,? )';
$stmt=$db->prepare( $sql );
/* bind params and execute */
$stmt->bind_param('ssss', $productname, $productbrand, $addername, $adder_email );
$dbstatus=$stmt->execute();
/* get the ID of the last inserted record */
$lineid=$db->insert_id;
$stmt->close();
/*
It would be usual to record the names / paths of images
that you upload so I created a new table for that purpose
*/
# insert records for new images to other table.
$sql='insert into `cbnadd_productimages` (`lineid`,`image`) values (?,?)';
$stmt=$db->prepare( $sql );
$stmt->bind_param('is', $lineid, $targetname );
/*
Process the file uploads - using the Array syntax
means you can easily loop through all the files &
rename and log to db.
*/
$obj=$_FILES[ $field ];
foreach( $obj['name'] as $index => $void ){
$name=$obj['name'][ $index ];
$tmp=$obj['tmp_name'][ $index ];
# new image name format "id_brand_product_category_filename.ext"
$targetname=sprintf('%d_%s_%s_%s_%s', $lineid, $productbrand, $productname, $index, $name );
# full path for the image to be saved to
$targetpath=sprintf('%s/%s', $dir, $targetname );
# move the file
$status=move_uploaded_file( $tmp, $targetpath );
# upload the output variable
$uploads[]=$status ? sprintf('The file "%s" has been uploaded OK. Information has been added to the directory: %s', $targetname, ( $dbstatus ? 'True' : 'False' ) ) : sprintf('There was a problem saving "%s". Information logged to db: %s ',$targetname, ( $dbstatus ? 'True' : 'False' ) );
# maintain a list of files to be used if db operation fails.
$files[]=$targetpath;
# save image details... or try to
$stmt->execute();
}
#commit to database or erase files if there is a problem
if( !$db->commit() ) {
$errors[]='Failed to commit transaction';
foreach( $files as $file ){
unlink( $file );
$errors[]=sprintf('File deleted: "%s"',$file);
}
$uploads=[];
}
}
}
}catch( Exception $e ){
$errors[]=$e->getMessage();
}
}
?>
<!DOCTYPE html>
<html lang='en'>
<head>
<title>PHP: Multiple file uploads - different inputs</title>
<meta charset='utf-8' />
<style>
form{width:60%;float:none;margin:1rem auto;padding:0.5rem 1rem;font-family:monospace;border:1px dashed gray;border-radius:0.5rem;background:whitesmoke;}
label{width:80%;margin:0.5rem auto;display:block;float:none;padding:0.25rem;}
label > input{float:right;width:75%;}
fieldset{margin:1rem auto;padding:1rem;border:1px solid rgba(100,100,100,0.5);background:white;border-radius:0.5rem;}
form > div{margin:1rem auto}
[type='submit']{padding:1rem;}
legend{background:rgba(100,100,100,0.5);color:white;padding:0.5rem;border-radius:0.5rem;min-width:20%;}
.error{color:red;}
.success{color:green;}
</style>
</head>
<body>
<form name='uploads' method='post' enctype='multipart/form-data'>
<fieldset>
<legend>Product</legend>
<label>Name:<input type='text' name='productname' /></label>
<label>Brand:<input type='text' name='productbrand' /></label>
</fieldset>
<fieldset>
<legend>Product images</legend>
<label>Image-Face:<input type='file' name='productimage[FaceProduct]' /></label>
<label>Image-Nutrition:<input type='file' name='productimage[NutritionValue]' /></label>
<!-- other images could be added using same method but different index values ~ EG: -->
<label>Image-Ingredients:<input type='file' name='productimage[Ingredients]' /></label>
<label>Image-Labels:<input type='file' name='productimage[Labels]' /></label>
</fieldset>
<fieldset>
<legend>User details</legend>
<label>Added by:<input type='text' name='addername' /></label>
<label>Email:<input type='text' name='adder_email' /></label>
</fieldset>
<fieldset>
<input type='submit' />
</fieldset>
<div>
<?php
if( $_SERVER['REQUEST_METHOD']=='POST' ){
if( !empty( $uploads ) ){
foreach( $uploads as $message )printf('<div class="success">%s</div>',$message);
}
if( !empty( $errors ) ){
foreach( $errors as $message )printf('<div class="error">%s</div>',$message);
}
}
?>
</div>
</form>
</body>
</html>
推荐阅读
- json - 在 Jinja2 模板中循环 Ansible 变量数组以创建嵌套字典
- jsdoc - 如何使用 JSDoc 注释返回此副本的方法?
- python - Python 解码 | 字节到 json
- node.js - ScrollConsoleScreenBuffer 影响裁剪矩形外的数据
- sql - 是否可以在 SQL Server 中使用通配符作为 OPENJSON 的参数?
- swift - 如何在后台强制 macOS 应用程序更新?
- android - NoSuchFieldException:类 Landroid/widget/ImageView 中没有字段 mMaxWidth
- git - 我在 git 中一次提交了 10 个文件,但现在我怎样才能只恢复其中的 2 个
- reactjs - 在useState问题之前调用react useCallback
- rust - 如何在 Rust 中按值返回结构?