EL
Gravando imagem no banco de dados
Olá colegas.
Eu precisei gravar uma imagem dentro de um campo blob, mas não encontrei exemplo de como fazer isso no adianti.
Segue a forma como resolvi. Talvez não seja a melhor forma, mas pelo menos resolveu meu problema.
Caso algum colega saiba de uma melhor forma de resolver o problema, por gentileza coloque aqui.
A ideia é sempre usar um arquivo de imagem, antes de gravar no banco, ou até mesmo antes de renderizar na tela.
Esse arquivo fica numa pasta temporaria, e será apagado depois de certo tempo.
O unico incoveniente é que, toda vez que o registro é editado, um novo arquivo temporario é criado. Logo, a pasta "tmp" vai enchendo. Por isso que eu preciso apagar os arquivos temporarios. Se alguem tiver uma ideia melhor, posta aqui.
Na classe active Record tive que fazer o seguinte: Criei um campo virtual "imagem" que irá receber o caminho do arquivo temporario através de um metodo magico.
Na classe TPage de edição, onde a imagem será mostrada, eu resolvi usar um TImageCropper para pegar o campo virtual e mostrar na tela. Caso o usuario deseje selecionar outra imagem para ser gravada no banco, esse mesmo campo será usado para armazenar o local onde a imagem foi gravada.
Eu precisei gravar uma imagem dentro de um campo blob, mas não encontrei exemplo de como fazer isso no adianti.
Segue a forma como resolvi. Talvez não seja a melhor forma, mas pelo menos resolveu meu problema.
Caso algum colega saiba de uma melhor forma de resolver o problema, por gentileza coloque aqui.
A ideia é sempre usar um arquivo de imagem, antes de gravar no banco, ou até mesmo antes de renderizar na tela.
Esse arquivo fica numa pasta temporaria, e será apagado depois de certo tempo.
O unico incoveniente é que, toda vez que o registro é editado, um novo arquivo temporario é criado. Logo, a pasta "tmp" vai enchendo. Por isso que eu preciso apagar os arquivos temporarios. Se alguem tiver uma ideia melhor, posta aqui.
Na classe active Record tive que fazer o seguinte: Criei um campo virtual "imagem" que irá receber o caminho do arquivo temporario através de um metodo magico.
- <?php
- class MinhaClasse extends TRecord
- {
- const TABLENAME = 'minha_tabela';
- ...
- ...
- private $imagem; // esta variavel sera usada para conversao
- public function __construct($id = NULL, $callObjectLoad = TRUE)
- {
- ...
- parent::addAttribute('campo_blob_do_banco');
- ...
- }
- // este metodo magico sera usado para pegar a imagem que ja esta no banco. Inicialmente ele grava essa imagem num arquivo temporario.
- // Ele tambem apaga imagens antigas.
- //
- public function get_imagem()
- {
- if (!empty($this->img_brasao)) {
- // apagando arquivos antigos
- $dir = getcwd()."/tmp/";
- $tempo = 3600;
- /*** percorrendo todos os arquivos da pasta ***/
- foreach (glob($dir."*.jpg") as $file) {
- /*** 3600 = 1hora, 86400=24horas ***/
- if(time() - filectime($file) > $tempo)
- {
- unlink($file);
- }
- }
- // gerando um nome unico
- $tmpfile = md5(date('Y-m-d H:i:s:u'));
- $output_file = getcwd()."/tmp/{$tmpfile}.jpg";
- // gravando o campo blob para um arquivo
- file_put_contents($output_file, $this->campo_blob_do_banco);
- return $output_file;
- } else return NULL;
- }
- ?>
Na classe TPage de edição, onde a imagem será mostrada, eu resolvi usar um TImageCropper para pegar o campo virtual e mostrar na tela. Caso o usuario deseje selecionar outra imagem para ser gravada no banco, esse mesmo campo será usado para armazenar o local onde a imagem foi gravada.
- <?php
- class MinhaClasseForm extends TPage
- {
- private $form;
- public function __construct( $param, $embbed=false )
- {
- parent::__construct();
- ...
- ...
- // Aqui estou pegando informacao daquele metodo magico get_imagem
- $img_brasao = new TImageCropper('imagem');
- $img_brasao->setAllowedExtensions( [ 'png', 'jpg', 'jpeg'] );
- $img_brasao->setSize(100, 200);
- $img_brasao->enableFileHandling();
- $row = $this->form->addFields( [ new TLabel('Brasão') , $img_brasao ] );
- ...
- ...
- // No momento de gravar o formulario, fazer o tratamento da imagem
- public function onSave( $param )
- {
- ...
- ...
- $data = $this->form->getData();
- $object = new $this->activeRecord;
- $object->fromArray( (array) $data);
- // Tratando a imagem antes de gravar no banco
- $nm = json_decode(urldecode($data->imagem));
- $file = getcwd().'/tmp/'. basename( $nm->fileName );
- $img = file_get_contents($file);
- $object->campo_blob_do_banco= $img;
- $object->store();
- ?>
Editado 11/02/2024 (há 7 meses) - Clique para ver alterações
Emilio,
Sugiro repensar e avaliar a possibilidade de gravar imagens nos sistema de arquivos e manter somente a referência para ela no banco de dados. Isso facilita backups (dumps), performance e outras coisinhas mais.
Att,