2013-12-13 39 views
1

我對PHP很新穎。我不想提出問題,因爲我確定這是記錄在某個地方,但經過一段時間後,我似乎無法將兩個和兩個放在一起。PHP - 在文件上傳時檢查不同的文件名

我有一個程序,將允許多個圖像上傳到數據庫中的項目。基本上,對於數據庫中的每個項目,可能會有多個圖像上傳。

實施例:

  • 檔案:的Xbox 360


圖片:

  • Xbox360.jpg
  • side.jpg
  • front.jpg

圖像和項目信息都存儲在數據庫(MySQL)中,但圖像存儲在文件系統中,數據庫指向文件系統中圖像的URL。

我遇到的問題是,一切按預期工作,除了它允許重複的圖像名稱寫入數據庫。它不允許將重複的圖像寫入文件系統,我對此感到滿意。我想確保圖像的名稱只添加一次到數據庫中。如果圖像名稱與另一個圖像名稱重複,則不需要寫入數據庫。

add_db.php:

$uniqueDir = uniqid(); 
$directory = "img/$uniqueDir/"; 

db_addItem($id_category, $name, $cost, $description, $qty, $directory); //Adds to the `items` table 

foreach ($_FILES['i_file']['name'] as $filename) { 
    if ($filename != '' && $filename != 'No file chosen') { 
     //I think above is where I check for unique image names 
     $url = "img/$uniqueDir/$filename"; 
     db_addImg($url, $filename); //Adds to the `img` table 
     $item_picsID = get_item_PicsID($filename, $url); 
     $itemID = get_itemID($directory); 
     db_insertImg($itemID, $item_picsID); 
    } 
} 
addFilesystem($directory); //Writes image(s) to filesystem 

function db_addImg($url, $filename) { 
    include 'mysql_login_pdo.php'; 

    // Create the SQL query 
    $query = "INSERT INTO img (`name`, `url`) VALUES(:filename, :url)"; 

    $stmt = $db->prepare($query); 
    $stmt->execute(array(
     ':filename' => $filename, 
     ':url' => $url 
    )); 
} 

function db_insertImg($itemID, $item_picsID) { 
    include 'mysql_login_pdo.php'; 

    // Create the SQL query 
    $query = "INSERT INTO `item_pics` (`item_id`, `img_id`) VALUES(:itemID, :item_picsID)"; 

    $stmt = $db->prepare($query); 
    $stmt->execute(array(
     ':itemID' => $itemID, 
     ':item_picsID' => $item_picsID 
    )); 
    $db = null; 
    return; 
} 

一切正常,但它會寫重複的圖像名稱到數據庫。我希望圖像名稱不同。我也不想重命名圖像(如果可能的話)。

回答

0

您可以img表定義的name列的UNIQUE索引,然後在你的db_addImg功能使用稍加修改INSERT聲明:

function db_addImg($url, $filename) { 
    //... 
    $query = "INSERT INGORE INTO img (`name`, `url`) VALUES(:filename, :url)"; 
    //... 
} 

它會悄悄地取消任何地方插入的是UNIQUE鍵衝突,這將在您的img表中以不同的文件名結尾。

+0

我想我在這裏遵循你的思維模式。我不知道MySQL中的「INSERT IGNORE」選項,所以我會詳細閱讀。我的猜測是,如果'name'列設置爲UNIQUE並且它與數據庫中已有的記錄相匹配,它將忽略查詢? (如果名稱不唯一,請不要將名稱和網址寫入表格) –

+0

您是對的。在這種情況下,普通的'INSERT'會產生違反約束的錯誤。如果它正在產生這個錯誤,使用'INSERT INGORE'靜靜地取消整個查詢。 –

+0

謝謝,我的朋友。如果我有足夠的代表upvote你,我會:) –

0

我會根據img表中的主鍵使用文件名,因爲您保證它是唯一的。

否則,你需要一個獨特的文件名與某種類型的散列,然後檢查文件系統。所有這些都可能是昂貴的操作。

看起來你正在使用PDO,所以靜態方法lastInsertId將得到最後一個插入ID(主鍵)。

例如:

// after your insert to img 
$filename = 'img' . $db->lastInsertId() . $extension; 

這需要稍微改變了img表。但是,最好將元數據(文件類型,大小等)存儲在此表中,而不是文件位置(因爲它可能會更改)。

+0

夥計,感謝您的鏈接。我仍然在學習PDO,所以我還沒有遇到'lastInsertId'。感謝您的信息! –

+0

沒問題。歡迎來到StackOverflow!不要忘記[接受答案](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)。 –

0

我認爲使用的hash值更好,因爲primary key的值更好。因爲字符串搜索比int慢得多。

+0

我不完全確定你在暗示什麼。哈希對我來說是一個外來的詞,除了密碼之外,所以如果你有一個我可以閱讀的鏈接,我會非常感激。我處理'url'的MySQL表具有以下列:'id','url'。我假設你告訴我使用'id'而不是'url'? –