miércoles, 19 de febrero de 2014

Leer ficheros de texto con Php.

En algunas aplicaciones nos es necesario entrar información al sistema obtenida desde ficheros de texto en lugar de utilizar formularios. Por ejemplo si tenemos facturas de productos vendidos, el proceso sería más rápido si cargamos estos ficheros y procesamos la información que nos interesa en un proceso automático.

En este artículo queremos brindar algunas prácticas interesantes para realizar este procesamiento utilizando las ventajas para el trabajo con ficheros que nos brinda Php.

Por ejemplo utilizando el caso de productos que habíamos mencionado, supongamos que tenemos un fichero en formato txt que tiene la información de una factura, pondremos un caso bien sencillo donde tenemos el número de factura, algunos datos adicionales del emisor y receptor de la factura y una tabla que contiene los detalles de la venta realizada:

En este caso podemos leer el fichero línea a línea e ir realizando las validaciones que nos interesan y recoger la información. Para realizar el procesamiento del fichero e ir sacándonos del programa cuando se encuentre que no cumple algunas reglas de validación podemos usar las sentencias Try-catch y lanzamos el error detectado.

Por ejemplo:

<?php          
try{
if (file_exists("Factura.txt")===FALSE)
throw new Exception('El fichero no existe.');
$text = file_get_contents("Factura.txt");
if ($text === FALSE)
{
throw new Exception('El fichero no puedo ser leído.');
}
$text= mb_convert_encoding($text, 'UTF-8',mb_detect_encoding($text, 'UTF-8, ISO-8859-1', true));
$texts = explode("\n",$text);
echo "Fichero leído correctamente." ;
}
catch (Exception $e)
{
echo 'Excepción capturada: ', $e->getMessage(), "\n";
}
?>

Con la función file_exists verificamos que efectivamente el fichero exista en nuestro directorio, y procedemos a leer el archivo completo como una única cadena con file_get_contents, en caso de fallo esta función devuelve false. Y finalmente en este bloque dividimos esa cadena en líneas, para esto hacemos uso de una función muy interesante para este caso que es la función explode que divide una cadena ($text) por otra (“/n”) en este caso fin de línea y nos devuelve una matriz que contiene las subcadenas contenidas en la cadena $text y separadas por el fin de línea. Ya con esto tenemos en $texts el fichero línea a línea.

Para las primeras cuatro líneas hacemos un procesamiento similar en todos los casos, siempre debe leerse una etiqueta determinada y después la información asociada a esta etiqueta:

$invoice_no = trim($texts[0]);
$invoice_no = explode("Factura No.",$invoice_no);
if(count($invoice_no)!=2)
throw new ErrorException('La etiqueta "Factura No." no existe o está escrita incorrectamente');
$invoice_no = trim($invoice_no[0]);

Siempre es interesante utilizar la función trim para eliminar los espacios en blanco (u otros caracteres) del principio y final de la cadena. Siempre verificamos en estos caso que la cantidad de elementos contenidos en la matriz $invoice_no después de aplicar explode no puede ser diferente de 2, porque si la información viene correctamente en la posición 1 vamos a obtener la que nos interesa.

Lo que sigue es leer la información de la tabla de productos, para eso primeramente verificamos que los datos de la cabecera sean correctos, comparándolo con un arreglo que previamente tenemos y después en un ciclo recorremos los productos hasta llegar al fin de la tabla, asumimos que terminamos la lectura de la tabla cuando llegamos a encontrar la cadena “Total:” que es lo que sigue detrás de la misma.

$cabecera = array('Cantidad','Nombre','Precio Unitario', 'Descuento', 'Importe');
$cabecera_tabla = trim($texts[5]);
$cabecera_tabla = explode("\t",$cabecera_tabla);
$result= array_diff($cabecera_tabla,$cabecera);
if(!empty($result))
throw new ErrorException("Los datos de la cabecera de la tabla de productos están escritos incorrectamente");

$datos = array();
$tabla = true;
$no_producto = 0;
$j= 6;
while ($tabla==TRUE)
{
//Verificar si se terminó la tabla
$end = strpos($texts[$j], 'Total:');
if($end === FALSE)
{
$detalle = explode("\t",trim($texts[$j]));
$datos[$no_producto]->CANTIDAD = $detalle[0];
$datos[$no_producto]->NOMBRE = $detalle[1];
$datos[$no_producto]->PRECIOUNITARIO = $detalle[2];
$datos[$no_producto]->DESCUENTO = $detalle[3];
$datos[$no_producto]->IMPORTE = $detalle[4];
$no_producto++;
$j++;
}
else
{
//termino la tabla
$tabla = false;
}
}

La función strpos devuelve la posición numérica de la primera aparición de una cadena, si necesitáramos la cadena en sí utilizáramos strstr aunque esta última es más lenta y consume más memoria. Si no queremos distinguir entre mayúsculas y minúsculas podemos utilizar stripos y stristr.

Es todo, espero haya sido de utilidad.


¿Te ha gustado este Post? Compártelo con tus amigos.

No hay comentarios:

Publicar un comentario

IconIconIcon