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

PHP & Base de données Discussion :

[Doctrine] Sérialisation Doctrine_record et identifiant


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 19
    Par défaut [Doctrine] Sérialisation Doctrine_record et identifiant
    Bonjour,

    Je travaille à un projet avec Zend Framework et Doctrine 1.x.

    Je rencontre un problème dans la sérialisation de mes objets Doctrine_Record.
    Pour faire simple, j'ai comme objet central un ouvrage (Publications_Model_Book) auquel je rattache différents objets de classement et notamment un éditeur et des collections.

    Mon formulaire de création est multi-étapes ce qui signifie que je dois placer en session les différents objets Doctrine_Record créés lors de ces étapes. Pour placer ces objets en session je les transforme en tableau avec la méthode toArray(true) et je les recréé avec la méthode fromArray.

    Il se trouve que cela fonctionne parfaitement pour la plupart des champs sauf les identifiants qui semblent perdus entre chaque session.

    Avez-vous une idée comment gérer les identifiants lors de la sérialisation ?


    Merci beaucoup par avance,

    Frédéric

  2. #2
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Je n'ai jamais fais, ni eu le besoin de faire.

    Par contre, doctrine embarque le paterne de sérialize. Je pense que tu aurais plutôt intérêt a sérialiser plutôt que d'envoyer vers un array().
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $string = serialize($record);
    $record = unserialize($string);
    Par contre je ne vois pas bien comment tu veux gérer tes identifiants. A priori ton problème vient que tu veux "sauvegarder" temporairement un enregistrement maître (qui n'existe que virtuellement) et les enregistrements enfants qui lui sont liés sur l'identifiant (Id en général). Sauf que si tu utilises les fonctions de base de Doctrine, l'Id en question n'est pas créé par Doctrine mais par la base de donnée. Il n'est envoyé à doctrine qu'après la première sauvegarde. Hors tu ne veux pas sauvegarder...

    Je pense que tu as intérêt à procéder en plusieurs étapes distincte création du record de base, des records lié mais sans le lien. Sauvegarde du principal. Attachement du principal à ces enfants et sauvegarde des enfants.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 19
    Par défaut Re:
    Bonjour,

    tu as bien compris ce que je veux faire. Le problème est que ce formulaire est utilisé à la fois pour la création d'un nouvel ouvrage et pour l'édition d'un ouvrage existant.

    En fait les identifiants sont parfois déjà créés (les objets existent déjà en base de données), comme par exemple quand je veux lier un éditeur déjà créé à un ouvrage.

    Le principe des identifiants fonctionne bien dans mon appli il me semble, les problèmes arrivant après "sérialisation".

    Je pense que tu as raison sur la méthode de sérialisation. Avec toArray/fromArray Doctrine considère que l'on veut transférer des données d'un objet à un autre ; c'est lorsque l'on sérialise réellement que l'objet complet peut-être recréé.

    J'ai utilisé toArray/fromArray après la lecture d'un article de blog évoquant le fait que la sérialisation d'un objet Doctrine_Record pouvait être une sérieuse pénalité pour les sessions (en terme de performance et de mémoire consommée), dans la mesure où la sérialisation conserve les différentes informations sur les états des objets.

    Merci de ton aide en tout cas !

    Frédéric

  4. #4
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Si tu travailles en MCV tu peux avoir un même formulaire mais des traitements différent suivant que tu es en création ou en édition. Personnellement je travail avec symfony et c'est quelque chose que j'ai déjà implémenté régulièrement.

    Je pense (mais il faudrait analyser plus près le code (le tiens et celui de Doctrine) ) que c'est lors de la unserial() que l'absence de Id réel apparait.

    Il reste la possibilité de ne pas déléguer à la base de donnée le soins de créer l'Id de l'objet et de le faire directement. De l'attribuer dés la première création bien avant la première sauvegarde, quitte à perdre quelques numéro.

    Regarde aussi du côté de Doctrine 2 qui est sorti il y a peu. Il est possible qu'il gère mieux ce type de problème et, accessoirement, les performances sont largement dopées et le système beaucoup plus souple. Ça vaut la peine de s'y pencher. Seul bémol, la documentation périphérique qui manque encore largement.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 19
    Par défaut Re:
    Je commence à utiliser les fonctions serialize/unserialize sur mes modèles.

    Il y a un truc énervant c'est que les références ne sont pas sérialisées récursivement.

    J'ai bien trouvé la méthode serializeReferences(bool) et je l'utilise sur mon modèle Book pour les objets liés.

    Mais par contre cette sérialisation ne se fait pas en profondeur. D'après le code de la méthode Doctrine_record::serialize il faut paramêtrer cela pour chaque objet lié.

    Par exemple : dans mon modèle objet, un livre est lié à un Identifier qui est lui-même lié à un IdentifierType (ISBN13, ISBN10, EAN13) ; ex. :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Book->Identifier->identifierType
    Du coup mon Identifiertype n'apparaît pas à la désérailisation.

    J'ai trouvé comme moyen temporaire de modifier le constructeur de mes modèles pour inclure l'appel à la méthode serializeReferences.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     
    //Exemple pour l'identifier :
     
    class Publications_Model_Identifier extends Publications_Model_Base_Identifier
    {
     
    	public function __construct($table = null, $isNewEntry = true)
    	{
    		parent::__construct($table, $isNewEntry);
    		$this->serializeReferences(true);
    	}
    }
    Qu'en penses-tu ?


    Merci encore

  6. #6
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Je pense que tu serais beaucoup plus à l'aise avec Doctrine 2.

    En effet, il conserve nativement les enregistrements entre les sessions avant de les enregistrer.

    Donc tu fais tes modifications, tu récupères ton enregistrement d'une session à une autre, et tu enregistres quant tu as terminé. Du moins en théorie, en pratique, je n'ai pas encore testé.


    Je pense que, sur Doctrine 1, la sérialisation est orienté mono enregistrement (ou valable pour une collection et encore) et que vouloir modifier comme tu le fais me semble un sac à bug à moyenne échéance. Une des raisons de la création de Doctrine 2 était l'impossibilité de conserver des lots d'enregistrements entre deux appels d'une même session. Et les équipes de Doctrine on considéré que ce n'était pas faisable dans la version 1. M'est avis que tu vas plus loin que ce que sait faire le produit.

    La seul fois où j'ai eu à faire ce type de manipulation, ma solution a été de créer en base avec un flag sur le principale et de purger régulièrement la base des créations non terminées. Brutal mais efficace.

Discussions similaires

  1. [Doctrine] Colonne identifiant automatique
    Par caradhras dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 09/07/2009, 12h10
  2. Sérialisation avec sockets
    Par sebi77 dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 03/05/2004, 20h24
  3. identifiant commencant par 1
    Par claudyyyyy dans le forum Langage SQL
    Réponses: 6
    Dernier message: 28/04/2004, 14h16
  4. enregistrer une image et un identifiant
    Par dosach dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 18/03/2004, 17h18
  5. SGBD ou sérialisation
    Par tiboleo dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 07/10/2003, 16h18

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