2 回答
TA贡献1829条经验 获得超7个赞
我创建了表,测试了页面,但有两件事很奇怪:
消息有问题,照片的名称不显示。
即使我插入一张照片,系统也会更新数据库中的 4 行。
这是我收到的消息:
文件“130_Candy_Produit_FaceProduct_pic01.jpg”已上传正常。信息已添加到目录:True 保存“130_Candy_Produit_NutritionValue_”时出现问题。记录到数据库的信息:True 保存“130_Candy_Produit_Ingredients_”时出现问题。记录到数据库的信息:True 保存“130_Candy_Produit_Labels_”时出现问题。记录到数据库的信息:True
这里是代码:
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>
<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>
TA贡献1735条经验 获得超5个赞
我将这个演示放在一起,展示了如何在 HTML 中使用不同的命名约定,并在使用 PHP 处理上传时将其与数组结合起来。如果您查看表单 - 特别是file输入,您会注意到一个通用名称productimage,但以数组语法编写,例如- 允许在循环中的 PHP 中productimage[ KEY ]进行访问,正如您将在下面的处理部分中看到的那样。KEY这是为 PDO 编写的mysqli,但可以直接迁移到 PDO。
全文中有大量注释可以帮助指导您 - 但您可以仅通过编辑数据库连接详细信息和变量来进行测试$dir。
<?php
error_reporting( E_ALL );
if( $_SERVER['REQUEST_METHOD']=='POST' ){
class PostException extends Exception {
public function __construct( $msg=null, $code=null ){
parent::__construct( $msg, $code );
}
public function geterror(){
return $this->getMessage();
}
}
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__ . '/images/uploads';
# 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 ) ){
# -------------------------------------------------
# ignore the fact that this is a mysqli connection
# the same methodology will work with PDO so you
# will need to use your own PDO connection
# OR
# edit the connection details below to suit
# -------------------------------------------------
$args=array(
'host' => 'localhost',
'user' => 'root',
'pwd' => 'xxx',
'db' => 'xxx'
);
mysqli_report( MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT );
$db=new mysqli( ...array_values( $args ) );
$db->set_charset('utf8');
$db->begin_transaction();
/*
create table `cbnadd_newproduct` (
`id` int(10) unsigned not null auto_increment,
`productname` varchar(50) null default null,
`productbrand` varchar(50) null default null,
`addername` varchar(50) null default null,
`adder_email` varchar(50) null default null,
primary key (`id`)
)
collate='utf8mb4_general_ci'
engine=innodb;
+--------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| productname | varchar(50) | YES | | NULL | |
| productbrand | varchar(50) | YES | | NULL | |
| addername | varchar(50) | YES | | NULL | |
| adder_email | varchar(50) | YES | | NULL | |
+--------------+------------------+------+-----+---------+----------------+
*/
#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();
/*
create table `cbnadd_productimages` (
`id` int(10) unsigned not null auto_increment,
`lineid` int(10) unsigned not null,
`image` varchar(128) not null,
primary key (`id`),
index `lineid` (`lineid`)
)
collate='utf8mb4_general_ci'
engine=innodb;
+--------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| lineid | int(10) unsigned | NO | MUL | NULL | |
| image | varchar(128) | NO | | NULL | |
+--------+------------------+------+-----+---------+----------------+
*/
/*
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 ];
# ensure we don't process non-existant files
if( !empty( $tmp ) ){
# 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.<br />Information has been added to the directory: %s', $targetname, ( $dbstatus ? 'True' : 'False' ) ) : sprintf('There was a problem saving "%s".<br />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>
<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.75rem 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;}
[type='file']{border:1px solid rgba(100,100,100,0.5); padding:0.25rem;border-radius:0.25rem;color:rgba(100,100,100,0.5);background:rgba(200,200,200,0.5);}
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);
}
$errors=$uploads=array();
}
?>
</div>
</form>
</body>
</html>
- 2 回答
- 0 关注
- 102 浏览
添加回答
举报