Foros del Web » Programando para Internet » PHP »

[SOLUCIONADO] Leer text Pesado con PHP

Estas en el tema de Leer text Pesado con PHP en el foro de PHP en Foros del Web. buenas tardes Queridos compañeros un gran saludo. Tengo un problema grandisimo, necesito leer un archivo text de 22MB , pero me sale servidor reiniciado , ...
  #1 (permalink)  
Antiguo 05/05/2014, 16:15
Avatar de informacionsys  
Fecha de Ingreso: mayo-2011
Ubicación: Bogota D.C
Mensajes: 793
Antigüedad: 12 años, 11 meses
Puntos: 76
Leer text Pesado con PHP

buenas tardes

Queridos compañeros un gran saludo.

Tengo un problema grandisimo, necesito leer un archivo text de 22MB , pero me sale servidor reiniciado , lo ejecuto y a los 30 segundos mas o menos me sale dicho mensaje, he configurado todas las directivas necesarias para aumentar el tiempo de ejecución , pero nada...

He pensado en ideas como leer el archivo por partes, o dividirlo en varios archivos para leerlos mas facil, pero no he encontrado absolutamente nada parecido a lo que busco...

  #2 (permalink)  
Antiguo 05/05/2014, 16:27
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Leer text Pesado con PHP

¿Y no has pensado, tal vez, en usar un mejor lenguaje que PHP para eso?
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #3 (permalink)  
Antiguo 05/05/2014, 16:43
Avatar de informacionsys  
Fecha de Ingreso: mayo-2011
Ubicación: Bogota D.C
Mensajes: 793
Antigüedad: 12 años, 11 meses
Puntos: 76
Respuesta: Leer text Pesado con PHP

Hola....

Si pudiera hacerlo no duraria en usar otro lenguaje, pero tiene que ser con Php, de hecho la ideas de leerlo por partes , fue de un compañero quien me dijo que alguna vez le habia tocado leer un archivo por bytes en c++ , pense que de pronto en php se podia simular lo mismo...
  #4 (permalink)  
Antiguo 05/05/2014, 16:52
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años
Puntos: 292
Respuesta: Leer text Pesado con PHP

Prueba con por ejemplo..

Código PHP:
Ver original
  1. ini_set('max_execution_time',3600);  
  2. ini_set('memory_limit', 512 Mb);

Lo mas probable es que lo de arriba No funcione en el servidor de produccion pero si en tu maquina xD

---
En tu lugar, si es que quieres en TU maquina propia leeria todo el archivo en php o en lenguaje que sepas... y me guardaria en otro archivo las posiciones especificas que necesito para procesar ese archivo:

- Son registros ? fin de registro.

- Solo texto ? donde estan los saltos de linea


Luego subiria por ftp ese archivo junto con el "descriptor" por decirlo asi que generastes en tu maquina.

En el servidor programas un cronojob cada 1 minuto a un script que lo que hace es leer el archivo por partes desde los puntos especificos (o multiplos de ellos en realidad, en una cantidad manejable) definidos por el descriptor y vas procesando esos pedazos!

Código PHP:
Ver original
  1. <?php
  2. // Primero: leo el archivo con las posiciones de salto y un segundo archivo donde tengo un contador para saber a cual de esas posicones saltar
  3.  
  4. // Luego... abro el archivo molesto
  5. $fp = fopen('somefile.txt', 'r');
  6.  
  7. // saltar a una posicion especifica
  8. fseek($fp, $ini);
  9.  
  10. // leer una cantidad especifica de bytes (cierta cantidad de 'registros')
  11. $data = fgets($fp, 4096);
  12.  
  13. procesar($data);  //  :))))
__________________
Salu2!

Última edición por Italico76; 05/05/2014 a las 17:12
  #5 (permalink)  
Antiguo 06/05/2014, 01:09
Avatar de Triby
Mod on free time
 
Fecha de Ingreso: agosto-2008
Ubicación: $MX->Gto['León'];
Mensajes: 10.106
Antigüedad: 15 años, 8 meses
Puntos: 2237
Respuesta: Leer text Pesado con PHP

Yo he abierto con PHP archivos incluso mayores y no he tenido problemas, será cuestión de ver el código que estás usando.

Por cierto, como te comenta Italico76, en la mayoría de servidores compartidos no podrás modificar tiempo máximo de ejecución, uso de memoria ni otras directivas "al vuelo", para eso requieres, al menos, un VPS.
__________________
- León, Guanajuato
- GV-Foto
  #6 (permalink)  
Antiguo 06/05/2014, 07:03
Avatar de informacionsys  
Fecha de Ingreso: mayo-2011
Ubicación: Bogota D.C
Mensajes: 793
Antigüedad: 12 años, 11 meses
Puntos: 76
Respuesta: Leer text Pesado con PHP

Hola a todos..

bueno de hecho es una intranet , y tengo acceso para modificar cualquier directiva del php.ini...

les comento la logica rapidamente: En html muestro la vista previa del archivo con sus cabeceras y un solo registro nada mas.... el usuario tiene la posibilidad de escoger que columnas o cabeceras desea trabajar....despues de eso, leo todo el archivo completo y almaceno en un arreglo final la informacion de las columnas que escogió el usuario para posteriormente almacenarla en la base de datos...

Aqui el codigo :

Código PHP:
Ver original
  1. public function FileMatrizAsociativo($file_name,$separador)
  2.     {
  3.                
  4.         $file  = fopen($file_name,"r");
  5.         $matriz = array();
  6.  
  7.         if($file)
  8.         {  
  9.             $matriz = array();
  10.             $contador = 0;
  11.             $cabeza = fgetcsv($file,50000000,$separador);
  12.             $cantcols = count($cabeza);
  13.  
  14.  
  15.             while($recordSet = fgetcsv($file,50000000,$separador))
  16.             {  
  17.                 foreach($this->campos as $camp)//arreglo con los campos que escogio el usuario
  18.                 {  
  19.                     for($cols = 0; $cols < $cantcols ; $cols++)// for columnas del archivo
  20.                     {  
  21.                         //quita espacios
  22.                         $indices = str_replace(" ","",trim($cabeza[$cols]));
  23.                         //quitar caracteres raros
  24.                         $namecabeza = $this->QuitarCaracteresRarosCargue(utf8_encode($indices));
  25.                        
  26.                         if(trim($camp->COLUMN_NAME) == strtoupper($namecabeza))
  27.                         {  
  28.                             $arreglodatos[strtolower($camp->COLUMN_NAME)] = $recordSet[$cols];
  29.                         }
  30.                     }// for de la cabeza del archivo
  31.  
  32.                 }// foreach campos
  33.                
  34.                   array_push($matriz,$arreglodatos);
  35.                 $contador++;
  36.             }// while
  37.         }// fin validacion archivo
  38.  
  39.         return $matriz;
  40.     }

PD: La funcion anterior la uso para leer archivos text y/o csv; para leer excel uso una libreria, pero la logica es la misma....
  #7 (permalink)  
Antiguo 06/05/2014, 12:35
Colaborador
 
Fecha de Ingreso: mayo-2008
Ubicación: $MX['VZ']['Xalapa']
Mensajes: 3.005
Antigüedad: 15 años, 11 meses
Puntos: 528
Respuesta: Leer text Pesado con PHP

Meter 22 mb en una variable no es algo que php no pueda hacer, pero suponiendo que tienes recursos escasos, debes considerar mejorar tu algoritmo.

Si el usuario va a indicar qué columnas quiere guardar en la base de datos, puedes mostrarle por ejemplo la primer hoja (unas cuantas lineas) del archivo,una vez que te indiquen qué columnas quieren, lees linea por linea el archivo seleccionando las columnas que quieren guardar y las guardas, pero sin tener que meter todo en memoria.
  #8 (permalink)  
Antiguo 06/05/2014, 13:43
Avatar de informacionsys  
Fecha de Ingreso: mayo-2011
Ubicación: Bogota D.C
Mensajes: 793
Antigüedad: 12 años, 11 meses
Puntos: 76
Respuesta: Leer text Pesado con PHP

hola

En la vista previa lo hago asi, solo le muestro el primero registro nada mas, ya cuando voy a guardar toda la informacion vuelvo y leo el archivo usando la funcion que mostre anteriormente.

Logre simplificar la funcion a esto:

Código PHP:
Ver original
  1. public function FileMatrizAsociativo($file_name,$separador)
  2.     {
  3.                
  4.         $file   = fopen($file_name,"r");
  5.         $matriz = array();
  6.                        
  7.         if($file)
  8.         {
  9.             while($recordSet = fgetcsv($file,50000000,$separador))
  10.             {  
  11.                 $dataInfo = array();
  12.  
  13.                 foreach($this->campos as $camp)
  14.                 {
  15.                     $dataInfo[strtolower($camp->COLUMN_NAME)] = $recordSet[$camp->id];
  16.                 }
  17.                
  18.                 array_push($matriz,$dataInfo);                
  19.             }// while
  20.         }// fin validacion archivo
  21.         //die(var_dump($matriz));
  22.         return $matriz;
  23.     }

Mejoro bastante ya no se revienta a los 35s si no 1m 18s , pero a un asi aparecer servidor reiniciado , aunque por debajo sigue insertando los registros...

Última edición por informacionsys; 06/05/2014 a las 13:50
  #9 (permalink)  
Antiguo 06/05/2014, 15:07
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años
Puntos: 292
Respuesta: Leer text Pesado con PHP

Cita:
Iniciado por informacionsys Ver Mensaje
Mejoro bastante ya no se revienta a los 35s si no 1m 18s , pero a un asi aparecer servidor reiniciado , aunque por debajo sigue insertando los registros...
Por debajo no.... sino que hace su trabajo HASTA que se queda sin recursos
__________________
Salu2!
  #10 (permalink)  
Antiguo 06/05/2014, 15:25
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Leer text Pesado con PHP

Yo pienso que hacer esperar al usuario "en lo que el servidor procesa lo que sea" es mala experiencia de usuario, de entrada yo no usaría ningún lenguaje del lado del servidor web para procesar nada tan largo o pesado.

En dado caso implementaría un sistema de queues en la cual programaría dicha tarea en el background del sistema y una vez finalizada notificaría en el dashboard del usuario por dicho resultado.

Desde la interfaz web únicamente registraría dicha tarea de manera asíncrona, no importa si cierro la pagina o navego, yo sé que el sistema está haciendo su trabajo y no me obliga a esperar a que lo termine.

Así que una solución correcta está muy lejos de "configurar el tiempo de espera" de nuestra instalación de PHP, dicho de otro modo: esa solución se le ocurre a cualquiera, un profesional no lo haría así.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #11 (permalink)  
Antiguo 06/05/2014, 15:27
Avatar de informacionsys  
Fecha de Ingreso: mayo-2011
Ubicación: Bogota D.C
Mensajes: 793
Antigüedad: 12 años, 11 meses
Puntos: 76
Respuesta: Leer text Pesado con PHP

gracias por la aclaracion..

Viendo el proceso despues de que la funcion retorna el arreglo final se recorre para la insercion , lo cual hace que se demore mas... entonces se me ocurrio la idea de hacerlo el dos acciones...

1) Guardar el arreglo en un txt , en formato json_encode, y mostrar un boton al usuario que diga Finalizar. 2) Leer el txt , para solo recorrer la informacion e insertarla..

Bueno y adivinen que , no funcionooo ....


Gracias por tu sugerencia pateketrueke , lo que dices es muy cierto... bueno seguire buscando otras alternativas....

Última edición por informacionsys; 06/05/2014 a las 15:49
  #12 (permalink)  
Antiguo 06/05/2014, 16:10
Avatar de dashtrash
Colaborador
 
Fecha de Ingreso: abril-2007
Ubicación: Ni en Sevilla,ni en Sanlúcar..qué más da..
Mensajes: 927
Antigüedad: 17 años
Puntos: 270
Respuesta: Leer text Pesado con PHP

Cita:
Iniciado por informacionsys Ver Mensaje
gracias por la aclaracion..

Viendo el proceso despues de que la funcion retorna el arreglo final se recorre para la insercion ,
Retornas un array para hacer una insercion?
Para qué creas el array con todo el fichero??
Lee hasta un maximo de x filas, compones un insert con esas x filas, y lo ejecutas.
Luego lees x más.

Lo que comenta pateketrueke se hace muy fácilmente con fastcgi_finish_request en caso de que estés usando php con fastcgi.
  #13 (permalink)  
Antiguo 06/05/2014, 16:17
Avatar de informacionsys  
Fecha de Ingreso: mayo-2011
Ubicación: Bogota D.C
Mensajes: 793
Antigüedad: 12 años, 11 meses
Puntos: 76
Respuesta: Leer text Pesado con PHP

Hola...

Bueno ,creo que esa fue una de las primeras ideas , poder leer el archivo por partes.... pero googleando no encontre nada parecido....
  #14 (permalink)  
Antiguo 06/05/2014, 16:55
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años
Puntos: 292
Respuesta: Leer text Pesado con PHP

Lo que comenta @pateketrueke esta muy bien explicado aqui:

http://stackoverflow.com/questions/4...finish-request
__________________
Salu2!
  #15 (permalink)  
Antiguo 06/05/2014, 16:59
Avatar de informacionsys  
Fecha de Ingreso: mayo-2011
Ubicación: Bogota D.C
Mensajes: 793
Antigüedad: 12 años, 11 meses
Puntos: 76
Respuesta: Leer text Pesado con PHP

Hola

Compañeros gracias por el material...... voy a revisarlo esta noche .....

Muchas Gracias a todossss.....
  #16 (permalink)  
Antiguo 06/05/2014, 17:05
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años
Puntos: 292
Respuesta: Leer text Pesado con PHP

Para que leas algo mas antes de dormir te dejo un enlace donde muestran el uso de funciones para conocer el uso de CPU y memoria de tu script:

http://code.tutsplus.com/tutorials/9...now--net-11304
__________________
Salu2!
  #17 (permalink)  
Antiguo 06/05/2014, 20:17
Avatar de informacionsys  
Fecha de Ingreso: mayo-2011
Ubicación: Bogota D.C
Mensajes: 793
Antigüedad: 12 años, 11 meses
Puntos: 76
Respuesta: Leer text Pesado con PHP

Cita:
Iniciado por Italico76 Ver Mensaje
Para que leas algo mas antes de dormir te dejo un enlace donde muestran el uso de funciones para conocer el uso de CPU y memoria de tu script:

http://code.tutsplus.com/tutorials/9...now--net-11304
Gracias por el dato, la mayoria no las conocia.....
  #18 (permalink)  
Antiguo 07/05/2014, 07:40
Avatar de dashtrash
Colaborador
 
Fecha de Ingreso: abril-2007
Ubicación: Ni en Sevilla,ni en Sanlúcar..qué más da..
Mensajes: 927
Antigüedad: 17 años
Puntos: 270
Respuesta: Leer text Pesado con PHP

Cita:
Iniciado por informacionsys Ver Mensaje
Hola...

Bueno ,creo que esa fue una de las primeras ideas , poder leer el archivo por partes.... pero googleando no encontre nada parecido....
No lees el archivo por partes.Lees el archivo de 1 vez.Lo que no haces es cargar todo el fichero en un array, y luego hacer inserts desde un array con TODAS las filas del fichero.
Si tu fichero es de 1000000 de lineas,no crees un array con 1000000 de elementos, y luego haces el insert.Lee el fichero linea a linea, pero cada vez que leas 1000, haz insert de esas mil (entiendo que harás un batch insert, y no 1000000 de inserts...).
Vacias el array, y vuelta a empezar.Así, 1000 veces.
No es "leer el archivo por partes".Es simplemente un for , y una operacion módulo (y una comparación).
  #19 (permalink)  
Antiguo 08/05/2014, 09:43
Avatar de informacionsys  
Fecha de Ingreso: mayo-2011
Ubicación: Bogota D.C
Mensajes: 793
Antigüedad: 12 años, 11 meses
Puntos: 76
Respuesta: Leer text Pesado con PHP

Cita:
Iniciado por dashtrash Ver Mensaje
No lees el archivo por partes.Lees el archivo de 1 vez.Lo que no haces es cargar todo el fichero en un array, y luego hacer inserts desde un array con TODAS las filas del fichero.
Si tu fichero es de 1000000 de lineas,no crees un array con 1000000 de elementos, y luego haces el insert.Lee el fichero linea a linea, pero cada vez que leas 1000, haz insert de esas mil (entiendo que harás un batch insert, y no 1000000 de inserts...).
Vacias el array, y vuelta a empezar.Así, 1000 veces.
No es "leer el archivo por partes".Es simplemente un for , y una operacion módulo (y una comparación).
Hola...


Muchas Gracias, me diste una excelente idea que me funciono a la maravilla....
  #20 (permalink)  
Antiguo 08/05/2014, 09:57
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años
Puntos: 292
Respuesta: Leer text Pesado con PHP

Pues si.... varios te digimos "procesa por pedazos" !!!
__________________
Salu2!
  #21 (permalink)  
Antiguo 08/05/2014, 10:30
Avatar de informacionsys  
Fecha de Ingreso: mayo-2011
Ubicación: Bogota D.C
Mensajes: 793
Antigüedad: 12 años, 11 meses
Puntos: 76
Respuesta: Leer text Pesado con PHP

Cita:
Iniciado por Italico76 Ver Mensaje
Pues si.... varios te digimos "procesa por pedazos" !!!


Si y Muchas gracias, solo que de primerazo no veia la logica para hacerlo, ....

Les agradezco a todos por su gran colaboracion ..

Etiquetas: pesado, text
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 13:58.