Jump to content
Emerson Rodrigo

Leitura de Arquivos OFX com PHP

Recommended Posts

Fala pessoal!

 

Hoje precisei criar uma rotina para importação de arquivos OFX, aqueles que são usados para fazer integração bancária.

 

Esse arquivos nada mais são do que o extrato bancário em um formato universal para integração com vários tipos de sistemas e linguagens de programação.

 

Como não é uma coisa que se acha fácil por ai, resolvi postar e deixar disponível para quem precisar.

 

Código do arquivo Ofx.php

<?phpclass Ofx {    private $ofxFile;    public function __construct($ofxFile) {        $this->ofxFile = $ofxFile;    }    /*     * Converte o arquivo OFX para XML     */    public function getOfxAsXML() {        $content = file_get_contents($this->ofxFile);        $line = strpos($content, "<OFX>");        $ofx = substr($content, $line - 1);        $buffer = $ofx;        $count = 0;        while ($pos = strpos($buffer, '<')) {            $count++;            $pos2 = strpos($buffer, '>');            $element = substr($buffer, $pos + 1, $pos2 - $pos - 1);            if (substr($element, 0, 1) == '/')                $sla[] = substr($element, 1);            else                $als[] = $element;            $buffer = substr($buffer, $pos2 + 1);        }        $adif = array_diff($als, $sla);        $adif = array_unique($adif);        $ofxy = $ofx;        foreach ($adif as $dif) {            $dpos = 0;            while ($dpos = strpos($ofxy, $dif, $dpos + 1)) {                $npos = strpos($ofxy, '<', $dpos + 1);                $ofxy = substr_replace($ofxy, "</$dif>\n<", $npos, 1);                $dpos = $npos + strlen($element) + 3;            }        }        $ofxy = str_replace('&', '&', $ofxy);        return $ofxy;    }    /*     * Retorna o Saldo da conta na data de exportação do extrato     */    public function getBalance() {        $xml = new SimpleXMLElement($this->getOfxAsXML());        $balance = $xml->BANKMSGSRSV1->STMTTRNRS->STMTRS->LEDGERBAL->BALAMT;        $dateOfBalance = $xml->BANKMSGSRSV1->STMTTRNRS->STMTRS->LEDGERBAL->DTASOF;        $date = strtotime(substr($dateOfBalance, 0, 8));        $dateToReturn = date('Y-m-d', $date);        return Array('date' => $dateToReturn, 'balance' => $balance);    }    /*     * Retora um array de objetos com as transações     *      * DTPOSTED => Data da Transação     * TRNAMT   => Valor da Transação     * TRNTYPE  => Tipo da Transação (Débito ou Crédito)     * MEMO     => Descrição da transação     */    public function getTransactions() {        $xml = new SimpleXMLElement($this->getOfxAsXML());        $transactions = $xml->BANKMSGSRSV1->STMTTRNRS->STMTRS->BANKTRANLIST->STMTTRN;        return $transactions;    }}

Exemplo de utilização:

<?phprequire_once 'Ofx.php';$ofx = new Ofx('extrato.ofx');$saldo = $ofx->getBalance();?><html>    <head>        <title>Transações</title>    </head>    <body>        <h1>Seu saldo em <?php echo date("d/m/Y", strtotime($saldo['date'])); ?> é de R$ <?echo $saldo['balance']; ?></h1>               <h2>Transações</h2>        <table border="1" cellpadding="3" cellspacing="0">            <thead>                <tr>                    <th>Data</th>                    <th>Descrição</th>                    <th>Tipo</th>                    <th>Valor</th>                </tr>            </thead>            <tbody>                <?php foreach ($ofx->getTransactions() as $transaction) : ?>                    <tr>                        <td><?php echo date("Y-m-d", strtotime(substr($transaction->DTPOSTED, 0, 8))); ?></td>                        <td><?php echo $transaction->MEMO; ?></td>                        <td><?php echo $transaction->TRNTYPE; ?></td>                        <td><?php echo $transaction->TRNAMT; ?></td>                    </tr>                <?php endforeach; ?>            </tbody>        </table>    </body></html>

É isso ai, espero que seja útil!

Edited by Mário Monteiro
  • +1 1

Share this post


Link to post
Share on other sites

Olá Emerson.

Muito Obrigado pelo post..

mais cara infelizmente na minha maquina o código não funciona

gera vários erros de WARNiNG: SIMPLEXMLELEMENT,

ainda sou meio leigo em php e gostaria muito de sua ajuda.

não teria como postar o código zipado para download juntamente com um exemplo

de arquivo ofx.

 

Att. Alessandro

Share this post


Link to post
Share on other sites

Pra quem está tento problemas com a codificação do arquivo OFX altere a linha

$content = file_get_contents($this->ofxFile);

para:

$content = utf8_decode(file_get_contents($this->ofxFile));

isso deve resolver

Share this post


Link to post
Share on other sites

Emerson, muito obrigado. Mesmo após 2.5 anos seu post me ajudou demais.

Só deu problema em casos de OFX's provenientes do Banco do Brasil.

Aparentemente é porque os arquivos não fecham algumas tags aí dá erro.

 

Share this post


Link to post
Share on other sites

Emerson, valeu pelo post... ajudou muito.

 
Devy++, tive o mesmo problema e resolvi assim:
 
    public function __construct($ofxFile) {
        $this->ofxFile = $this->closeTags($ofxFile);
    }

    public function closeTags($ofx=null) {
      $buffer = '';
      $source = fopen($ofx, 'r') or die("Unable to open file!");
      while(!feof($source)) {
          $line = trim(fgets($source));
          if ($line === '') continue;

          if (substr($line, -1, 1) !== '>') {
              list($tag) = explode('>', $line, 2);
              $line .= '</' . substr($tag, 1) . '>';
          }
          $buffer .= $line ."\n";
      }

      $name = realpath(dirname($ofx)) . '/' . date('Ymd') . '.ofx';
      $file = fopen($name, "w") or die("Unable to open file!");
      fwrite($file, $buffer);
      fclose($file);

      return $name;
    }

Share this post


Link to post
Share on other sites
Em 14/06/2017 at 12:06, aMaltha disse:

Emerson, valeu pelo post... ajudou muito.

 
Devy++, tive o mesmo problema e resolvi assim:
 

    public function __construct($ofxFile) {
        $this->ofxFile = $this->closeTags($ofxFile);
    }

    public function closeTags($ofx=null) {
      $buffer = '';
      $source = fopen($ofx, 'r') or die("Unable to open file!");
      while(!feof($source)) {
          $line = trim(fgets($source));
          if ($line === '') continue;

          if (substr($line, -1, 1) !== '>') {
              list($tag) = explode('>', $line, 2);
              $line .= '</' . substr($tag, 1) . '>';
          }
          $buffer .= $line ."\n";
      }

      $name = realpath(dirname($ofx)) . '/' . date('Ymd') . '.ofx';
      $file = fopen($name, "w") or die("Unable to open file!");
      fwrite($file, $buffer);
      fclose($file);

      return $name;
    }

 

Share this post


Link to post
Share on other sites

o composer nao esta instalando da a mensagem de erro abaixo ---   alguem pode ajudar --  preciso importar o .ofx e gravar no Banco de Dados mysql

[InvalidArgumentException]
  Could not find a version of package asmpkg/ofx matching your minimum-stability (stable). Require it with an explicit version constraint allowing its desir   
  ed stability.

 

 

Share this post


Link to post
Share on other sites

Esse código tem problema se o cara usar uma palavra reservada na descrição do extrato bancário,
E seria interessante  bufferizar somente 1x;
mas enfim quem esta querendo resolver algum problema em código de manutenção na empresa como eu:

 

	$ofxy = $ofx;
	foreach ($adif as $dif) {
		$dpos = 0;
-		while ($dpos = strpos($ofxy, $dif, $dpos + 1)) {       // mudar essa linha
+		while ($dpos = strpos($ofxy, "<$dif", $dpos + 1)) {
			$npos = strpos($ofxy, '<', $dpos + 1);
			$ofxy = substr_replace($ofxy, "</$dif>\n<", $npos, 1);
			$dpos = $npos + strlen($element) + 3;
		}
	}
	$ofxy = str_replace('&', '&', $ofxy);
	return $ofxy;



 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.