将多张照片上传(并重命名)到服务器

时间:2020-07-19 15:01:17

标签: php mysql

即使我不擅长开发,我也试图创建一个表格,该表格允许将多张照片上传到服务器,并将文本上传到数据库。

对于文本,没问题。要上传一张照片,也做得很好。

我不能做的就是以单张表单的形式上传几张照片。 我应该使用 while for foreach 循环吗?如果是这样,我如何检索照片信息? 我指定我不尝试使用“多个”功能。即使文件以相同的格式上传,用户也必须使用单独的“文件上传”字段。

我指定要在上传过程中重命名文件。 使用下面的代码,上载有效,但仅重命名第一个文件有效。第二个(当然还有以下几个)也被重命名。第二个示例:

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>

2 个答案:

答案 0 :(得分:1)

谢谢@Professor 我创建了表,测试了页面,但是有两件事很奇怪:

  1. 消息出现问题,照片名称不正确 出现。
  2. 即使我插入一张照片,系统也会更新数据库中的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 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>

答案 1 :(得分:0)

我将这个演示放在一起,展示了如何在HTML中使用不同的命名约定,并在使用PHP处理上传文件时将其与数组绑定。 如果您查看表单-特别是file输入,您会注意到一个公用名productimage,但是它以productimage[ KEY ]之类的数组语法编写-允许在PHP中访问KEY在循环中,如下面的处理部分所示。这是为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 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.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>