簡體   English   中英

將多張照片上傳(並重命名)到服務器

[英]Upload (and rename) several photos to the server

即使我不擅長開發,我也在嘗試創建一個表單,允許將多張照片上傳到服務器並將文本上傳到數據庫。

對於文本,沒有問題。 也上傳一張照片,這很好。

我不能做的是在一個表單提交中上傳幾張照片。 我應該使用while還是forforeach循環? 如果是這樣,我如何檢索照片信息? 我指定我不會嘗試使用“多個”function。 即使文件以相同的形式上傳,用戶也必須使用單獨的“文件上傳”字段。

我指定要在上傳期間重命名文件。 使用下面的代碼,上傳工作,但只有第一個文件的重命名工作。 第二個(當然還有以下幾個)被嚴重重命名。 第二個例子:

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 我創建了表格,測試了頁面,但有兩件事很奇怪:

  1. 消息有問題,照片的名稱沒有出現。
  2. 即使我插入一張照片,系統也會在數據庫中更新 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>

我把這個演示放在一起,展示了如何在 HTML 中使用不同的命名約定,並在使用 PHP 處理上傳時將其與數組綁定。 如果您查看表單 - 特別是file輸入,您會注意到一個通用名稱productimage但以數組語法(如productimage[ KEY ]編寫 - 允許在循環中訪問 PHP 中的KEY ,正如您將在下面的處理部分中看到的那樣. 這是為mysqli編寫的,但可以直接遷移到 PDO。

整個過程中有很多注釋可以幫助指導您 - 但您可以通過編輯 db 連接詳細信息和$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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM