2016-03-26 58 views
0

我正在構建一個動態表單,允許用戶爲每個條目創建可變數量的行。該表格包含圖片上傳功能。我能夠使圖片上傳工作,但不完全如我所願 - 問題是我似乎被迫使用文件的'tmp_name',並且無法獲取原始文件名。PHP - 從動態表單上傳圖像 - 文件命名問題

首先,這裏是我的PHP(標題到MySQL)...

require '../credentials.php'; 
$servername = "localhost"; 
$dbname = "dynamic_test"; 
$target_dir = "uploads/"; 

$conn = new mysqli($servername, $username, $password, $dbname); 

$sql = ''; 

$name = $_POST['name']; 
$route = $_POST['route']; 

$site_array = $_POST['site']; 

foreach($site_array as $siteNumber => $value){ 

    $species_array[$siteNumber] = $_POST['species'.$siteNumber.'']; 
    $deadinjured_array[$siteNumber] = $_POST['deadinjured'.$siteNumber.'']; 
    $image_array[$siteNumber] = $_FILES['image'.$siteNumber.'']['tmp_name']; 

    foreach($species_array[$siteNumber] as $key => $species){ 

     if($image_array[$siteNumber][$key]){ 
      $target_file = ($target_dir . rand(1, 9999999) . strtolower(basename($image_array[$siteNumber][$key]))); 

      if(move_uploaded_file($image_array[$siteNumber][$key], $target_file)){ 
       $image_url = $target_file; 
      } 
     };   

    $deadinjured = $deadinjured_array[$siteNumber][$key]; 

    $sql .= "INSERT INTO test (volunteer, route, site, species, deadinjured, image_url) 
    VALUES ('$name', '$route', '$siteNumber', '$species', '$deadinjured', '$image_url');"; 

    }; 
}; 


if ($conn->multi_query($sql) === TRUE) { 
    echo "MySQL thanks you"; 
    $conn->close(); 
}; 

聲明本線 -

$image_array[$siteNumber] = $_FILES['image'.$siteNumber.'']['tmp_name']; 

爲了獲得圖像轉換成$ image_array,他們要求無論是['name']或['tmp_name']後綴 - 在此處使用['name']會導致move_uploaded_file函數失敗 - 這會生成錯誤Undefined variable: image_url。但是,我發現通過將['tmp_name']構建到$ image_array變量中,我能夠使move_uploaded_file函數正常工作,因爲該函數期望在第一個參數中使用['tmp_name']後綴。

所以我的問題是這樣的 - 有沒有辦法使用實際文件名而不是臨時名稱將圖像存入圖像數組?這並不是什麼大問題 - 上面的代碼確實有效,我不需要保留這個特定項目的實際文件名 - 但我仍然想知道這樣做的正確方法。

謝謝。

回答

0

我發現這裏的問題出在語法上。 Eihwaz提出了一些很好的建議,但這裏是工作代碼的最後一部分 - 見我的筆記發生了什麼變化......(SQL注入的威脅中)

require '../credentials.php'; 
$servername = "localhost"; 
$dbname = "dynamic_test"; 
$target_dir = "uploads/"; 

$conn = new mysqli($servername, $username, $password, $dbname); 

$sql = ''; 

$name = $conn->real_escape_string($_POST['name']); 
$route = $conn->real_escape_string($_POST['route']); 

$site_array = $_POST['site']; 

foreach($site_array as $siteNumber => $value){ 

    $siteNumber = $conn->real_escape_string($siteNumber); 

    $species_array[$siteNumber] = $_POST['species'.$siteNumber.'']; 
    $deadinjured_array[$siteNumber] = $_POST['deadinjured'.$siteNumber.'']; 

    //IT IS NECESSARY TO SUFFIX THIS WITH ['name'], 
    $image_array[$siteNumber] = $_FILES['image'.$siteNumber.'']['name']; 

    foreach($species_array[$siteNumber] as $key => $species){ 

     if($image_array[$siteNumber][$key]){ 
      $target_file = ($target_dir . rand(1, 9999999) . strtolower(basename($image_array[$siteNumber][$key]))); 

      //ALTHOUGH SLIGHTLY LESS ELEGANT THAN USING A VARIABLE, I FOUND THAT THIS WORKED BECAUSE ['tmp_name'] MUST PRECEDE [$key] - I WAS THINKING IT HAD TO BE THE OTHER WAY AROUND 
      if(move_uploaded_file($_FILES['image'.$siteNumber.'']['tmp_name'][$key], $target_file)){ 
       $image_url = $conn->real_escape_string($target_file); 
      } 
     };   

    $deadinjured = $deadinjured_array[$siteNumber][$key]; 

    $sql .= "INSERT INTO test (volunteer, route, site, species, deadinjured, image_url) 
VALUES ('$name', '$route', '$siteNumber', '$species', '$deadinjured', '$image_url');"; 

    }; 
}; 
0

整個_FILE只是存儲陣列中:

require '../credentials.php'; 
$servername = "localhost"; 
$dbname = "dynamic_test"; 
$target_dir = "uploads/"; 

$conn = new mysqli($servername, $username, $password, $dbname); 

$sql = ''; 

$name = $_POST['name']; 
$route = $_POST['route']; 

$site_array = $_POST['site']; 

foreach($site_array as $siteNumber => $value){ 

    $species_array[$siteNumber] = $_POST['species'.$siteNumber]; 
    $deadinjured_array[$siteNumber] = $_POST['deadinjured'.$siteNumber]; 
    $image_array[$siteNumber] = $_FILES['image'.$siteNumber]; 

    foreach ($species_array[$siteNumber] as $key => $species) { 
     $image_url = false; 

     if (isset($image_array[$siteNumber][$key])) { 
      $target_file = ($target_dir . $image_array[$siteNumber][$key]['name']); 

      if (move_uploaded_file($image_array[$siteNumber][$key]['tmp_name'], $target_file)) { 
       $image_url = $target_file; 
      } 
     }  

     $deadinjured = isset($deadinjured_array[$siteNumber][$key]) ? $deadinjured_array[$siteNumber][$key] : false; 

     $sql .= "INSERT INTO test (volunteer, route, site, species, deadinjured, image_url) 
     VALUES ('$name', '$route', '$siteNumber', '$species', '$deadinjured', '$image_url');"; 

    }; 
}; 

注意雖然,你有SQL注入的威脅。另外,我建議使用唯一的名稱來存儲文件。如果您確實需要保留原始名稱,請將原始名稱與自動生成的名稱一起存儲在數據庫中。因此,用戶在上傳文件時將看到文件名,但實際上它將以不同的名稱存儲在服務器上。使用uniqid或類似的東西來生成隨機名稱。

+0

這是返回了一些錯誤 - '未定義抵消:1 '和'未定義變量:image_url'。 – skwidbreth

+0

是的,值得注意的是,這仍在開發中,所以目前還沒有內建驗證或SQL注入防護功能。正在努力讓流量下降...... – skwidbreth