Загрузка файлов и их хранение
Поделюсь своим опытом загрузки и хранения файлов в интранет системе.
Основные проблема хранения файлов это сохранить о нём данные и имена фалов в кириллице. Для решения этой проблемы необходимо хранить информацию о файле (имя на русском, и mime тип файла и т.п.). Все это лучше организовать с помощью базы данных.
Создадим таблицу (MySQL):
CREATE TABLE UploadFiles ( Id INT (11) NOT NULL AUTO_INCREMENT, Attached_alias VARCHAR (20) DEFAULT NULL COMMENT 'Прикреплён к чему', Attached_id INT (11) DEFAULT NULL COMMENT 'Прикремпён к ключу', Local_name VARCHAR (80) DEFAULT NULL COMMENT 'Имя файла на диске', Type VARCHAR (50) DEFAULT NULL COMMENT 'mime тип файла при загрузке', Name VARCHAR (250) DEFAULT NULL COMMENT 'Оригинальное имя', Ext VARCHAR (20) DEFAULT NULL COMMENT 'Расширение файла', Size INT (11) DEFAULT NULL COMMENT 'Размер файла в байтах', PRIMARY KEY (Id) )
Поле Attached_alias – указывает какой модуль загружал файл (например прикреплено к сообщению гостевой или к сообщению форума).
Поле Attached_id – указывает ID сообщения.
Загрузка файла:
//Загрузка файлов
foreach($_FILES as $file) {
$insert_file = null;
if ($file['tmp_name'] != '') {
//Преобразуем имя для сохранения
$insert_file['Attached_alias'] = 'mes';
$insert_file['Attached_id'] = $insert['Id'];
$insert_file['Local_name'] = 'mes_'.$insert['Id'].'_'.md5($file['tmp_name'].date('ydmhis')).'.ulf';
move_uploaded_file($file['tmp_name'], UPLOAD_PATH.$insert_file['Local_name']);
$insert_file['Name'] = $file['name'];
$Ext = explode('.', $file['name']);
$insert_file['Ext'] = strtolower($Ext[sizeof($Ext) - 1]);
$insert_file['Type'] = $file['type'];
$insert_file['Size'] = $file['size'];
$this->db->insert('UploadFiles', $insert_file);
}
}
В строке 11 придумываем функцию для хэширования имени файлов используя время, это необходимо для того, чтобы имя файла всегда было уникальным, вероятность того что хэш имени файла с временем загрузки файла совпадёт ничтожно мала.
Имя файла получается похожим на: mes_161_342631bc07c109c538ee48ed4d1a329f.ulf
Это даёт дополнительные преимущества:
- файл нельзя загрузить напрямую (если требуется авторизация и прочее)
- информацию о файле всегда можно получить из БД не теребя файловую систему
- можно обрабатывать данные о скачивании файла (например: сколько раз, кто, в какое время).
Процедура скачивания файла пользователем (php+CodeIgniter):
//Обезопашиваем входные данные
$id = (int)$id;
if ($id == 0) show_404();
//Запрос информации о файле
$query = $this->db->get_where('UploadFiles', array('Id' => $id));
if ($query->num_rows() == 1)
{
$row = $query->row_array();
$type = $row['Type'];
$file_name = $row['Name'];
$file_path = UPLOAD_PATH.$row['Local_name'];
$file_name = iconv("utf-8", "windows-1251", $file_name); //Конвертируем кодировку имени файла
//Отправляем пользователю
header('Content-Type: content='.$type);
header('Content-Disposition: attachment; filename="'.$file_name.'"');
readfile($file_path);
} else show_404();
По моему очень удобно, может кому-то пригодится.
Понравилась статья? Оставьте комментарий или подпишитесь на RSS рассылку.


[...] Хранение файлов было организовано по следующему принципу [...]