IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

[Sessions/objets] Sauvegarde d'objets: devient StdClass apres delinearisation


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de knoodrake
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    86
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2007
    Messages : 86
    Par défaut [Sessions/objets] Sauvegarde d'objets: devient StdClass apres delinearisation
    EDIT: Solution aux posts #4 (et #5)

    Bonjour a tous.

    J'ai un objet "$user->panier", que je serialize pour rentrer dans une variable de session. Probleme, lorsque je "unserialize" l'object, il devient un object de la StdClass et ne me sert donc plus a rien.
    Pourtant, la définition de la classe PANIER (celle de l'objet) est faite AVANT le session_start(), etc..

    Le petit soupson que j'ai: l'objet $user->panier est créé, comme vous pouvez le voir, DANS le constructeur de la classe USER. c'est dans cette même classe USER qu'elle est sérializée et unsérializée. Ca pourai venir de la ?

    Bon, bref, voici le code.

    La fameuse classe qui renit son objet (la méchante!):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    <?php
    class PANIER
    {
    	public $articles = array();
    	public $date_dodo = 0;
     
    	public function __get ($name) {
    		$value = null;
    		if ($name == "nombre_d_articles") {
    			$value = $this->nombre_d_articles();
    		} elseif ($name == "total") {
    			$value = $this->get_total();
    		} elseif ($name == "articles") {
    			$value = $this->articles;
    		} else {
    			if (!isset($this->articles[$name])) $value = 0;
    			else $value = $this->articles[$name];
    		}
    		return $value;
    	}
     
    	public function __set ($name,$value) {
    		$this->articles[$name] = $value;
    		return true;
    	}
    	public function remove ($name) {
    		unset($this->aricles[$name]);
    		return true;
    	}
     
    	public function nombre_d_articles () {
    		return array_sum($this->articles);
    	}
     
    	// retourne le prix total
    	public function get_total () {
    		$db = DB::getMe();
    		$total = 0;
    		foreach ($this->articles as $k => $v)
    			$total += PRODUIT::prix($k) * $v;
    		return $total;
    	}
     
    	public function __sleep () {
    		foreach ($this->articles as $k => $v)
    			if ($v <= 0) unset($this->articles[$k]);
    		$this->date_dodo = time();
    	}
    }
    ?>
    la classe USER au travers de laquelle la classe PANIER est manipulé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
     
     
    class USER
    {
    	private static $instance;
     
    	private function __construct ($login) {
    		$db = DB::getMe();
    		// a proteger !! //
    		$q = "SELECT * FROM `client` WHERE `login` = '$login'";
    		$r = $db->queryfetchobject($q);
     
    		$this->nom = $r->nom;
    		$this->prenom = $r->prenom;
    		$this->login = $r->login;
    		$this->password = $r->password;
    		$this->mail = $r->mail;
    		/* etc.. */
     
    		// restore le panier 
    		$this->panier = new PANIER ();
    		if (!empty($_SESSION['cart']))
    			$this->panier = unserialize($_SESSION['cart']);
    	}
     
    	public static function getMe ($login=null) {
    		if (!empty($login))
    			self::$instance = new USER ($login);
    		elseif (empty(self::$instance))
    			self::$instance = new USER ($_SESSION['login']);
    		return	self::$instance;
    	}
     
    	public function ajouter_au_panier($id,$qte) {
    		if (isset($this->panier->{"id".$id})) {
    			$this->panier->{"id".$id} += $qte;
    		} else 	$this->panier->{"id".$id}  = $qte;
     
    		$this->backup_panier();
    	}
     
    	public function enlever_du_panier($id,$qte) {
    		if (isset($this->panier->{"id".$id})) {
    			$this->panier->{"id".$id} -= $qte;
    			if ($this->panier->{"id".$id}<=0)
    				$this->panier->remove("id".$id);
    		}
    		$this->backup_panier();
    	}
     
    	private function backup_panier() {
    		if (!empty($this->panier)) {
    			$panier = serialize($this->panier);
    			$_SESSION['cart'] = $panier;
    		} else unset ($_SESSION['cart']);
    	}
     
    	public function __destruct () {
    		$this->backup_panier();
    	}
    }
     
    ?>
    et le lieu du crime:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    <?php
    require ("inc/panier.class.php");
    require ("inc/user.class.php");
    session_start();
    require ("include.php"); // le reste du programme.
     
    /* .. 
    	reste de la page 
    .. */
     
    $user = USER::getMe();
    echo "<pre>";print_r($_SESSION);echo"</pre>";
    /*
     *  Et cette ligne ci dessu, donne ( le drame !) :
     * [ ...blabla..] 
     * [cart] => O:8:"stdClass":1:{s:4:"id26";i:1;} <-- StdClass :'-(
     * [..blabla..]
     *
    */
    ?>

    Donc si quelqu'un pouvait m'aider, ou m'indiquer un piste de recherche, quelque chose..

    Merci par avance.

    Cordialement, Damien.

  2. #2
    Membre émérite
    Avatar de viviboss
    Profil pro
    Inscrit en
    Août 2006
    Messages
    943
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Gard (Languedoc Roussillon)

    Informations forums :
    Inscription : Août 2006
    Messages : 943
    Par défaut
    PHP est un langage de script, et s'interprete de haut en bas, et de gaucha à droite.

    Pourquoi ton session_start() est si bas ? Pourquoi ne le mets-tu pas au début ?

    Dans ta classe USER, tu utilises des variables de SESSION, sans qu'elles soient déclarer....

    Conseil : session_start au début, essaye....

    Je fais à peu près les même choses (même si je préfère sérializer et unserializer à l'extérieur des classes....), mais mes includes de classes je les faits juste après le session_start().

    PS : petite question : pourquoi ne pas, d'ailleur, faire hériter USER de PANIER ?

    Enfin, c'est juste une question omme ca....
    Veni Vidi Vici
    -------------------------
    Mes articles : developpez.com ou bien vbview.net
    -------------------------
    Et SURTOUT ne pas oublier la bible PHP : --> php_manual_fr.chm!!!
    Et aussi : --> pear_manual_fr.chm!!!

    Ou encore : --> Les tutoriaux & cours PHP de Développez.com
    -------------------------

  3. #3
    Membre éclairé Avatar de knoodrake
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    86
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2007
    Messages : 86
    Par défaut
    Merci pour cette réponse rapide (et désolé la mienne pas rapide.. fête de la musique oblige )


    PHP est un langage de script, et s'interprete de haut en bas, et de gaucha à droite.

    Pourquoi ton session_start() est si bas ? Pourquoi ne le mets-tu pas au début ?
    Parcque j'ai lu quelque part sur ce forum que la définition de la classe a délinéariser devait se faire avant le session_start().
    Quoi qu'il en soit, qu'il soit avant ou après ne change rien.

    Dans ta classe USER, tu utilises des variables de SESSION, sans qu'elles soient déclarer....
    Hein ? quoi que qui ?
    Mais la aussi, quoi qu'il en soit, les session ormis ce probleme de StdClass marchent très bien comme ça. on peu se logger, rester logger, etc.. et quand on ajoute un truc au panier, le truc est bien ajouté au panier, le panier reste etc.. sauf que le panier ne marche pas car il n'a plus de méthodes :-/
    M'enfin, pas de probleme du côté des sessions visiblement.
    PS : petite question : pourquoi ne pas, d'ailleur, faire hériter USER de PANIER ?
    J'y ai pensé. faudra que j'y re-pense (voir si ça m'apporte quelque chose).

  4. #4
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    6 152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 6 152
    Par défaut
    Citation Envoyé par knoodrake
    Parce que j'ai lu quelque part sur ce forum que la définition de la classe a délinéariser devait se faire avant le session_start().
    Quoi qu'il en soit, qu'il soit avant ou après ne change rien.
    Parce que vous faites vous-mêmes cette sérialisation (appel aux fonctions serialize et unserialize), ce que fais déjà PHP (du coup vos variables sont (dé)sérialisés deux fois en tout) et l'emplacement des déclarations ne doit jouer, dans votre code, que lors du unserialize, je suppose. Sérialisez-vous toutes vos données, quelles qu'elles soient ?

    Je serais intéressé par un dump complet de vos variables de session. Est-ce possible d'en avoir un ?

  5. #5
    Membre éclairé Avatar de knoodrake
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    86
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2007
    Messages : 86
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $user = USER::getMe();
    	echo "<pre>";var_dump($_SESSION);echo"</pre>";
    done : (enfin, une fois la méthode $user->ajoute_au_panier($id) executée au moins une fois)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    array(3) {
      ["sessionkey"]=>
      &string(32) "bd20ebd606f16f01fe45e7c733e00b49"
      ["login"]=>
      &string(6) "client"
      ["cart"]=>
      &string(34) "O:8:"stdClass":1:{s:4:"id26";i:1;}"
    }
    julp, ce que vous voulez dire, c'est que lorsque je fait $_SESSION['var']=$obj , $obj est automatiquement linéarisé par php, et idem pour la délinéarisation ?

    Edit: PS: j'ai la configuration par defaut de XAMPP Linux.

  6. #6
    Membre Expert
    Inscrit en
    Janvier 2005
    Messages
    2 291
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 291
    Par défaut
    Je vais peut-etre dire une betise ou tout mélanger, mais il me semblait qu'il fallait coder les méthodes __sleep() et __wake() pour les classes que l'on souhaiter pouvoir (dé)sérialiser dans les sessions, non?

  7. #7
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    6 152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 6 152
    Par défaut
    Citation Envoyé par knoodrake
    julp, ce que vous voulez dire, c'est que lorsque je fait $_SESSION['var']=$obj , $obj est automatiquement linéarisé par php, et idem pour la délinéarisation ?
    Bien sûr, comme toute variable. Vous ne sérialisez pas vos chaînes ou vos variables numériques lorsque vous les utiliser dans une session ? C'est la même chose, la seule restriction est celle que vous avez évoqué : la(les) déclaration(s) des classes doivent être faites avant session_start.

    D'autre part, votre méthode __sleep est erronée puisque PHP attend qu'on lui retourne un tableau : vous devriez avoir une erreur (de type notice).

    Quelle version de PHP utilisez-vous ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Architecture / Services] Graphe d'objets à sauvegarder
    Par mauvais_karma dans le forum Plateformes (Java EE, Jakarta EE, Spring) et Serveurs
    Réponses: 5
    Dernier message: 05/03/2006, 16h07
  2. [POO] sauvegarde d'objets et perte des methodes
    Par Matth_S dans le forum Langage
    Réponses: 3
    Dernier message: 23/12/2005, 15h47
  3. Réponses: 4
    Dernier message: 14/09/2005, 21h39
  4. sauvegarder un objet au format .x
    Par sylvain_bos dans le forum DirectX
    Réponses: 3
    Dernier message: 19/08/2004, 23h05
  5. [arbre] Sauvegarder un objet dans un fichier
    Par Guigui_ dans le forum Langage
    Réponses: 6
    Dernier message: 07/02/2003, 00h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo