2011-08-01 87 views
0

我目前有一個PHP上傳表單,可以讓用戶上傳多個文件。這是上傳文件的後端腳本。將多個上傳文件存儲在數據庫中的最佳方式

while(list($key,$value) = each($_FILES[images][name])) 
{ 
if(!empty($value)){ // this will check if any blank field is entered 
$filename = $value; // filename stores the value 


$filename=str_replace(" ","_",$filename);// Add _ inplace of blank space in file name, you can remove this line 


$file_ext = @strtolower(@strrchr($filename,".")); 
$file_ext = @substr($file_ext, 1); // remove dot 
$filename = md5(uniqid(rand(), true)) . '.' . $file_ext; 


$add = "/html/uploaded/$filename"; // upload directory path is set 
copy($_FILES[images][tmp_name][$key], $add);  // upload the file to the server 
chmod("$add",0777); 

} 
} 

在此while循環之後,我運行SQL查詢將信息插入到我的數據庫中。我如何確保第一個文件存儲爲$ file1,第二個文件存儲爲$ file2等。

我試着計算循環來找出哪個數字文件是哪個文件,但它不工作。

回答

2

將文件存儲在數據庫中通常被認爲是一個壞主意。通過將文件放在服務器的本地光盤上,並將文件名存儲在數據庫中,可以取得更好的效果。

看着你的代碼,看起來你實際上正在嘗試這樣做,所以你的問題標題有點用詞不當。

您的代碼有幾個結構性問題。試試這個代碼了:所以在這裏

$errors = array(); 
$files = array(); 
foreach ($_FILES['images'] as $k=>$image) { 

    // handle upload errors 
    if ($image['error'] != 0 && $image['error'] != 4) {   
     switch ($image['error']) { 
      case '1': 
      case '2': 
       $err = 'The uploaded file exceeds the maximum file size.'; 
       break;     
      case '3': 
       $err = 'The upload was inturupted, transfer failed.'; 
       break; 
      case '6': 
      case '7': 
      case '8': 
       $err = 'Server error. Please try again later.'; 
       break; 
     } 
     // record error and move on 
     $errors[] = array('image'=>$k, 'error'=>$err); 
     continue; 
    } elseif ($image['error'] == 4) { 
     // error 4 means no image was sent 
     continue; 
    } 

    // determine the extension 
    $ext = explode('.', $image['name']); 
    if (count($ext) != 2) { 
     $errors[] = array('image'=>$k, 'error'=>'Could not determine file extension.'); 
     continue; 
    } else { 
     switch ($ext[1]) { 
      case 'jpg': 
      case 'jpeg': 
      case 'gif': 
      case 'png': 
       break; 
      default: 
       $errors[] = array('image'=>$k, 'error'=>'Unsupported file extension.'); 
       continue; 
       break; 
     } 
    } 

    // make a random-ish filename 
    $filename = time().uniqid(rand(), true) . '.' . $ext[1]; 
    $path = '/html/uploaded/'.$filename; // upload directory path is set 

    move_uploaded_file($image['tmp_name'], $path);  // upload the file to the server 
    // this is a bad idea right here! Use 775 at least, if possible 
    chmod($path,0777); 
    $files[] = array('name'=>$filename, 'path'=>$path); 
} 

// now loop the $files array and put the paths into the database 

// you also should do something with the errors listed in $errors 

編輯

是把這些文件導入數據庫的快速和骯髒的例子。我注意到你有一個sizeext字段 - 如果這應該記錄文件和圖像的擴展名......哪一個?無論如何,如果你填寫其他變量,下面的代碼將把文件名放入數據庫。

我想告訴你 - 這個數據庫設計有缺陷。如果你想要超過5張圖片怎麼辦?您必須更改數據庫表的結構並編輯代碼。如果創建一個關係表結構,爲每個帶有ID的文件插入一行以將它們全部綁定在一起(即album_id,然後您有一個名爲albums並帶有頂級信息)的關係表結構會更好。

// start building up the SQL query, start with 
// some fields that are straightforward 
$sql = ' 
    INSERT INTO table_name (
     `id`, 
     `status`, 
     `user`, 
     `title`,'; 

// now loop the list of files (5 only), 
// add each needed field 
for ($i=1; $i < count($files) && $i < 5; $i++) { 
    $sql .= '`file'.$i.'`,'; 
} 

// build out the rest of the query, add values 
// for the straightforward fields 
$sql .= ' 
    `size`, 
    `ext`, 
    `ip`, 
    `date` 
) VALUES (
    NULL, 
    "'.$status.'", 
    "'.$user.'", 
    "'.$title.'", 
'; 

// loop the files 
$ct = 1; 
foreach ($files as $f) { 
    $sql .= '"'.$f['name'].'",'; 
    // only allow 5 files 
    if ($ct == 5) 
     break; 
    $ct++; 
} 

// wrap up building the query 
$sql .= ' 
    "'.$size.'", 
    "'.$ext.'", 
    "'.$ip.'", 
    "'.$date.'" 
)'; 

mysql_query($sql); 
+0

感謝克里斯,我確實存儲在我的服務器上的文件,只是保留在數據庫中的文件名作爲參考。 一切正常,但如果我上傳了兩個文件,我希望第一個文件存儲在表中的字段file1下,第二個文件存儲在file2下等。 – Jako

+0

爲了說明這一點,我需要看到你的數據庫結構。但是,如果你簡單地循環示例代碼中的'$ files'數組,它們將按照上傳的順序進行。 –

+0

Chris,這裏是我的數據庫結構的外觀,http://jako.in/db.jpg – Jako

1

首先,在for循環中訪問像$ _FILES這樣的關聯數組時,應該使用撇號。

關於您的問題:爲什麼不使用類似$filename = sprintf('%s%d.%s', md5(uniqid(rand(), true)), $key, $file_ext);的東西來代替$filename = md5(uniqid(rand(), true)) . '.' . $file_ext;

相關問題