Recentemente encontrei um rapaz que estava procurando um artigo sobre impressora fiscal Bematech com PHP, e no Google só se achava artigo com o link do blog do Deivison, que por sinal, não existe mais. Então procurei no web.archive.org e encontrei, assim sendo, postarei aqui para ficar registrado para quem procurar encontrar facilmente.
Um dos maiores problemas com o desenvolvimento de sistemas para web é a comunicação com periféricos. Não conheço uma maneira de acessar uma porta de comunicação direto com o browser. Mesmo assim eu precisava desenvolver um aplicativo comercial e a partir dele enviar e recuperar dados de uma impressora fiscal Bematech em uma intranet com 5 computadores Windows.
Entrei no site da Bematech (http://www.bematech.com.br) e encontrei um aplicativo de comunicação com a impressora fiscal que roda no shell do Linux. Tive, então, a idéia de fazer com o computador onde fica a impressora o servidor Linux, onde rodaria meu aplicativo PHP, e com o PHP fazer o aplicativo ser executado sempre que necessário.
O aplicativo da Bematech funciona da seguinte forma:
No arquivo "BEMAFILX.CMD" você grava os comandos para impressora fiscal, depois executa o "BEMAFILX.OUT", que pega as informações do primeiro arquivo e envia para a porta de comunicação da impressora. Logo depois, grava nos arquivos "RETORNO.TXT" e "STATUS.TXT" respectivamente as informações de retorno e o status da impressora fiscal.
Com o arquivo "BEMAFILX.INI" você define as configurações necessárias para o aplicativo funcionar corretamente, como por exemplo a porta serial onde a impressora está ligada.
Criei depois uma função para gravar os comandos no "BEMAFILX.CMD", executar o "BEMAFILX.OUT" e ler os arquivos de status e retorno:
function envia_dado($dado) {
// A variável $dado contém as informações que serão enviadas para impressora fiscal
$fp =
fopen("bemafilx.cmd",
"w");
// abre o arquivo de comandos
$executa = "./bemafilx.out";
$comando = `$executa`; // executa o aplicativo "bemafilx.out"
if (file_exists("status.txt")) { // pega as informações do arquivo 'status.txt'
$filename = "status.txt";
$fd =
fopen ($filename,
"r");
$fp =
fopen("status.txt",
"w");
// logo depois de ler o arquivo ele deixa em branco o conteúdo do arquivo
} else {
$status = "";
}
if (file_exists("retorno.txt")) { // lê o conteudo do arquivo de retorno
$filename = "retorno.txt";
$fd =
fopen ($filename,
"r");
chmod ("retorno.txt",
0666);
$fp =
fopen("retorno.txt",
"w");
// deixa em branco o conteúdo do arquivo de retorno
} else {
$retorno = "";
}
return $retorno;
}
Note que a variável de $status nunca é usada, na verdade eu ainda não precisei testar o status da impressora em meus aplicativos.
Uma impressora fiscal é diferente de uma impressora comum e não aceita qualquer dado, na verdade existe uma formatação especial e que você pode entender lendo o manual da impressora que vem junto com o equipamento e que também está disponível no site da Bematech.
Exemplo de uso da função envia_dado():
$retorno = envia_dado(chr(27).chr(251).'00|'.chr(27)); // Esse comando abre o cupom fiscal
$retorno = envia_dado(chr(27).chr(251).'05|'.chr(27)); // Esse comando imprime uma Redução Z
Eu criei minhas próprias funções de formatação e só não disponibilizo pelo motivo de achar que elas ainda não estão 100% e aconselho você mesmo a criar as suas.
Não encontrei absolutamente nada sobre impressora fiscal + php e tive que me virar, então achei interessante compartilhar o que descobri com outros programadores PHP. Com certeza essa não é a única forma de fazer isso e gostaria de conhecer outras maneiras.
Será que é só comigo? A cada novo sistema algum cliente inventa algo mais difícil e com certeza no futuro vou ter que fazer comunicação com leitores de código de barra, teclados para senha, impressoras matriciais que precisam imprimir caracteres não gráficos para uma impressão mais rápida, balanças e outros dispositivos. E tudo isso não em uma Intranet mas na Internet o que torna meu trabalho atualmente impossível. Por isso tenho muito interesse em comunicação de periféricos usando o PHP no browser. Já pensei na possibilidade do desenvolvimento de plugins, mas ainda não tenho conhecimento de como fazer e nem sei se um plugin pode enviar dados a uma porta serial (acho que não).
Autor: Deivison Alves Elias