2012-02-13 147 views
1

我想重命名一個圖像文件並將文件位置保存在數據庫中。重命名文件的名稱編號

---------------------------------------- 
| id | name | category | image   | 
---------------------------------------- 
| 1 | foo | category | uploads/1.jpg | 
---------------------------------------- 

的:我正在上傳並插入我想看看我的表像這樣以後有問題與它的問題,因爲我想給文件命名爲錶行我在插入的id 。 id字段自動遞增。 這裏是我爲它的代碼:

function service() 
{ 
    $con=$this->do_upload(); 
    $id=mysql_insert_id(); 
    $data=array(
     'name'=>$this->input->post('name'), 
     'category'=>$this->input->post('category'), 
     'image'=>'uploads/'.$id.$con['file_ext']; 
    ); 
    $query=$this->db->insert('table',$data); 
    return $query; 
} 

這不是正確的方法和假設的文件沒有保存在數據庫中保存wanted.instead它,因爲它被保存「上傳/ 1.JPG」的作爲'uploads/0.jpg'。
任何人都可以爲我提供正確的約定嗎? n.b.我正在使用codeigniter 2.1.0mySQL數據庫。

+1

我們假設你知道你錯過了'$''上con' - >'$ ID。con ['file_ext'];' – 2012-02-13 13:31:58

+0

函數'do_upload()'發生了什麼?如果連接關閉或其他數據庫操作發生,您可能會丟失'INSERT_ID' – 2012-02-13 13:33:11

+1

文件名不應包含「upload /」,可能您將所有文件保存在該目錄中,因此將該文件命名爲「image1.jpg」 – 2012-02-13 13:34:24

回答

4

你不能在不調用mysql查詢之前使用mysql_insert_id訪問id。您必須插入新記錄並更新它。與新的文件名。

編輯:

當我上傳圖片/其他文件到服務器時,我總是用一些隨機哈希重命名它們。所以文件在文件系統上有唯一的散列名稱,而在mysql行中,只設置了這個散列來將db行與文件關聯起來。

所以插入新記錄到數據庫之前,產生一些隨機字符串,檢查是否有此名稱的文件已經存在:

$filename = ''; 
do { 
    $filename = substr(md5(uniqid(rand(), true)), 0, 8); 
} while (!file_exists('uploads/'.$filename)); 

做在do_upload方法,讓它在$con數組的形式返回文件的名稱。

+2

什麼hsz說是正確的。您需要將文件添加到文件系統,將記錄添加到數據庫。返回最後的ID#,然後重命名文件,然後重新查詢數據庫以更新具有新文件名的行。 **建議**將文件命名爲時間戳,並將該時間戳存儲在數據庫中。減少對db的查詢。和獨特的一樣。 – gorelative 2012-02-13 13:38:01

+0

可以舉一個例子,使用時間戳嗎?謝謝你,@Mike – Shabib 2012-02-13 13:48:59

+0

關於加載(儘管最小)隨機哈希比time()調用需要更多的資源。在兩個時間()呼叫中將是更好的路線。 – gorelative 2012-02-13 15:32:15

1

如果只是用一個獨特的價值爲您id場,你可以這樣做:

function update_service($id) 
{ 
    $con=$this->do_upload(); 
    $result = mysql_query("SELECT MAX(id) FROM <table_name>"); 
    $data = mysql_fetch_row($result); 
    $id = $data[0] + 1; 
    $data=array(
     'name'=>$this->input->post('name'), 
     'category'=>$this->input->post('category'), 
     'image'=>'uploads/'.$id.$con['file_ext']; 
    ); 
    $query=$this->db->insert('table',$data); 
    return $query; 
} 
+1

此解決方案可能導致數據不準確。快速場景:我們有10條記錄,所以最後一個id是'10',所以'$ id = 11'。但如果我們刪除最後5條記錄,它將是'$ id = 6'。 MySQL的自動增量會插入新的recod和'id = 11',我們將使用'$ id = 6'。不要這樣做! – hsz 2012-02-13 13:43:35

+0

感謝你@krister,但有沒有其他方式做到這一點,而無需進行兩次數據庫調用? – Shabib 2012-02-13 13:44:34

+0

@hsz,那麼你如何建議去做?在這些情況下,我是新手。 – Shabib 2012-02-13 13:46:09

1
function service() 
{ 
    $con=$this->do_upload(); 
    $id = time(); 
    $data=array(
     'name'=>$this->input->post('name'), 
     'category'=>$this->input->post('category'), 
     'image'=>'uploads/'.$id.$con['file_ext']; 
    ); 
    $query=$this->db->insert('table',$data); 
    return $query; 
} 

使用time()代替mysql_insert_id ..然後你只需要做同樣的事情在​​3210函數..它要求文件名只是使用time()

0

我在其中一個應用程序中構建了相同的功能。我使用的是我從這裏下載的uuid生成器類:https://github.com/Repox/codeigniter-uuid

使用此類我爲新上傳的圖像生成uuid,然後將文件名設置爲「.ext」。我將uuid存儲在數據庫字段中,以及上載映像的用戶對文件名稱進行引用。

這對我來說工作得很好。

所以一段代碼如下所示:

$this->load->library('uuid'); 
$uuid = $this->uuid->v4(); 
$new_file_name = $uuid.$image_data['file_ext']; 

希望這有助於。

問候 塞巴斯蒂安

+0

這是實現序列行爲的許多方法之一。 關於原來的問題,似乎使用$ id = mysql_insert_id();應該在插入之後完成,而不是在: http://www.tutorialspoint.com/mysql/mysql-using-sequences.htm – alfasin 2012-02-17 01:56:46