Answer the question
In order to leave comments, you need to log in
How to properly organize the storage of files in a MySQL database (loading and unloading via PHP)?
Good afternoon.
I am new to PHP and when implementing a simple application, a problem arose - files uploaded to the MySQL database via PHP are damaged (when transferring a file from the database to the client, the file size increases by 4-5 bytes.
The server is implemented based on IIS + MySQL + PHP.
In the database the tblfiles table has the following structure:
CREATE TABLE `tblfiles` (
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'Идентификатор',
`name` VARCHAR(250) NOT NULL COMMENT 'Оригинальное имя файла',
`premise_id` INT(11) NOT NULL COMMENT 'Идентификатор помещения',
`mime_type` VARCHAR(250) NOT NULL COMMENT 'mime-тип загруженного файла',
`file_content` LONGBLOB NOT NULL COMMENT 'контент файла',
`size` INT(11) NOT NULL COMMENT 'размер в байтах',
INDEX `id` (`id`)
)
COMMENT='Файлы'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1
if (isset($_FILES['files']))
{
$premise_id = $_POST['input_item_id'];
//пролистываем весь массив файлов по одному $_FILES['file']['name'] as $k=>$v
foreach ($_FILES['files']['name'] as $k=>$v)
{
//директория загрузки
$uploaddir = "uploads/";
$uploadfile = $_FILES['files']['name'][$k];
//черный список типов файлов
$blacklist = array(".php", ".phtml", ".php3", ".php4");
foreach ($blacklist as $item)
{
if(preg_match("/$item\$/i", $_FILES['files']['name'][$k]))
{
echo "Нельзя загружать скрипты.";
exit;
}
}
//перемещаем файл из временного хранилища
if (move_uploaded_file($_FILES['files']['tmp_name'][$k], $uploadfile))
{
//подготавливаем переменные
$mime_type = $_FILES['files']['type'][$k];
$filename = basename($uploadfile);
$file = fopen($uploadfile,"rb"); //Открыли файл на чтение ($uploadfile - имя файла)
$img_content = fread($file,filesize($uploadfile)); // Прочитали содержимое файла в переменную
$file_size = filesize($uploadfile);
fclose($file);
unlink($uploadfile);
try
{
//пишем данные в базу
$stmt = $cnndb->prepare("INSERT INTO tblfiles ( name, premise_id, mime_type, file_content, size ) VALUES ( :name, :premise_id, :mime_type, :file_content, :size )");
$stmt->bindParam(':name', $filename, PDO::PARAM_STR);
$stmt->bindParam(':premise_id', $premise_id, PDO::PARAM_INT);
$stmt->bindParam(':size', $file_size, PDO::PARAM_INT);
$stmt->bindParam(':mime_type', $mime_type, PDO::PARAM_STR);
$stmt->bindParam(':file_content', $img_content, PDO::PARAM_LOB);
$cnndb->errorInfo();
$stmt->execute();
}
catch(PDOException $e)
{
'Error : ' .$e->getMessage();
}
}
else
echo "<center><br>Файл не загружен, вернитесь и попробуйте еще раз.</center>";
}
}
$id = strip_tags($_GET['id']);
$cnndb = CreateCon();
$sql="SELECT name, file_content, mime_type FROM tblfiles WHERE id= $id";
$result = $cnndb->query($sql);
if (!$result)
{
die('Could not connect: ' . mysql_error());
}
if($row = $result->fetch(PDO::FETCH_ASSOC)) {
$file_name = $row['name'];
$mime_type = $row['mime_type'];
$file_content = $row['file_content'];
header("Content-Type: $mime_type");
header('Content-Disposition: attachment; filename="'.$file_name.'"');
echo $file_content;
}
Answer the question
In order to leave comments, you need to log in
Is there by any chance a closing php tag in the issuance code? Is there extra spaces after it?
try also sending header header('Content-Length: ' . $size);
just in case, try doing ob_clean before uploading, and exit after.
Well, in general, yes, you should not turn the database into a file repository.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question