Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

BASH: TABLEAUX EN FICHIER


Information sur la source

Catégorie :Astuces Classé sous : bash, tableaux, fichier, mémoire Niveau : Débutant Date de création : 02/06/2008 Date de mise à jour : 02/06/2008 17:39:19 Vu : 2 651

Note :
Aucune note

Commentaire sur cette source (10)
Ajouter un commentaire et/ou une note

Description

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

  • <?
  • 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);
  • }
  • }
  • }
  • ?>
<?
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.
 

Historique

02 juin 2008 17:38:00 :
couleur code
02 juin 2008 17:39:19 :
couleur..;(grrr)

Commentaires et avis

signaler à un administrateur
Commentaire de coucou747 le 02/06/2008 19:15:12

$result = shell_exec("grep '".$this->separator.$index.$this->separator."' ".$this->dirTmp.$this->arrayName." 2>&1");
ouch.... c'est assez porc comme methode... utiliser mysql ou autre aurait ete une meilleur solution...
bref.... ou a la limite, faire un fichier temporaire ./Array/nom_du_tableau/clef qui contiendrait le contenu.

proposition d'amelioration :
tu devrais passer a php5, et utiliser la classe ArrayAccess, histoire de pouvoir faire tout ca de facon transparente.

sinon, qu'arrive t'il dans le cas d'un tableau bidimentionnel ?

signaler à un administrateur
Commentaire de codefalse le 02/06/2008 19:40:12 administrateur CS

et je rajouterai que l'usage de la spl serait ici un plus non n?gligeable ! :)

signaler à un administrateur
Commentaire de coucou747 le 02/06/2008 20:35:05

ArrayAccess c'est dans la SPL...

signaler à un administrateur
Commentaire de codefalse le 02/06/2008 21:38:20 administrateur CS

En fait je me suis mal exprim?, mais je voulais surtout parler des Iterator et compagnie, s'il n'utilise pas ArrayAccess, ce sera mieux. Apr?s en effet ArrayAccess est dans la SPL.

signaler à un administrateur
Commentaire de gentilKiki le 02/06/2008 23:29:27

Salut,
Oui bien sur, je pourrai utiliser tout un tas de choses bien plus pratiques tel que php5, mysql et porquoi pas, un autre langage. Mais voila, je ne dispose pas a ma guise d'une base de données, ni de l'administration du serveur. J'oublie souvent que les devs d'autres boites ont plus de droits que moi.
J'aurai du le mettre en préambule;)
Maintnenant, je reconnais que la solution du grep est plus que bourrine, mais n'ayant pas grand chose a dispo, je la trouve 'adaptée'.

signaler à un administrateur
Commentaire de codefalse le 02/06/2008 23:39:35 administrateur CS

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

signaler à un administrateur
Commentaire de gentilKiki le 02/06/2008 23:54:40

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).

signaler à un administrateur
Commentaire de coucou747 le 02/06/2008 23:54:46

codefalse, beaucoup d'entreprises disent : tant que ca marche, on garde...

sinon, dans ce cas precis, arrayacces serait plus approprie qu'un iterator...

signaler à un administrateur
Commentaire de codefalse le 02/06/2008 23:58:57 administrateur CS

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 ! ;)

signaler à un administrateur
Commentaire de gentilKiki le 03/06/2008 00:02:01

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;)

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Comment vérifier un lien ? [ par MaTHieU ] Salut, Je voudrais savoir comment vérifier un lien... Par exemple : http://www.monsite.fr/fichier.zip Si le fichier est présent ça marque "OK" Si le l Upload de fichier [ par clovis ] Salut,je voudrais simplement savoir comment faire pour uploader un fichier de mon disque sur le serveur en PHP.Thanks téléchargement de fichier .TXT ou .DOC ou ... [ par julien ] je voudrais permettre le téléchargement sur les postes clients de fichiers .txt ou .doc. pour l'instant quand on clique sur les liens, ils s'ouvrent d AU SECOURS !!! ZIP ZIP [ par omnikod ] Voilà mon pb :je voudrais que le script php lise à un certain moment (kan la base dépasse une certaine taille par exemple) les enregistrement d'une t form->php->html [ par BigZoo ] voilà mon pb:j'ai un fichier html en destination avec une structure bien définie et je veux, à partir d'un formulaire dans lequel je mets du texte, de Editer un fichier texte dans une zone de saisie [ par la_glisse ] Bonjour,je suis débutant et je cherche comment éditer un fichier texte dans une zone de saisie comme celle ou nous écrinons tous pour laisser nos mess Fichier [ par koko ] J'aimerais pouvoir ouvrir et écrire dans un fichier texte. Mais c'est pas du bete texte a écrire. 1. Quand j'écris quelques choses, le texte doit se Lecture de fichier [ par koko ] Je voudrais lire un fichier fichier.txt dans la page index.phpvoici ma fonction&lt;? echo "Texte: ". $fp = fopen("fichier.txt","r"); $donnees = fgets créer un fichier ???? petit PB [ par MangaII ] Hello les gars !Voilà, j'ai un petit soucis, j'ai besoin de créer des fichiers (TXT) sur mon site, depuis ma page en PHP ! le PB, c que je pe pas ! Je Formulaire + fichier externe [ par koko ] J'ai un petit formulaire avec 2 text (&lt;INPUT TYPE="text") et un button. Quand je clique sur le button, il doit mettre les 2 text dans un fichier ex


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,640 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.