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 :

stockage objet session avec attribut private : KO [Fait]


Sujet :

Langage PHP

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    306
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 306
    Points : 194
    Points
    194
    Par défaut stockage objet session avec attribut private : KO
    Bonjour,

    Je mets ce post dans la rubrique SESSION mais je pense aussi que j'aurai pu le mettre dans Accès Database.

    Je vous explique :

    J'utilise une base SQL Server pour stocker mes variables de session. J'ai donc redéfini le set_session_handler avec mes propres fonctions d'accès au serveur SQL (2005 pour info).

    Tout se passe correctement : stockage de chaines, d'entiers, d'objets.... à l'exception des objets avec des attributs private!!!!! Et oui, c'est fou! Si mon objet a le malheur d'avoir un attribut private, le stockage dans la database crash!!

    J'ai donc regardé de plus près en affichant l'objet sérialisé avec qu'il ne soit inséré en base :

    Voici mon objet tout bête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Class Maison	{
     
    	public $type;
     
    	public $name;
     
    	public $value;
    }
    Le stockage de cet objet ne pose pas de pb.
    Sa sérialisation donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    O:6:"Maison":3:{s:4:"type";N;s:4:"name";N;s:5:"value";N;}
    Maintenant si on met l'attribut type en private :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Class Maison	{
     
    	private $type;
     
    	public $name;
     
    	public $value;
    }
    Le stockage de cet objet crash avec le message suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Eric_Handler_Session (Maileva_Handler_Session::write) : SQLSTATE[HY000]: General error: 20018 Incorrect syntax near 'session_maison|O:6:"Maison":3:{s:12:"'. [20018] (severity 5) [(null)]
    Sa sérialisation donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    O:6:"Maison":3:{s:12:"Maisontype";N;s:4:"name";N;s:5:"value";N;}
    J'ai trouvé bizarre le nombre de caractères dans la dernière sérialisation, le comptage du nombre de caractères n'est pas correct pour le type. En effet, il en compte 12 (s:12), alors que MaisonType ne fait que 10 caractères.

    Je me suis donc amusé à supprimer les éventuels caractères spéciaux que je ne voyais pas à l'oeil nu et je me suis rendu compte qu'il avait ajouté avant et après Maison le caractère ASCII Nul (0*00 ou \0 en php);

    Le probème est que je peux pas faire un str_replace de ce caractère car lors de la désirialisation, il va m'negueuler en me disant que ce n'est pas le bon nombre de caractères (12 attendu au lieu de 10).

    Donc 2 solutions :
    - je passe tous mes attributs en public ce qui est pas top en termes d'encapsulation objet
    - ou avez-vous une solution ?

    Merci d'avance pour ceux qui se pencheront sur ce problème non trivial!

  2. #2
    Membre du Club
    Profil pro
    Développeur Web
    Inscrit en
    Avril 2006
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2006
    Messages : 37
    Points : 43
    Points
    43
    Par défaut
    utiliser __sleep() sur ta classe ?

    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
    Class Maison {
     
      private $type, $name, $value;
     
      public function __construct($type, $name; $value) {
     
        $this->type = $type;
        $this->name = $name;
        $this->value = $value;
     
      }
     
      public function __sleep() {
     
        return array('type', 'name', 'value');
     
      }
     
    }

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    306
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 306
    Points : 194
    Points
    194
    Par défaut
    Hello Méthylbro,

    Sympa de me répondre.

    J'ai testé ta solution mais ça ne marche pas mieux.

    D'après ce que j'ai pu comprendre dans la doc, __sleep précise les membres de la classe qui doivent être sérialisés et non la manière dont ils doivent l'être.

    Je crois que c'est mort car j'ai vu dans la doc PHP que mon problème était connu : http://fr.php.net/serialize#60834

    J'ai déjà commencé à mettre tous membres de mes classes en public.

    Merci encore.

  4. #4
    Membre du Club
    Profil pro
    Développeur Web
    Inscrit en
    Avril 2006
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2006
    Messages : 37
    Points : 43
    Points
    43
    Par défaut
    hum ...

    et tu as pensé à te créer toi même une méthode serialize() retournant une chaine de caractères comme le ferais la fonction classique ?

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    306
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 306
    Points : 194
    Points
    194
    Par défaut
    Hello,

    Ben, je ne sais pas si on peut redéfinir en PHP la foncrion serialize().

    J'ai trouvé une autre solution moins crade que celle de passer les membres en public :
    Il faut modifier les functions write et read du set_session_handler afin de remplacer les \0 par une chaine quelconque lors de l'écrtiture en base et de faire l'inverse pour la lecture.

    Ainsi les fonctions read et write du set_session_handler doivent contenir :

    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
     
    define('DELIMITEUR_MEMBRES_PRIVES','privateMembre');
     
     function write($id, $data)
     {
        $data = str_replace(chr(0),DELIMITEUR_MEMBRES_PRIVES,$data);
        .... écriture en base...
     }
     
     function read($id)
     {   
       .... lecture en base ...
       $result = str_replace(self::DELIMITEUR_MEMBRES_PRIVES,chr(0),$result);
       return $result;
     }

Discussions similaires

  1. Objet Session avec plusieurs adresses IP
    Par Aquellito dans le forum ASP
    Réponses: 3
    Dernier message: 31/01/2012, 20h00
  2. Objet en session avec serialize()
    Par numerodix dans le forum Langage
    Réponses: 6
    Dernier message: 13/09/2009, 23h35
  3. Réponses: 10
    Dernier message: 22/09/2008, 10h23
  4. Réponses: 3
    Dernier message: 04/05/2007, 09h08
  5. Problème avec l'Objet "Session"
    Par ghislain007 dans le forum ASP
    Réponses: 4
    Dernier message: 03/03/2006, 22h07

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