Zend Framework

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 09-08-2010 21:01:43

nosferapti
Membre
Date d'inscription: 10-01-2010
Messages: 40

[Résolu] Doctrine, Zend_Entity ou Zend_Db

Bonjour,

Il était une fois un développeur (moi) qui découvrit Zend Framework. Je fus très content puisque les classes qui tournaient autour de Zend_Db me convenaient très bien.
Puis, j'entendis dire que la librairie Doctrine allait être intégrée dans ZF version 2. Je m'en réjouis donc, bien que ne l'ayant jamais utilisée, étant donné que j'en eus entendu le plus grand bien.

En ce beau jour d'hui, je me renseigne sur les changements à prévoir dans les développements de ces prochaines semaines et là les bras m'en tombent :

http://truffo.fr/2009/11/doctrine-2-0-integre-dans-le-zend-framework-2-0/ a écrit:

Le composant Zend_Db ne devrait pas être menacés, ils offrent des services qui sont un peu différent.

Donc je ne comprends pas : Doctrine ne remplace pas Zend_Db ?

Voilà ma question du point de vue théorique et voici, à la suite, la même question (à mon avis), du point de vue pratique : avec Zend_Db, j'aime bien l'utilisation du code suivant, par exemple, qui me simplifie mon code pour la recherche d'enregistrements :

Code:

$gestionPageavancee->select() // $gestionPageavancee est une instance de Zend_Db_Table_Abstract
->where('contenuPageavancee LIKE :recherche')
->bind(array(
    'recherche' => $recherche,
))

et donc ma question : l'arrivée de Doctrine me permettra-t-elle de "mieux" faire ça ? "mieux" pouvant être une réduction du nombre de lignes de code et / ou une réduction des ressources utilisées.

Dernière modification par nosferapti (11-08-2010 20:33:33)


GNAP !

Hors ligne

 

#2 09-08-2010 21:24:15

mikaelkael
Administrateur
Lieu: Donges
Date d'inscription: 18-06-2007
Messages: 1175
Site web

Re: [Résolu] Doctrine, Zend_Entity ou Zend_Db

Hello,

Zend_Entity n'existe plus (en tout cas il est bien rangé dans un coin). Son auteur Benjamin Eberlei a rejoint la team Doctrine pour la version 2.

Doctrine 2 est fractionné en 3 sous-parties : Common, DBAL et ORM. DBAL correspond à DataBase Abstraction Layer (sorte de surcouche à PDO). Contrairement à ce qui est indiqué il ne sera pas "inclus" dans Zend Framework mais son association sera facilitée (ressource d'application, fournisseur Zend\Tool...). Pour une idée plus précise, il y a par exemple http://github.com/beberlei/zf-doctrine

La proposal de Zend\Db en version 2 est présentée sur cette page : http://framework.zend.com/wiki/display/ … quirements

@+


Less code = less bugs
Contributeur ZF - ZCE - ZFCE - Doc ZF (CHM & PDF) - Vice-trésorier AFUP 2011
Ubuntu 11.04 - ZendServer

Hors ligne

 

#3 10-08-2010 19:40:03

nosferapti
Membre
Date d'inscription: 10-01-2010
Messages: 40

Re: [Résolu] Doctrine, Zend_Entity ou Zend_Db

mikaelkael a écrit:

Doctrine 2 est fractionné en 3 sous-parties : Common, DBAL et ORM. DBAL correspond à DataBase Abstraction Layer (sorte de surcouche à PDO).

j'ai du mal à voir les différences. dans mon exemple de code du 1er message, Zend_Db fait de l'ORM et de la DBA, c'est ça ?


GNAP !

Hors ligne

 

#4 10-08-2010 23:11:37

Delprog
Administrateur
Date d'inscription: 29-09-2008
Messages: 670

Re: [Résolu] Doctrine, Zend_Entity ou Zend_Db

Salut,

Le DBAL est une couche du framework qui permet de piloter la base de données. C'est cette couche qu'utilise l'ORM pour communiquer avec la bdd, et c'est grâce au DBAL qu'il peut utiliser le bon driver en fonction du type de SGBDR (ex. PDO_MYSQL).

Le DBAL permet aussi de manipuler facilement et directement la base de données, obtenir des informations sur les tables, etc. sans nécessiter la présence de l'ORM.

Avec le DBAL tu peux par exemple faire :

Code:

$alter = array(
    'add' => array(
        'mon_champ' => array(
            'type' => 'string',
            'length' => 150
            'notnull' => true,
            'default' => 'super'
        )            
    )         
);
$conn->export->alterTable('ma_table', $alter);

Mais tu peux aussi créer des bases, lister les tables, obtenir des informations sur les tables etc etc.
Nous l'utilisons en standalone surtout pour nos scripts de migrations et nos tâches automatiques de maintenance sur la bdd, c'est bien pratique.

L'ORM est une couche du framework par dessus le DBAL qui permet de faire du mapping, c'est à dire de traduire les types de données en entités et manipuler la base de données relationnelle comme si c'était une base objet. Il permet aussi l'utilisation du DQL, le langage de requête de Doctrine.

Très souvent, les programmeurs utilisent l'ORM alors qu'ils n'en ont pas besoin. La plupart du temps le DBAL est suffisant. Un bon article à lire : http://www.doctrine-project.org/blog/or … t-a-choice


A+ benjamin.


http://www.anonymation.com/ - anonymation - Studio de création.
http://code.anonymation.com/ - anonymation - blog - développement et architecture web

Hors ligne

 

#5 10-08-2010 23:27:51

nosferapti
Membre
Date d'inscription: 10-01-2010
Messages: 40

Re: [Résolu] Doctrine, Zend_Entity ou Zend_Db

Delprog a écrit:

Très souvent, les programmeurs utilisent l'ORM alors qu'ils n'en ont pas besoin. La plupart du temps le DBAL est suffisant. Un bon article à lire : http://www.doctrine-project.org/blog/or … t-a-choice

je n'ai pas tout compris dans cet article. j'ai plus l'habitude de lire des explications techniques en anglais donc là ce texte théorique sans exemple de code est assez obscur pour moi. est ce que tu aurais un exemple de code ?

Delprog a écrit:

L'ORM est une couche du framework par dessus le DBAL qui permet de faire du mapping, c'est à dire de traduire les types de données en entités et manipuler la base de données relationnelle comme si c'était une base objet. Il permet aussi l'utilisation du DQL, le langage de requête de Doctrine.

j'ai fait une recherche sur DQL et j'ai trouvé ça :
http://www.doctrine-project.org/documen … y-language

Code:

$q = Doctrine_Query::create()
    ->select('a.name')
    ->from('Account a');

donc ça revient au même qu'avec Zend_Db, non ?

P.S. : je crois que j'ai compris, l'ORM permet de faire ça ?

Code:

$account = new Account();
$account->name = 'test 1';
$account->amount = '100.00';
$account->save();

GNAP !

Hors ligne

 

#6 11-08-2010 11:31:04

Delprog
Administrateur
Date d'inscription: 29-09-2008
Messages: 670

Re: [Résolu] Doctrine, Zend_Entity ou Zend_Db

Salut,

Non, Zend_Db et Doctrine ne font pas du tout la même chose.

Le but d'un ORM est de mapper un modèle métier objet sur une base de données. C'est à dire qu'il doit permettre de mapper les objets métiers utilisés dans l'application et gérer leur persistance par "magie", sans que ces objets n'aient la moindre idée de l'existence d'une base de données.

Il est donc possible de faire :

Code:

$artist = new Artist('Françis l\'haleine');
$album = new Album('J\'ai pas d\'amis');
$artist->addAlbum($album);

$artistRepository->save($artist);

Dans ce cas là, je ne fais que manipuler mon métier et demander à un autre objet qui gère des collections d'objets métiers de faire persister mon objet, et je ne m'occupe pas du reste, Doctrine sait ce qu'il doit faire parce que j'ai mappé mes objets Artist et Album sur ma base de données (via mon fichier de config).

C'est ce que fait (et fera mieux en version 2) Doctrine. C'est très différent de Zend_Db, qui lui ne fait que simplement transformer des collections (tables) et des enregistrements (rows) en objets, ce qui permet de manipuler la base de données simplement mais en conservant un lien très fort entre les Zend_Db_Table/Zend_Db_Table_Row et la structure de ma base de données. Si je change le nom d'un champ dans une table, je dois adapter mon objet Row.

Attention donc, le DQL ne manipule pas des champs et des tables, mes des entités (mes objets métiers) et des propriétés et relations de ces objets.

L'article explique que beaucoup de développeurs n'aiment pas les modèles métiers objets et préfèrent manipuler directement des datasets, et que dans ce cas utiliser un ORM et générer des entités n'est pas utile, le DBAL est suffisant pour abstraire le moteur de base de données. Dans ce cas, Zend_Db est suffisant aussi.


A+ benjamin.

Dernière modification par Delprog (11-08-2010 18:58:24)


http://www.anonymation.com/ - anonymation - Studio de création.
http://code.anonymation.com/ - anonymation - blog - développement et architecture web

Hors ligne

 

#7 11-08-2010 19:06:29

nosferapti
Membre
Date d'inscription: 10-01-2010
Messages: 40

Re: [Résolu] Doctrine, Zend_Entity ou Zend_Db

Delprog a écrit:

Si je change le nom d'un champ dans une table, je dois adapter mon objet Row.

et qu'apporte Doctrine en plus pour gérer ça ?

Delprog a écrit:

Attention donc, le DQL ne manipule pas des champs et des tables, mes des entités (mes objets métiers) et des propriétés et relations de ces objets.

si les objets ont le nom des tables et les attributs ont le nom des colonnes de la table, là aussi il n'y a pas de grande différence, non ?

Delprog a écrit:

L'article explique que beaucoup de développeurs n'aiment pas les modèles métiers objets et préfèrent manipuler directement des datasets, et que dans ce cas utiliser un ORM et générer des entités n'est pas utile, le DBAL est suffisant pour abstraire le moteur de base de données. Dans ce cas, Zend_Db est suffisant aussi.

Zend_Db permet aussi de générer des entités si on crée des classes qui hérite de Zend_Db_Table_Row si j'ai bien compris. et au final il y a juste besoin de travailler avec les objets comme dans le code là :

Code:

$pageavancee = $gestionPageavancee->fetchRow( // $gestionPageavancee est une instance de Zend_Db_Table_Abstract
    $gestionPageavancee->select()
        ->where('contenuPageavancee LIKE :recherche')
        ->bind(array(
            'recherche' => $recherche,
        )
    )
);

$pageavancee->dateAffichage = time();
$pageavancee->save();

// ou avec une méthode de la classe GestionPageavancee : 

$pageavancee = $gestionPageavancee->recherche(array('recherche' => $recherche));
$pageavancee->dateAffichage = time();
$pageavancee->save();

GNAP !

Hors ligne

 

#8 11-08-2010 20:13:58

Delprog
Administrateur
Date d'inscription: 29-09-2008
Messages: 670

Re: [Résolu] Doctrine, Zend_Entity ou Zend_Db

et qu'apporte Doctrine en plus pour gérer ça ?

Zend_Db ne fait que transformer les noms des champs en propriétés objet. Avec Doctrine (ou autre ORM), tu fais du véritable mapping de champs sur la base de données, ta propriété objet peut très bien être "name" et le champ dans ta base "artist_first_name". Dans doctrine tu manipuleras l'objet métier sans te soucier de la persistance, si le nom de ton champ change, tu n'as qu'à changer le mapping et tu n'auras pas à ré-écrire le code partout où tu accèdes à la propriété.

Avec Zend_Db, si ton champs s'appelle "artist_first_name", la propriété de l'objet Row sera "artist_first_name", si tu changes ce champs dans la bdd, tu devras repasser partout dans le code où tu l'utilises. Ca veut donc dire que tes objets sont étroitement liés à la structure de base de données, alors que le modèle métier devrait être totalement ignorant de la persistance.


si les objets ont le nom des tables et les attributs ont le nom des colonnes de la table, là aussi il n'y a pas de grande différence, non ?

Si tu n'utilises pas les alias de doctrine et que tu le laisses générer simplement tes entités en fonction de la base, effectivement ça ne fait presque aucune différence, je dis presque parce que le DQL reste quand même différent. Par contre attention c'est valable que pour Doctrine 1, Doctrine 2 lui, permet au développeur de créer ses objets métiers indépendamment de toute persistance.

Admettons deux tables :
artists                albums
artist_id             album_id
artist_name       artist_id
                        album_name

Avec une relation one-to-many.

Imagine maintenant deux entités :
Model_Artist           Model_Album
id                          id
name                    artistId
                            name

Avec Doctrine tu map les propriétés de tes entités sur les champs de tes tables (tu fais des correspondances).


Pour récupérer que le nom de l'artiste avec que le nom de ses albums, avec Zend_Db tu feras :

Code:

$select = $artistTable->select()->setIntegrityCheck(false);
$select->from(array('ar' => 'artists'), array('artist_name'))
       ->leftJoin(array('al' => 'albums'), 'al.artist_id = ar.artist_id', array('album_name'));

$rows = $artistTable->fetchAll($select);

C'est très proche du SQL tel que tu l'écrirais, avec l'instruction ON appropriée pour la jointure etc.

Avec doctrine et le DQL c'est différent, tu vas interroger tes objets métiers :

Code:

$artists = Doctrine_Query::create()
            ->select('ar.name, al.name')
            ->from('Model_Artist ar')
            ->leftJoin('ar.albums al')
            ->execute();

Si on traduit en français, ça veut dire : "Remonte moi chaque objet Model_Artist avec sa propriété name et avec tous ses objets Model_Album liés et leurs propriétés name".

Dans le premier cas tu requêtes directement en fonction du schéma de ta base et tu écris explicitement ta jointure, Zend_Db ne fait que traduire la requête dans le langage de la base de données.

Dans le 2ème cas, tu ne requêtes pas la bdd directement, mais tu requêtes tes entités, les jointures sont implicites et sont manipulées comme des relations entres objets. Le DQL est ensuite traduit dans une requête compréhensible par le moteur de ta base de données en fonction de ton mapping (grâce au DBAL).

Tu vois bien que si je change le nom d'un champ dans ma table, ça va impacter la requête Zend_Db mais pas celle de Doctrine qui continue à requêter mes objets et non pas mes tables.

Avec le résultat des requêtes précédentes, si je veux afficher la liste d'albums de chaque artiste, avec Zend_Db je dois parcourir toutes mes rows et faire une condition pour passer à l'artiste suivant, ex :

Code:

$artistName = '';
foreach($rows as $row) {
    if ($artistName != $row->artist_name) {
        echo 'Artiste : ' . $row->artist_name . '<br />';
    }
    echo '    - ' . $row->album_name . '<br />';
    $artistName = $row->artist_name;
}

Et en plus j'utilise directement le nom de mes champs.

Avec le résultat Doctrine :

Code:

foreach($artists as $artist) {
    echo 'Artiste : ' . $artist->name . '<br />';
    foreach($artist->albums as $album) {
        echo '    - ' . $album->name . '<br />;
    }
}

Dans ce cas là je parcours mes objets métiers et leurs relations de façon logique et dans un contexte métier et purement POO.


Zend_Db permet aussi de générer des entités si on crée des classes qui hérite de Zend_Db_Table_Row si j'ai bien compris. et au final il y a juste besoin de travailler avec les objets comme dans le code là :

Oui, mais zend ne fait que refléter exactement la structure de ta base de données dans une version objet de cette base.

Avec Doctrine 2, les objets métiers sont créés par les programmeurs avec leurs comportements métier indépendamment de la base. Les propriétés des objets sont ensuite mappés sur un système de persistance, par ex. une base de données relationnelle. Le modèle métier est donc extensible, facilement réutilisable et n'a pas une implémentation spécifique à un type de base de données, ce sont de pures objets PHP.

Plus simplement, avec Zend_Db tu manipules des tables (collections) et des lignes de ces tables (enregistrements) directement, alors qu'avec un ORM tu manipules des objets métiers qui sont indépendants de tout système persistance.


A+ benjamin.

Dernière modification par Delprog (11-08-2010 20:15:43)


http://www.anonymation.com/ - anonymation - Studio de création.
http://code.anonymation.com/ - anonymation - blog - développement et architecture web

Hors ligne

 

#9 11-08-2010 20:30:27

nosferapti
Membre
Date d'inscription: 10-01-2010
Messages: 40

Re: [Résolu] Doctrine, Zend_Entity ou Zend_Db

Delprog a écrit:

Plus simplement, avec Zend_Db tu manipules des tables (collections) et des lignes de ces tables (enregistrements) directement, alors qu'avec un ORM tu manipules des objets métiers qui sont indépendants de tout système persistance.

avec Zend_Db il est possible de définir ces propres classes qui représentent les lignes de la table et à partir de là il est aussi possible de définir un mapping dans cette classe

Merci pour ces détails je vois un peu plus clair. Malheureusement (pour Doctrine), les classes que j'utilise préparent déjà la séparation entre la tables et les objets donc au final je pense que je ne vais pas utiliser Doctrine

Merci à tous les participants


GNAP !

Hors ligne

 

#10 12-08-2010 09:03:10

Blount
Membre
Date d'inscription: 23-06-2009
Messages: 95
Site web

Re: [Résolu] Doctrine, Zend_Entity ou Zend_Db

@Delprog : mais, existe t-il des limites au DQL ?
Par exemple, si je veux récupérer tout les artistes et le nombre d'albums leurs étant associés.
Comment faire sans récupérer toutes les informations des albums ? En fait, il faut faire un COUNT et un GROUP By (SQL parlant).
Ou, la récupération des informations des albums est-elle indispensable ?

Est-il facile de jouer avec les fonctions SQL ? Par exemple, si je veux récupérer la somme total d'une facture avec SUM sur la table "article".

Actuellement, j'ai un champ SQL qui est incrémenté/décrémenté (nombre d'album pour un artiste) et géré par des triggers.

Hors ligne

 

#11 12-08-2010 10:13:33

Delprog
Administrateur
Date d'inscription: 29-09-2008
Messages: 670

Re: [Résolu] Doctrine, Zend_Entity ou Zend_Db

Salut,

Le DQL n'est pas obligatoire. Il est possible, et même conseillé pour des raisons de performances, d'exécuter des requêtes pures pour les aggregations. Par ex., si un pattern tel que DAO est utilisé, c'est dans cette couche que les requêtes sont construites, que ce soit du DQL ou sur le driver directement. D'ailleurs ça reste valable aussi lorsqu'on utilise Zend_Db, utiliser des mappers et une couche DAO permet même avec Zend_Db de détacher les objets de la persistance.

Ce n'est pas parce que vous utilisez un ORM que tout doit passer par lui, à vous d'architecturer votre appli. pour ne pas être bloqués. J'ai très rarement vu des projets où on se contente d'utiliser un composant DB, beaucoup de requêtes sont écrites en dur et sont exécutées directement avec le driver PDO.

Le DQL est très gourmant en ressource (transformation de la requête, hydratation des résultats, etc.), il faut donc l'utiliser intelligemment, ne pas hydrater des entités quand ce n'est pas nécessaire et bien utiliser les différents types d'hydratation (array, scalar, etc.). Avoir aussi une bonne politique de cache est un gain assez conséquent.

Mais le DQL est quand même bien foutu, je peux très bien faire :

Code:

$count = Doctrine_Query::create()
          ->select('COUNT(1) as compteur')
          ->from('Model_Album al')
          ->where('al.date > ?', '2010-01-01')
          ->fetchOne(array(), Doctrine_Core::HYDRATE_SINGLE_SCALAR);

A+ benjamin.


http://www.anonymation.com/ - anonymation - Studio de création.
http://code.anonymation.com/ - anonymation - blog - développement et architecture web

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages