varios valores txt texto mostrar manejo leer guardar ejemplos directorio desde datos archivos archivo php text-files edi fixed-width

valores - Biblioteca PHP para crear/manipular archivos de texto de ancho fijo.



leer y mostrar archivo de texto en php (7)

Tenemos una aplicación web que hace seguimiento de tiempo, nómina y recursos humanos. Como resultado, tenemos que escribir muchos archivos de datos de ancho fijo para exportarlos a otros sistemas (declaraciones de impuestos estatales, archivos ACH, etc.). ¿Alguien sabe de una buena biblioteca para esto donde pueda definir los tipos / estructuras de registro, y luego actuar sobre ellos en un paradigma OOP?

La idea sería una clase que entregue especificaciones y luego trabaje con una instancia de dicha especificación. ES DECIR:

$icesa_file = new FixedWidthFile(); $icesa_file->setSpecification(''icesa.xml''); $icesa_file->addEmployer( $some_data_structure );

Donde icesa.xml es un archivo que contiene la especificación, aunque podría usar llamadas OOP para definirlo usted mismo:

$specification = new FixedWidthFileSpecification(''ICESA''); $specification->addRecordType( $record_type_name = ''Employer'', $record_fields = array( array(''Field Name'', Width, Vailditation Type, options) ) );

EDITAR: No estoy buscando consejos sobre cómo escribir una biblioteca de este tipo, solo quería saber si ya existía. ¡¡Gracias!!


Creo que necesita un poco más de información de la que proporcionó: ¿Qué tipo de estructuras de datos le gustaría usar para sus registros y definiciones de columna? Parece que esta es una clase bastante especializada que requeriría personalización para su caso de uso específico.

Tengo una clase de PHP que escribí que básicamente hace lo que está buscando, pero confiando en otras clases que usamos en nuestro sistema. Si puede suministrar los tipos de estructuras de datos con los que desea utilizar, puedo verificar si funcionarán para usted y enviarlos.

Nota: publiqué esta respuesta anteriormente desde una computadora pública y no pude hacer que pareciera ser de mí (se mostró como un usuario aleatorio). Si lo ves, ignora la respuesta de "John".


Felizmente he usado esta clase para un uso similar antes. Es un archivo de clases php, pero está muy bien calificado y ha sido probado y probado por muchos. No es nuevo (2003), pero a pesar de que todavía hace un buen trabajo, tiene una API muy buena y limpia que se parece en algo al ejemplo que publicaste con muchas otras novedades.

Si puede ignorar el uso alemán en los ejemplos, y el factor de edad -> es un código muy bueno.

Posted from the example: //CSV-Datei mit Festlängen-Werten echo "<p>Import aus der Datei fixed.csv</p>"; $csv_import2 = new CSVFixImport; $csv_import2->setFile("fixed.csv"); $csv_import2->addCSVField("Satzart", 2); $csv_import2->addCSVField("Typ", 1); $csv_import2->addCSVField("Gewichtsklasse", 1); $csv_import2->addCSVField("Marke", 4); $csv_import2->addCSVField("interne Nummer", 4); $csv_import2->addFilter("Satzart", "==", "020"); $csv_import2->parseCSV(); if($csv_import->isOK()) { echo "Anzahl der Datensätze: <b>" . $csv_import2->CSVNumRows() . "</b><br>"; echo "Anzahl der Felder: <b>" . $csv_import2->CSVNumFields() . "</b><br>"; echo "Name des 1.Feldes: <b>" . $csv_import2->CSVFieldName(0) . "</b><br>"; $csv_import2->dumpResult(); }

Mis 2 centavos, buena suerte!


Lo siento, no puedo ayudarte con una clase directa. He visto algo que hace esto, pero no recuerdo dónde lo siento, pero debería ser simple para un programador construir,

Entonces, ¿cómo he visto este trabajo en un ejemplo:

php lee en los datos

php luego usa una bandera (por ejemplo, $ _GET [''type'']) para saber cómo generar los datos EG Printer, HTML, Excel

Entonces, creas archivos de plantilla para cada versión, luego, dependiendo de la bandera que cargues y utilices la plantilla definida, ya que para Ancho fijo esto es algo HTML, no PHP, así que esto debería hacerse en plantillas CSS

Entonces, a partir de esto, puede generar sus datos como lo requiera cualquier usuario,

Smarty Templates es bastante bueno para esto y luego el encabezado de php para enviar el tipo de contenido cuando sea necesario.


No conozco ninguna biblioteca PHP que maneje específicamente registros de ancho fijo. Pero hay algunas buenas bibliotecas para filtrar y validar una fila de campos de datos si puede hacer el trabajo de dividir cada línea del archivo usted mismo.

Eche un vistazo a los componentes Zend_Filter y Zend_Validate de Zend Framework. Creo que ambos componentes son bastante autónomos y solo requieren Zend_Loader para funcionar. Si lo deseas, puedes sacar solo esos tres componentes de Zend Framework y eliminar el resto.

Zend_Filter_Input actúa como una colección de filtros y validadores. Usted define un conjunto de filtros y validadores para cada campo de un registro de datos que puede utilizar para procesar cada registro de un conjunto de datos. Hay muchos filtros y validadores útiles ya definidos y la interfaz para escribir los suyos es bastante sencilla. Sugiero el filtro StringTrim para eliminar caracteres de relleno.

Para dividir cada línea en campos, extendería la clase Zend_Filter_Input y agregaría un método llamado setDataFromFixedWidth (), así:

class My_Filter_Input extends Zend_Filter_Input { public function setDataFromFixedWidth($record, array $recordRules) { if (array_key_exists(''regex'', $recordRules) { $recordRules = array($recordRules); } foreach ($recordRules as $rule) { $matches = array(); if (preg_match($rule[''regex''], $record, $matches)) { $data = array_combine($rule[''fields''], $matches); return $this->setData($data); } } return $this->setData(array()); } }

Y defina los diversos tipos de registro con expresiones regulares simples y nombres de campo coincidentes. ICESA podría verse algo como esto:

$recordRules = array( array( ''regex'' => ''/^(A)(.{4})(.{9})(.{4})/'', // This is only the first four fields, obviously ''fields'' => array(''recordId'', ''year'', ''federalEin'', ''taxingEntity'',), ), array( ''regex'' => ''/^(B)(.{4})(.{9})(.{8})/'', ''fields'' => array(''recordId'', ''year'', ''federalEin'', ''computer'',), ), array( ''regex'' => ''/^(E)(.{4})(.{9})(.{9})/'', ''fields'' => array(''recordId'', ''paymentYear'', ''federalEin'', ''blank1'',), ), array( ''regex'' => ''/^(S)(.{9})(.{20})(.{12})/'', ''fields'' => array(''recordId'', ''ssn'', ''lastName'', ''firstName'',), ), array( ''regex'' => ''/^(T)(.{7})(.{4})(.{14})/'', ''fields'' => array(''recordId'', ''totalEmployees'', ''taxingEntity'', ''stateQtrTotal''), ), array( ''regex'' => ''/^(F)(.{10})(.{10})(.{4})/'', ''fields'' => array(''recordId'', ''totalEmployees'', ''totalEmployers'', ''taxingEntity'',), ), );

Luego, puede leer su archivo de datos línea por línea y enviarlo al filtro de entrada:

$input = My_Filter_Input($inputFilterRules, $inputValidatorRules); foreach (file($filename) as $line) { $input->setDataFromFixedWidth($line, $recordRules); if ($input->isValid()) { // do something useful } else { // scream and shout } }

Para formatear los datos para volver a escribir en el archivo, probablemente querrá escribir su propio filtro StringPad que envuelve la función interna str_pad. Luego para cada registro en su conjunto de datos:

$output = My_Filter_Input($outputFilterRules); foreach ($dataset as $record) { $output->setData($record); $line = implode('''', $output->getEscaped()) . "/n"; fwrite($outputFile, $line); }

¡Espero que esto ayude!


No conozco una biblioteca que haga exactamente lo que quieres, pero debería ser bastante sencillo rodar tus propias clases para manejar esto. Suponiendo que esté principalmente interesado en escribir datos en estos formatos, usaría el siguiente enfoque:

(1) Escriba una clase de formateador ligero para cadenas de ancho fijo. Debe admitir los tipos de registro definidos por el usuario y debe ser flexible con respecto a los formatos permitidos

(2) Cree una instancia de esta clase para cada formato de archivo que use y agregue los tipos de registro requeridos

(3) Use este formateador para formatear sus datos

Como sugirió, podría definir los tipos de registro en XML y cargar este archivo XML en el paso (2). No sé cuánta experiencia tiene con XML, pero en mi experiencia, los formatos XML a menudo causan muchos dolores de cabeza (probablemente debido a mi propia incompetencia con respecto a XML). Si va a utilizar estas clases solo en su programa PHP, no hay mucho que ganar al definir su formato en XML. Usar XML es una buena opción si también necesitará usar las definiciones de formato de archivo en muchas otras aplicaciones.

Para ilustrar mis ideas, aquí es cómo creo que usaría esta clase de formateador sugerido:

<?php include ''FixedWidthFormatter.php'' // contains the FixedWidthFormatter class include ''icesa-format-declaration.php'' // contains $icesaFormatter $file = fopen("icesafile.txt", "w"); fputs ($file, $icesaFormatter->formatRecord( ''A-RECORD'', array( ''year'' => 2011, ''tein'' => ''12-3456789-P'', ''tname''=> ''Willie Nelson'' ))); // output: A2011123456789UTAX Willie Nelson // etc... fclose ($file); ?>

El archivo icesa-format-declaration.php podría contener la declaración del formato de alguna manera como esta:

<?php $icesaFormatter = new FixedWidthFormatter(); $icesaFormatter->addRecordType( ''A-RECORD'', array( // the first field is the record identifier // for A records, this is simply the character A ''record-identifier'' => array( ''value'' => ''A'', // constant string ''length'' => 1 // not strictly necessary // used for error checking ), // the year is a 4 digit field // it can simply be formatted printf style // sourceField defines which key from the input array is used ''year'' => array( ''format'' => ''% -4d'', // 4 characters, left justified, space padded ''length'' => 4, ''sourceField'' => ''year'' ), // the EIN is a more complicated field // we must strip hyphens and suffixes, so we define // a closure that performs this formatting ''transmitter-ein'' => array( ''formatter''=> function($EIN){ $cleanedEIN = preg_replace(''//D+/'','''',$EIN); // remove anything that''s not a digit return sprintf(''% -9d'', $cleanedEIN); // left justified and padded with blanks }, ''length'' => 9, ''sourceField'' => ''tein'' ), ''tax-entity-code'' => array( ''value'' => ''UTAX'', // constant string ''length'' => 4 ), ''blanks'' => array( ''value'' => '' '', // constant string ''length'' => 5 ), ''transmitter-name'' => array( ''format'' => ''% -50s'', // 50 characters, left justified, space padded ''length'' => 50, ''sourceField'' => ''tname'' ), // etc. etc. )); ?>

Entonces solo necesitas la FixedWidthFormatter clase FixedWidthFormatter , que podría verse así:

<?php class FixedWidthFormatter { var $recordTypes = array(); function addRecordType( $recordTypeName, $recordTypeDeclaration ){ // perform some checking to make sure that $recordTypeDeclaration is valid $this->recordTypes[$recordTypeName] = $recordTypeDeclaration; } function formatRecord( $type, $data ) { if (!array_key_exists($type, $this->recordTypes)) { trigger_error("Undefinded record type: ''$type''"); return ""; } $output = ''''; $typeDeclaration = $this->recordTypes[$type]; foreach($typeDeclaration as $fieldName => $fieldDeclaration) { // there are three possible field variants: // - constant fields // - fields formatted with printf // - fields formatted with a custom function/closure if (array_key_exists(''value'',$fieldDeclaration)) { $value = $fieldDeclaration[''value'']; } else if (array_key_exists(''format'',$fieldDeclaration)) { $value = sprintf($fieldDeclaration[''format''], $data[$fieldDeclaration[''sourceField'']]); } else if (array_key_exists(''formatter'',$fieldDeclaration)) { $value = $fieldDeclaration[''formatter'']($data[$fieldDeclaration[''sourceField'']]); } else { trigger_error("Invalid field declaration for field ''$fieldName'' record type ''$type''"); return ''''; } // check if the formatted value has the right length if (strlen($value)!=$fieldDeclaration[''length'']) { trigger_error("The formatted value ''$value'' for field ''$fieldName'' record type ''$type'' is not of correct length ({$fieldDeclaration[''length'']})."); return ''''; } $output .= $value; } return $output . "/n"; } } ?>

Si también necesita soporte de lectura, la clase Formatter podría extenderse para permitir la lectura también, pero esto podría estar más allá del alcance de esta respuesta.


Si este es un archivo de texto con campos separados, deberá escribirlo usted mismo. Probablemente no sea un gran problema. Buena organización, ahorrará mucho tiempo.

  1. Su necesidad universal forma de definir estructuras. Es decir, xml.
  2. Tu necesitas algo para generar ... especialmente prefiero a Smarty para esto.

Así que éste:

<group> <entry>123</entry> <entry>123</entry> <entry>123</entry> </group>

Se puede interpretar fácilmente en prueba con esta plantilla:

{section name=x1 loop=level1_arr} {--output root''s--} {section name=x2 loop=level1_arr[x1].level2_arr} {--output entry''s--} {/section} {/section}

Esto es sólo una idea.

Pero imagínate:

  1. Necesitas xml
  2. Necesitas plantilla

Es decir 2 definiciones para abstraer cualquier estructura de texto.


Tal vez las funciones dbase son las que quieres usar. No son OOP, pero probablemente no sería demasiado difícil construir una clase que actuaría sobre las funciones proporcionadas en el conjunto de bases de datos.

Eche un vistazo al siguiente enlace para obtener detalles sobre la funcionalidad dbase disponible en PHP. Si solo está buscando crear un archivo para importarlo a otro sistema, estas funciones deberían funcionar para usted. Sólo asegúrese de prestar atención a las advertencias. Algunas de las advertencias clave son:

  • No hay soporte para los índices o campos memo.
  • No hay soporte para el bloqueo.
  • Dos procesos simultáneos del servidor web que modifican el mismo archivo dBase probablemente arruinarán su base de datos.

http://php.net/manual/en/book.dbase.php