R
R
Ruslan Demidov2015-02-25 10:37:07
PHP
Ruslan Demidov, 2015-02-25 10:37:07

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

The file upload code is as follows:
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>";
    } 
  }

The code for issuing a file from the database is as follows:
$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;
  }

The code is formed on the basis of examples, of which there are many on the Internet, adapted to itself (in the form of a skeleton that needs to be improved), it works, but somewhere there is an error, and where - due to lack of experience - I can’t find it.
Please help with advice on the given code or send an example of the correct organization of storing files in a SQL database.
Thank you.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexey Yakhnenko, 2015-02-25
@rd_nino

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.

A
Alexander, 2015-02-25
Madzhugin @Suntechnic

There is no correct way to store files in a DB, because storing files in a DB is not correct.
You need to store the paths to the files, and store the files themselves in the FS.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question