Armazenar arquivos em modo binário no MySQL usando PHP

Posted by Bento | Posted in Artigos, Banco de Dados, MySQL, PHP | Posted on 13-09-2009-05-2008

26

Olá pessoal, neste artigo vou mostrar como armazenar arquivos em modo binário no MySQL usando o PHP, e como recuperar estes arquivos para usá-los depois.

No banco de dados(MySQL) usaremos o campo do tipo BLOB é utilizado para armazenar arquivos binários e são dividivo em 4 tipos; TINYBLOB, BLOB, MEDIUMBLOB e LONGBLOB, a diferença é a capacidade de armazenar os dados.
Lembrando que podemos usar colunas do tipo TEXT para armazenar informações binarias também, abaixo a comparação.

-TINYBLOB, TINYTEXT – tamanho máximo de 255 – 256 Bytes

-BLOB, TEXT – tamanho máximo de 65535 – 64KB

-MEDIUMBLOB, MEDIUMTEXT – tamanho máximo de 16777215 – 16 MB

-LONGBLOB, LONGTEXT – tamanho máximo de 4294967295 – 4 GB

Observação:
-Na maioria dos servidores de hospedagem compartilhada o tipo LONGBLOB é configurada para suportar entre 50MB a 200 MB para manter o bom funcionamento do servidor.
-E que você deve analisar a real necessidade de armazenar o arquivo dentro do banco, pois isto faria sua base ficar gigante, e na maioria dos casos é gravado somente a URL(caminho do arquivo) no banco.

você poderá ler mais sobre especificaçõe de colunas do MySQL no link:
http://dev.mysql.com/doc/refman/4.1/pt/column-types.html

1° – Passo

O primeiro passo é criarmos o banco de dados e a tabela para armazenar nossos arquivos;
no exemplo o banco será chamado binario

CREATE DATABASE binario;

Agora crie uma tabela com o nome arquivos seguindo a estrutura abaixo;

CREATE TABLE `binario`.`arquivos` (
`Codigo` INT( 10 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'Codigo',
`NmArquivo` VARCHAR( 150 ) NOT NULL COMMENT 'nome original',
`Descricao` VARCHAR( 200 ) NULL COMMENT 'descrição do arquivo',
`Arquivo` MEDIUMBLOB NOT NULL COMMENT 'dados do arquivo',
`Tipo` VARCHAR( 15 ) NOT NULL COMMENT 'Tipo do arquivo, jpeg, doc, mp3, etc..',
`Tamanho` INT NOT NULL COMMENT 'Tamanho em bytes',
`DtHrEnvio` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Data e Hora de envio'
) ENGINE = MYISAM ;
 
/*
Claro que você deve implementar a tabela conforme a necessidade do seu projeto.
*/

2° – Passo

O proximo passo é criar um formulário HTML, para fazermos UPLOAD do arquivo que será gravado.
Não vou entrar em detalhes dos comandos HTML.

<pre escaped=”true” lang=”html” line=”1″>
form id=”upload” action=”upload_binario.php” enctype=”multipart/form-data” method=”post”

<label>
<input id=”file” name=”file” type=”file” />
</label>

<input id=”enviar” name=”enviar” type=”submit” value=”Enviar arquivo…” />
/form

</pre>

3° – Passo

Este é o ultimo passo para envio do arquivo para o banco de dados.
Antes de prosseguir crie um arquivo para conexao com o banco de dados.

//conexao.inc.php
$conexao = mysql_connect("localhost","root","password");
 mysql_select_db("binario");

Crie um arquivo chamado upload_binario.php

require_once('conexao.inc.php');
 
//recupera os dados enviados atraves do formulário
//NOME TEMPORÁRIO
$file_tmp = $_FILES["file"]["tmp_name"];
 //NOME DO ARQUIVO NO COMPUTADOR
$file_name = $_FILES["file"]["name"];
//TAMANHO DO ARQUIVO
$file_size = $_FILES["file"]["size"];
//MIME DO ARQUIVO
$file_type = $_FILES["file"]["type"];
 
//antes de ler o conteudo do arquivo você pode fazer upload para compactar em .ZIP ou .RAR, no caso de imagem você poderá redimensionar o tamanho antes de gravar no banco. Claro que depende da sua necessidade.
 
//Para fazer UPLOAD poderá usar COPY ou MOVE_UPLOADED_FILE
//copy($file_tmp, "caminho/pasta/$file_name");
//move_uploaded_file($file_tmp,"caminho/pasta/$file_name");
 
//lemos o  conteudo do arquivo usando afunção do PHP  file_get_contents
$binario = file_get_contents($file_tmp);
// evitamos erro de sintaxe do MySQL
$binario = mysql_real_escape_string($binario);
 
//montamos o SQL para envio dos dados
$sql = "INSERT INTO `binario`.`arquivos` (`Codigo` ,`NmArquivo` ,`Descricao` , `Arquivo` ,`Tipo` ,`Tamanho` ,`DtHrEnvio`)
VALUES ('NULL', 'foto.jpg', '$file_name', '$binario', '$file_type', '$file_size', CURRENT_TIMESTAMP)";
//executamos a instução SQL
mysql_query("$sql") or die (mysql_error());
?

Exibindo ou baixando o arquivo do banco de dados.
Vamos criar um arquivo chamado listar.php para mostrar todos arquivos gravados em nossa tabela arquivos e o link para visualizar o arquivo.

require_once('conexao.inc.php');
 
$consulta = "SELECT `Codigo`,`NmArquivo`,`Descricao`,`Tipo`,`Tamanho` 	FROM `arquivos`";
$resultado = mysql_query($consulta);
 
while($dados = mysql_fetch_array($resultado)){
$Codigo = $dados['Codigo'];
echo " | Arquivo: " . $dados['NmArquivo'];
echo " | Descriçao:" . $dados['Descricao'];
echo " | Tipo:" . $dados['Tipo'];
echo " | Tamanho:" . $dados['Tamanho']; // você pode fazer divisão por 1024 para mostrar em MB
echo " &gt;&gt; <a href="ver_arquivo.php?codigo=$Codigo" target="_blank">Ver arquivo</a>";
}
 
?

Agora criaremos o arquivo ver_arquivo.php que será responsável por mostrar o arquivo do banco de dados, selecionado

require_once('conexao.inc.php');
 
//recuperar o codigo do arquivo atraves do metodo GET
$codigo= $_GET['codigo'];
 
$consulta = "SELECT `Arquivo`,`Tipo` FROM `arquivos` WHERE Codigo= ' ".$codigo." ' ";
$resultado = mysql_query($consulta);
 
$dados = mysql_fetch_array($resultado);
$tipo = $dados['Tipo'];
$Arquivo = $dados['Arquivo'];
 
   //EXIBE ARQUIVO  - se o navegador não oferecer suporte para a extensão sera solicita dowload do arquivo
   header("Content-type: ".$tipo."");
   echo $Arquivo;
 
?

file_get_contents — Lê todo o conteúdo de um arquivo para uma string
mysql_real_escape_string — Escapa os caracteres especiais numa string para usar em um comando SQL, levando em conta o
copy — Copia arquivo
move_uploaded_file — Move um arquivo enviado para uma nova localização

Download – banco
binario.sql

Pessoal basicamente é isto, um script que poderá ser usado de várias maneiras e melhorado por você conforme sua necessidade.