Bash: tableaux en fichier

Soyez le premier à donner votre avis sur cette source.

Snippet vu 6 035 fois - Téléchargée 17 fois

Contenu du snippet

Peut etre vous etes vous deja retrouvé dans la situation ou vous devez enregistrer dans un tableaux plusieurs milliers d'entrées.
Le problème pour moi c'est posé, j'ai donc décidé de mette ce tableau dans un fichier.
Autant prévenir de suite, cette solution offre le désavantage d'etre très lent, mais d'un autre coté, elle préserve les ressources mémoire allouées a php, ce que je désirai.
De plus, j'ai prévu un switch entre gestion par fichier et gestion en mémoire, au cas ou ;)
Prérequis:
Il faut impérativement accés a une commande grep, en effet, cette classe lors de la lecture du tableau vient 'greper' le fichier pour trouver la ligne qui l'interresse.

Le concept:
En instanciant la class ArrayFile, on créé un fichier dans le répertoire temporaire de votre choix. Le stockage d'une variable dans ce tableau se fait par la methode add. Cette methode ecrit dans le fichier une ligne représentant l'index/key du tableau, et sa variable sérializée.
La lecture se fait par la methode get tout simplement.
Ex:
//note: le nom du tableau n'est pas obligatoire, mais il peut s'avérer interressant de retrouver le fichier que l'on a creer

$monBeauTableau = new ArrayFile('monTableau');
//ici pas besoin d'index, on incrémente automatiquement
$monBeauTableau->add('ma premiere valeur');

//ici on force l'index (15)
$monBeauTableau->add('ma seconde valeur avec un index définit',15);

//valeur index par une clé type string (cleTrois)
$monBeauTableau->add('ma troisième valeur avec clé','cleTrois');

Un accés directe a une valeur pourra etre possible via l'instruction 'get':
echo $monBeauTableau->get('cleTrois');
// resultat : ma troisième valeur avec clé

echo $monBeauTableau->get(15);
// resultat : 'ma seconde valeur avec un index définit'

Enfin, pour lister la totalité d'un tableau un simple foreachLine:
while(list($key,$value) = $monBeauTableau->foreachLine()){
echo "key = $key ";
print_r($value)."\n";
}

//unset du tableau
$monBeauTableau->unsetArray();

Un cas particulier:
si plusieurs add sont fait sur la meme clé, le get de cette clé renverra toutes les valeurs de cette clé.
Pour retourner, la dernière valeur, il faut utiliser la methode 'getUniq' au lieu de 'get'.

Source / Exemple :


<?
class ArrayFile{
	var $dirTmp = '/var/tmp/';
	var $handleW = null;
	var $handleO = null;
	var $index = null;
	var $separator = '##';
	
	
	/*
		permet de switcher entre le mode fichier (très lent mais peu gourmand) 
		et mémoire (rapide mais très gourmand)

  • /
var $typeOfStorage = 'file';//[file|mem] var $aData = null; /**
  • Constructor
  • $param: arrayName
  • $param: dirTmp
  • $param: typeOfStorage
    • /
function ArrayFile($arrayName='',$dirTmp='',$typeOfStorage = 'file'){ $this->typeOfStorage = $typeOfStorage; if($this->typeOfStorage == 'file'){ if(!$arrayName) $arrayName = uniqid(rand()); if($dirTmp!='' && is_dir($dirTmp)) $this->dirTmp = $dirTmp; if(!is_dir($this->dirTmp.'arrayFile')) mkdir($this->dirTmp.'arrayFile'); $this->dirTmp .='arrayFile/'; $this->arrayName = date('Ymd_his').'_'.$arrayName; if(file_exists($this->dirTmp.$this->arrayName)) $this->rmFile(); $this->handleW = fopen($this->dirTmp.$this->arrayName,'a'); $this->handleO = fopen($this->dirTmp.$this->arrayName,'r'); } } /** * *
    • /
function rmFile(){ exec("rm ".$this->dirTmp.$this->arrayName); } /**
  • Empilage de $varMixed par index
* *
    • /
function add($varMixed,$index=''){ if(!$index){ if(!$this->index) $this->index = 0; $mindex = $this->index; }else{ $mindex = $index; } if($this->typeOfStorage == 'file'){ fwrite($this->handleW,$this->separator.$mindex.$this->separator.serialize($varMixed)."\n"); }else{ $this->aData[$mindex][] = $varMixed; } if(!$index) $this->index++; } /**
  • Retourne toutes les occurences $index
*
    • /
function get($index){ if($index=='') return false; if($this->typeOfStorage == 'file'){ $result = shell_exec("grep '".$this->separator.$index.$this->separator."' ".$this->dirTmp.$this->arrayName." 2>&1"); $result = explode("\n",trim($result)); //si vide if($result[0]=='' && count($result)==1) return false; if(!is_array($result)) return false; foreach($result as $line){ $aTmp = explode($this->separator,trim($line)); $aArray[] = unserialize($aTmp[2]); } }else{ $aArray = $this->aData[$index]; } return $aArray; } /**
  • Ne retourne que le dernier élément ajouté pour index $index
*
    • /
function getUniq($index){ if($index=='') return false; $aResult = $this->get($index); if(!is_array($aResult)) return false; return array_pop($aResult); } /***
  • while(list($key,$value) = $aAlbum->foreachLine()){
echo "key = $key "; print_r($value)."\n"; } *
    • /
function foreachLine(){ if($this->typeOfStorage == 'file'){ if(!feof($this->handleO)){ $line = fgets($this->handleO, 4096); $aTmp = explode($this->separator,trim($line)); if($aTmp[1]!=''){ return array($aTmp[1],unserialize($aTmp[2])); }else{ return $this->foreachLine(); } }else{ fseek($this->handleO, 0); } }else{ list($k,$d) = each($this->aData); if($d!='') return array($k,$d); reset($this->aData); return false; } return false; } /** * *
    • /
function unsetArray(){ if($this->typeOfStorage == 'file'){ fclose($this->handleW); fclose($this->handleO); $this->rmFile(); }else{ unset($this->aData); } } } ?>

Conclusion :


Si vous n'avez pas peur de ralentir votre script, et si la mise en tableau demande beaucoup de ressource mémoire, alors voila une solution. L'autre solution consiste a allouer plus de mémoire a php via la config.

A voir également

Ajouter un commentaire Commentaires
Messages postés
13
Date d'inscription
mercredi 30 janvier 2008
Statut
Membre
Dernière intervention
9 octobre 2008

Le fait de passer de php4 a php5 est un risque sur une appli existante, dont une société dépend, du coup, Coucou747 a raison. Toutefois, cette société se prive aussi d'avantage que pourrait lui aporter une nouvelle version, sans parler des devs qui se sentent de plus en plus a la rue....
Mais on en reparlera au bar si vous voulez;)
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
1
Je sais je connais le probl?me :p
Mais c'est pas magnifique de se prendre la t?te lors des migrations ??? :p
Serveur inaccessible, clients m?contants, prises de t?tes, c'est trop bien ! ;)
Messages postés
12303
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
38
codefalse, beaucoup d'entreprises disent : tant que ca marche, on garde...

sinon, dans ce cas precis, arrayacces serait plus approprie qu'un iterator...
Messages postés
13
Date d'inscription
mercredi 30 janvier 2008
Statut
Membre
Dernière intervention
9 octobre 2008

Je ne code que pour le boulot.
Tu veux que je te mette en relation avec mes admins ?;)
Vous aurez beau dire, je n'y peux malheureusement rien;) C'est une réalité, je code avec (meme si c'est parfois gavant).
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
1
On ne te demande pas d'utiliser un autre langage, juste d'avoir un serveur ? jour :p
Php4 c'est mort, php6 va bientot sortir, alors php5, c'est la moindre des choses. Sinon autant tourner sur du windows 95 pour coder :D
Afficher les 10 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.