2012-02-13 166 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