Dica rápida: PHP + BYTEA

Fala galera! Estava aqui tentando exibir imagens armazenadas em um campo bytea do PostgreSQL e apanhei feito mala velha usando o par de funções pg_escape_bytea e pg_unescape_bytea.

Consegui achar a solução em um comentário no manual do PHP: “To prevent any problems with encoding you could use hexadecimal or base64 input to save and retrieve data to the database”

Usei base64_encode/base64_decode e tudo funcionou perfeitamente. Então, se você está tentando usar pg_escape_bytea($content) e pg_unescape_bytea($content) mude para base64_encode($content) para inserir no banco e base64_decode($content) para exibir no browser.

Valeu Mike-RaWare!

Para quem quiser ver o post: http://php.net/manual/en/function.pg-escape-bytea.php

Blob do SQL Server truncados no PHP

Hello folks, depois de um bom tempo sem postar nada vai ai uma dica de configuração do PHP com SQL Server. Essa dica é para quem está recuperando um blob (varbinary, image, etc) e quando é exibido pelo PHP vem truncado… exibindo parte da imagem e o resto em cinza indicando que ali teria que ter algo =]. Para resolver basta alterar o valor das propriedades mssql.textlimit e mssql.textsize no php.ini. Lembrando que os valores estão em bytes.

Abrasss

Postgres (Large Objects) + CodeIgniter (Image_Lib)

Estou no início do meu aprendizado com CodeIgniter e PostgreSQL e nesse pouco tempo não vi nenhuma referência à manipulação de blobs na documentação ou mesmo no código do framework. Para contornar o problema criei um helper para me auxiliar nessa tarefa. Utilizando as funções nativas do PHP em conjunto com o CodeIgniter, você pode manipular facilmente seus large objects. O único problema que tive foi com a image_lib usando gd2 e imagens geradas com pg_lo_read_all, sendo totalmente on the fly, isso ficará para um outro post.

Ok, vamos ao que interessa:

  • Exportando o large object – método 1
if ( ! function_exists('pgsql_lo_export')) {

	function pgsql_lo_export($id_object, $caminho_arquivo)
	{
		$CI =& get_instance();

		// Inicia a transação
		$CI->db->trans_start();

		// Exporta o arquivo
		$retorno = pg_lo_export($id_object, $caminho_arquivo);

		// Encerra a transação
		$CI->db->trans_complete();

		return $retorno;
	}
}

linha 5: Recupera a instância do CodeIgniter, sem isso não é possível usar as bibliotecas.

linha 8 e 14: Todas as funções de manipulação dos large objects devem estar dentro de uma transação e também precisam de um resource para a conexão. Essas linhas resolvem os dois problemas, engloba a chamada da função em uma transação e também cria uma conexão padrão. Não entendeu? clique aqui.

linha 11: Faz a mágica da exportação

  • Exibir a imagem – método 1
// Método do controller
public function thumbnail($oid)
{
	// define os diretórios
	$diretorio_saida = str_replace(SELF,'',APPPATH)."uploads/";
	$arquivo_saida = tempnam($diretorio_saida,'fa_');

	// Exporta o large object
	pgsql_lo_export($oid, $arquivo_saida);

	$config['image_library'] = 'gd2';
	$config['source_image'] = $arquivo_saida;
	$config['dynamic_output'] = TRUE;
	$config['create_thumb'] = TRUE;
	$config['maintain_ratio'] = TRUE;
	$config['width'] = 160;
	$config['height'] = 120;

	// Carrega a image_lib
	$this->load->library('image_lib', $config);

	// Tenta redimensionar a imagem
	if ( ! $this->image_lib->resize())
	{
		echo $this->image_lib->display_errors();
	}

	// Apaga o arquivo temporário
	unlink($arquivo_saida);
}

linha 5 e 6: Define onde gerar os arquivos temporários. Atenção para a linha 6 que usa a função tempnam, essa função cria um arquivo temporário com nome único. Vai ser útil para evitar problemas com nomes de arquivos

linha 9: Exporta o blob para o arquivo temporário usando a função criada anteriormente

linha 13 e 14: A opção dynamic_output indica que a imagem não será salva no disco (on the fly) e create_thumb que o arquivo original não será modificado

linha 23: Redimensiona nossa imagem

linha 29: Apaga nosso arquivo temporário

  • Exibir a imagem – método 2 (sem churumelas)
if ( ! function_exists('pgsql_lo_read_all')) {

	function pgsql_lo_read_all($id_objeto)
	{

		$CI =& get_instance();

		// Inicia a transação
		$CI->db->trans_start();

		// Abre o OID para leitura e envia para o browser
		$hnd = pg_lo_open($id_objeto, "r");
		pg_lo_read_all($hnd);
		pg_lo_close($hnd);

		// Encerra a transação
		$CI->db->trans_complete();

	}
}

Essa função é bem parecida com a primeira função, a diferença é que ela não exporta o binário para um arquivo no disco, o conteúdo é enviado diretamente para o browser usando pg_lo_read_all.

É isso ai, chega de programar … agora é a vez da cremosa gelada. Boas festas e até o próximo post.