[Class] Problème d'itérateurs

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : [Class] Problème d'itérateurs

par katagoto » 05 juil. 2008, 15:19

Merci sadeq, ça marche niquel :lol:

J'ai bien pensé que ça venait du fait que ça faisait next dès le début, mais je sne savais pas comment le résourde...

par sadeq » 05 juil. 2008, 14:51

Le problème est dans l'index de départ par rapport à la première lecture. Par défaut l'index est à 0 et l'itération fait systématiquement un next (index +1) avant de lire. C'est pourquoi ton tableau commence toujours par la deuxième case au lieu de la première.

Voici une adaptation que j'ai faite de ton code :
<?php
class Cache implements Iterator {
	//
	function Cache($fichier="cache.txt"){
		$this->fichier = $fichier;
	}
    // Variables pour les fonctions itératrices
    private $clef = array();// Les clefs

    private $valeur = array();// Les valeurs

    private $index = 0; // L'index
	
	private $fichier; // Fichier cache
	
//
    public function genere($contenu=null, $existe=true)
    {
        $existe=(bool) $existe;

        if (!$existe) {
            if(!empty($contenu)){
                $this->cache=$contenu;
            }
            else {
                die("Veuillez stipuler un contenu");
            }
        }
        else {
            if(!empty($contenu)){
                $this->cache=$contenu;
            }
            else {
                die("Veuillez stipuler un contenu");
            }
        }

        $this->test_tableau();

        // utilisation de serialize() pour transformer $content en chaine de caractères
        $contenu_serialize = serialize($this->cache);

        // échappement les caractères spéciaux pour pouvoir mettre le tout entre quotes dans le futur fichier
        $contenu_serialize = str_replace(array('"', "'"), array("\\\"", "\\'"), $contenu_serialize);

        // création du code php à stocker dans le fichier
        $contenu_serialize = "<?php \n" . "\$cache = unserialize(\"" .  $contenu_serialize . "\"); \n ?>";

        // écriture du code dans le fichier
        $resultat = file_put_contents($this->fichier, $contenu_serialize);

        // renvoie true si l'écriture du fichier a réussi
        return $resultat;
    }
//...
    private function test_tableau(){
        if(is_array($this->cache)){
            foreach ($this->cache as $clef => $valeur) {
                $this->clef[]=$clef;
                $this->valeur[]=$valeur;
            }
            return true;
        }
        return false;
    }
	
    // Les fonctions Itératrices (pour les boucles)
    public function current(){
        if ($this->valid()) return $this->valeur[$this->index]; else return null;
    }
    public function next(){
		$this->index++;
        if ($this->valid()) return true; else return false;
    }
	public function valid(){
		return ($this->index >= 0 && $this->index < count($this->clef));
	}
    public function previous(){
		$this->index--;
        if ($this->valid()) return true; else return false;
    }
    public function key(){
        if ($this->valid()) return $this->clef[$this->index];
    }
    public function rewind(){
        $this->index=0;
    }
}
//
$cache = new Cache();
$tableau1 = array("ligne 1", "ligne 2", "ligne 3", "ligne 4", "ligne 5");
$cache->genere($tableau1, false);
//
echo "<p><p><p>Test 1 :</p>";
while ($cache->valid()) {
    echo "<p>".$cache->current()."</p>";
	$cache->next();
}
//
$tableau2 = array("clef 1" => "ligne 1", "clef 2" => "ligne 2", "clef 3" => "ligne 3", "clef 4" => "ligne 4", "clef 5" => "ligne 5");
$cache->genere($tableau2, false);
//
echo "<p><p><p>Test 2 :</p>";
while ($cache->valid()) {
    echo "<p>".$cache->current()."</p>";
	$cache->next();
} 
?> 

par katagoto » 05 juil. 2008, 14:19

Sur PHP5 avancé seconde édition y a écrit :
return (this->index +1 <= count($this->login)) ;
Donc moi, en adaptant un peut j'arrive à ça :
return ($this->index +1 <= count($this->valeur));
Mais, même en essayant
return ($this->index +1 <= count($this->valeur));
ou
return (($this->index +1) <= count($this->valeur));
ou avec clefs, j'ai ce message d'erreur :
Fatal error: Maximum execution time of 30 seconds exceeded in D:\wamp\www\test\test_kache.php on line 19
Avec ligne 1 répété des 100aine de fois

Or, ce n'est que ça :
<?php
foreach ($cache as $valeur) {
	echo "<p>".$valeur."</p>";
}//l.19

par Sékiltoyai » 05 juil. 2008, 13:34

C'est sur next que tu dois fait l'incrémentation, pas sur valid amha.

[Class] Problème d'itérateurs

par katagoto » 05 juil. 2008, 12:00

Bonjours à toutes et tous,

Je vais faire deux topic, car j'ai deux problèmes pour une class, pour tenté de respecter la règle du forum...
Voilà, j'ai une class de gestion de cache qui à pour parent Itertor, seulement, voilà mon proble, il saute systèmatiquement le premier couple clef/valeur, exemple :

Si je fais ça :
<?php
include("Kache.php");
$cache=new Kache("test");
$tableau=array("ligne 1", "ligne 2", "ligne 3", "ligne 4", "ligne 5");
$cache->genere($tableau, false);

echo "<p><p><p>Test 2 :</p>";
foreach ($cache as $valeur) {
	echo "<p>".$valeur."</p>";
}
Ca m'affiche :
Test 2 :
ligne 2
ligne 3
ligne 4
ligne 5
Et si je fais :
$cache->detruit(true);
$tableau2=array("clef 1" => "ligne 1", "clef 2" => "ligne 2", "clef 3" => "ligne 3", "clef 4" => "ligne 4", "clef 5" => "ligne 5");
$cache->genere($tableau, false);
echo "<p><p><p>Test 3 :</p>";
foreach ($cache as $clef => $valeur) {
	echo "<p><b>[".$clef."]</b> - ".$valeur."</p>";
}
J'ai ça :
[1] - ligne 2
[2] - ligne 3
[3] - ligne 4
[4] - ligne 5
Voilà un bout de ma class :
<?php
class Kache implements Iterator {
//...
	// Variables pour les fonctions itératrices
	private $clef=array();// Les clefs

	private $valeur=array();// Les valeurs

	private $index=0; // L'index
//...
	public function genere($contenu=NULL, $existe=true)
	{
		$existe=(bool) $existe;

		if (!$existe) {
			if(!empty($contenu)){
				$this->cache=$contenu;
			}
			else {
				die("Veuillez stipuler un contenu");
			}
		}
		else {
			if(!empty($contenu)){
				$this->cache=$contenu;
			}
			else {
				die("Veuillez stipuler un contenu");
			}
		}

		$this->test_tableau();

		// utilisation de serialize() pour transformer $content en chaine de caractères
		$contenu_serialize = serialize($this->cache);

		// échappement les caractères spéciaux pour pouvoir mettre le tout entre quotes dans le futur fichier
		$contenu_serialize = str_replace(array('', "'", "0"), array('\\', '\'', '0'), $contenu_serialize);

		// création du code php à stocker dans le fichier
		$contenu_serialize = "<?php" . "\n" . '$cache = unserialize("' .  $contenu_serialize . '");' . "\n" . '?>';

		// écriture du code dans le fichier
		$fichier = fopen($this->chemin_cache.$this->nom.$this->extention, 'w');
		$resultat = fwrite($fichier, $contenu_serialize);
		fclose($fichier);

		// renvoie true si l'écriture du fichier a réussi
		return $resultat;
	}
//...
	private function test_tableau(){
		if(is_array($this->cache)){
			foreach ($this->cache as $clef => $valeur) {
				$this->clef[]=$clef;
				$this->valeur[]=$valeur;
			}
			return true;
		}
		return false;
	}

	// Les fonctions Itératrices (pour les boucles)
	public function current(){
		return $this->valeur[$this->index];
	}

	public function next(){
		$this->index+1;
	}

	public function valid(){
		return ($this->index++ < (count($this->clef)-1));
                                // si je fais return ($this->index++ <= count($this->clef));
                                // J'ai deux ligne de trop au test 3 du tyle [0] - 
	}

	public function key(){
		return $this->clef[$this->index];
	}

	public function rewind(){
		$this->index=0;
	}

}

?>
Voilà, mes tapleaux sont bon pourtant...

Par avance merci de votre aide...