Page 1 sur 1

Script lourd

Posté : 22 juin 2008, 12:15
par Modesar
Salut,
j'ai créé un script assez lourd et difficile à exécuter sur un hébergeur.
Après avoir fait quelques optimisation, j'ai réussi à trouver un moyen d'envoyer de gros fichiers .log par le script, puis de les faire analyser.
Je rencontre alors un problème, une erreur est retournée signalant qu'il n'y a pas assez de mémoire pour pouvoir traiter le fichier quand celui-ci est trop gros.
Une fois envoyé, le fichier log est traité ligne par ligne et des informations importantes sont envoyées vers une base de données, et donc dès qu'il y a trop de lignes le serveur arrête l'exécution.
J'aimerais savoir si il existe un moyen quelconque de régler ce problème, (vider la mémoire à la fin du traitement de chaque ligne ? faire des pauses ? découper les fichiers ?).
Merci de votre aide,
Modesar

Posté : 22 juin 2008, 12:51
par katagoto
Moi je viens de réaliser un script particulièrement lourd (50 regex environs) et il y a un premier moyen : l'éxécuter en local, et si c'est encore trop lourd le diviser en une dizaine de partie...

Posté : 22 juin 2008, 14:23
par Modesar
Merci katagoto, mais cette solution ne peut convenir dans mon cas, puisque le script n'est constitué que d'une seule boucle.
Je pense que c'est plutôt le fichier log qui devrait être coupé, mais comment ?
Quant à l'exécution en local, c'est ce que je fais actuellement, mais je pourrais pas le faire indéfiniment puisqu'il y a un log à envoyer par jour, qu'il faut copier la base de donnée, etc...

Posté : 22 juin 2008, 14:47
par katagoto
Je serais toi, je regarderais à partir de combient d'octets PHP bug, je compterais ce nombre d'octets, je prendrais la ligne du dessus jusqu'au début du fichier que je prend pour premier fichier etc.

Exemple

Code : Tout sélectionner

1. 30 o 2. 100 o 3. 75 // PHP bug à 150oi on ne prend que les lignes 1 et 2
Je sais pas si tu vois ce que je veux dire :oops:

Posté : 22 juin 2008, 15:33
par Calimero
Si tu es chez un hébergeur mutualisé, la solution d'augmenter la mémoire allouée à PHP ne s'appliquera pas à ton cas.

Il ne te reste que deux options : optimiser le script pour éviter de lui faire consommer trop de mémoire, et/ou fractionner son travail en petites unités.

Dans les deux cas, ça aiderait beaucoup d'avoir le code en question pour te conseiller.

Un point important soulevé par katagoto (si je l'ai bien compris) est de pouvoir quantifier la limite sur laquelle tu butes. Il faut pour cela que tu arrives à faire parler ton script pour savoir quand il s'arrête de fonctionner (par des echo, ou au pire, des file_put_contents() )

Sinon, il y a une solution paresseuse : tu peux aussi envisager de passer sur un hébergement dédié :wink:

Posté : 22 juin 2008, 18:04
par Modesar
J'ai réalisé de nouveaux tests et apparemment, le problème de mémoire est précédé d'un problème de vitesse :
Fatal error: Maximum execution time of 30 seconds exceeded in C:\wamp\www\ladder\filtre.php on line 95
Le serveur wamp ayant le même php.ini que le serveur de l'hébergeur. Quant à changer d'hébergeur, c'est déjà le 5ème, et celui-ci semble être mieux (taille d'upload plus grande).
Le problème semble n'avoir qu'une seule solution :
découper le fichier log en petites parties et exécuter le script pour chaque partie. La structure du log permet celà, mais il faut que la coupure se fasse en fin de ligne.
Y a-t-il donc une solution permettant de découper un fichier en 2 par exemple au bout de la 100e ligne ?
Merci de vos réponses pertinentes.

Posté : 22 juin 2008, 18:09
par Calimero
Pour la vitesse par contre tu peux y faire quelquechose :) regarde du côté de la fonction set_time_limit(), elle fait des merveilles :D

Posté : 22 juin 2008, 22:07
par Sékiltoyai
Une fois que c'est fait, utilise la fonction fgets() pour lire ligne par ligne ton fichier de log…

Posté : 23 juin 2008, 10:20
par Modesar
:cry: Le safe mode est activé, donc set_time_limit() ne fonctionnerait pas.
Voici la structure du code :
<?php
if ($tableau = file($_FILES['monfichier']['tmp_name']))
{ // ouverture du fichier, dans un tableau
   while(list(,$val)=each($tableau))
   { // envoie chaque ligne
   $val = mysql_real_escape_string(htmlspecialchars(str_replace("\\", "/", $val)));
   // (...) plusieurs conditions pour filtrer les données etc...
   } // fin de la recherche fichier
} // fin ouverture fichier
?>
La seule chose que je peux faire, c'est soit relancer le script pour chaque filtre, mais çà ne changerait rien car c'est au niveau du nombre de lignes que çà plante. Donc je crois que je vais effacer les lignes au fur et à mesure du filtrage et recommencer dès qu'on a atteint un nombre de ligne trop important. Vous pensez que c'est une bonne technique ?

Posté : 23 juin 2008, 10:49
par mcorgnet
Tu peux aussi t'arranger pour qu'un premier script découpe le fichier en sous fichiers, puis ensuite les analyser un par un ...