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

Symfony PHP Discussion :

Symfony2 / BDD Oracle


Sujet :

Symfony PHP

  1. #1
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2012
    Messages
    128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2012
    Messages : 128
    Points : 62
    Points
    62
    Par défaut Symfony2 / BDD Oracle
    Bonjour à tous,

    Je suis débutant en symfony (pas en php) et je cherche à développez un petit intranet.
    Cependant, cela fait maintenant 2 jours que je cherche à créer un lien entre ma base de donnée Oracle et mon projet symfony.

    J'ai bien vue que je devais utiliser doctrine ou encore propel ou autres mais j'aimerais justement NE PAS utiliser ces outils.

    Et là je bloque: Je ne trouve aucun tuto ou autre sur Internet (ou alors je suis passé à coté) qui me permettrait de connaitre ce qu'il y a a faire pour me connecter à cette base et tester via une simple requete SELECT * FROM... avec un petit affichage pour savoir si cela fonctionne réellement.

    J’espère que vous pourrez m'aider et que je n'en demande pas trop.

    Merci d'avance.

  2. #2
    Membre expérimenté Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Points : 1 310
    Points
    1 310
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    $conn = $this->container->get('database_connection');
    $sql = 'SELECT * FROM ...';
    $rows = $conn->query($sql);

  3. #3
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2007
    Messages : 4
    Points : 10
    Points
    10
    Par défaut
    Bonjour,

    Dans votre cas, vous pouvez utiliser uniquement la couche DBAL de doctrine pour attaquer votre base de données.

    Voici ce que j'utilise pour lancer une query. Il s'agit une fonction dans la classe:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    protected function queryExecute($query, array $values)
    {
       $stmt = $this->conn->prepare($query);
       foreach ($values as $key => $value) {
           $stmt->bindValue($key, $value);
       }
       $stmt->execute();
     
       return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    Excellente journée.

    Bertrand

    PS: il y a un canal IRC pour #symfony-fr

  4. #4
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2012
    Messages
    128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2012
    Messages : 128
    Points : 62
    Points
    62
    Par défaut
    Bonjour,

    Tout d'abord merci pour vos réponses.
    Il me reste maintenant une question: La configuration de la connexion à la base de données se situe bien dans le fichier Parameters.yml ?
    Si oui voici le fichier que j'utilise. Es-ce bon ? (j'ai repris mon TNSNAME.ORA)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    parameters:
        database_driver: oci8
        database_host: VDL
        database_port: 1521
        database_name: ***
        database_user: ***
        database_password: ***
    Et enfin dans vos bout de code vous avez respectivement 'database_connection' et 'conn'
    Ces variables comment sont-elles initialisées ? Vous vous servez de Parameters.yml ?

    Merci

  5. #5
    Membre expérimenté Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Points : 1 310
    Points
    1 310
    Par défaut
    Ton parameters.yml a l'air ok (après c'est la config de ta base on peut difficilement savoir à ta place ^^).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $conn = $this->container->get('database_connection');
    Cette ligne appelle le service portant l'id 'database_connection' que tu peux retrouver en tapant la commande php app/console container:debug dans ton terminal. Cette commande va te lister tous les services accessibles depuis le container et notamment ces deux lignes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     database_connection                                                                      n/a       alias for "doctrine.dbal.default_connection" 
     doctrine.dbal.default_connection                                                         container stdClass
    Ce service utilise les informations que tu auras déclaré dans ton fichier parameters.yml.
    Le $this->conn présume que tu te trouve dans une classe qui possède ce service comme attribut.

    Il t'est ensuite possible de faire des requêtes natives et de les binder toi même avec tes entités, soit avec une classe custom, soit en utilisant le ResultSetMapping de Doctrine.

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2011
    Messages : 5
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par ruyeken Voir le message
    Bonjour,

    Tout d'abord merci pour vos réponses.
    Il me reste maintenant une question: La configuration de la connexion à la base de données se situe bien dans le fichier Parameters.yml ?
    Si oui voici le fichier que j'utilise. Es-ce bon ? (j'ai repris mon TNSNAME.ORA)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    parameters:
        database_driver: oci8
        database_host: VDL
        database_port: 1521
        database_name: ***
        database_user: ***
        database_password: ***
    Et enfin dans vos bout de code vous avez respectivement 'database_connection' et 'conn'
    Ces variables comment sont-elles initialisées ? Vous vous servez de Parameters.yml ?

    Merci
    Ne pas oublier de rajouter dans le fichier config.yml le paramètre charset: UTF8 sous la connection DBAL car sinon Oracle ne répond pas correctement.

    Le retour de la query sera un tableau.

  7. #7
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2012
    Messages
    128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2012
    Messages : 128
    Points : 62
    Points
    62
    Par défaut
    Ok c'est bien pris.
    Ca commence à prendre forme dans ma tête...

    J'ai bien modifier le parameters charset UTF8
    Je rappelle que je débute avec symfony.

    Donc j'ai une classe DB.class.php située dans le répertoire entity:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?php
     
    namespace RPC\TestBundle\Entity;
     
    class DB{
        public function allCustomer(){
            $conn = $this->container->get('database_connection');
            $sql = 'SELECT * FROM CUSTOMER';
            $rows = $conn->query($sql);
     
            return $rows;
        }
    }
    Mais dans mon controller du coup ça se passe comment ? et dans mon twig ? Parce que dans mon twig c'est l'affichage et mon controller est censé récupérer le résultat de la requête et de l'insérer dans mon .twig.

    le getEntityManager, getRepository tout ça reste bien flou pour moi...

  8. #8
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2012
    Messages
    128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2012
    Messages : 128
    Points : 62
    Points
    62
    Par défaut
    Ah et je précise que quand je tente certains trucs j'ai cette erreur:
    "ParameterNotFoundException: You have requested a non-existent parameter "secret"."

    Ques ce que cela signifie ? j'ai louper qqch ?

    Merci pour vos futures réponses.

  9. #9
    Membre expérimenté Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Points : 1 310
    Points
    1 310
    Par défaut
    Ce que tu essayes de faire avec ta classe DB en réalité c'est le travail des repositories.

    Très grossièrement et pour les cas basiques : une entité c'est un objet persistant qui correspond à ton modèle de BDD. Les repositories, ce sont des classes qui correspondent à une entité et dans lesquelles tu retrouveras toutes les requêtes propres à cette entité. Si tu n'utilises pas Doctrine pour faire la transition entre les résultats de tes requêtes et tes entités, tes requêtes ne retourneront que des tableaux.
    Si tu ne manipules que des tableaux, il faut commencer à te demander l'intérêt d'utiliser la POO et un framework comme Symfony.

    Donc on va partir du principe que tu veux faire des requêtes natives mais qu'après, faisant preuve de bon sens, tu décides de mapper tes résultats dans des objets (appelés entités). Là tu vas avoir besoin d'un service, (d'une autre classe) qui va faire ce boulot. Doctrine t'en propose un qui s'appelle le ResultSetMapping. Un résultat de requête correspondra à un graphe d'objets. Sinon tu peux t'en faire un toi même si tu as des besoins très spécifiques.

    L'entity manager, c'est le point central pour toutes les fonctionnalités de l'ORM. Ça regroupera tous les éléments liés à Doctrine, et à la persistance des objets comme le UnitOfWork, le Query Language, les Repositories etc. Ce que tu dois en retenir c'est que tu en as besoin pour persister un objet et l'enregistrer en base.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    $object = new Object();
    $object->setAttr1($attr1);
    $object->setAttr2($attr2);
     
    $entityManager->persist($object);
    $entityManager->flush();
    Ce morceau te fera une requête INSERT dans la table qui correspond à ta classe Object. Si à la place d'un new on récupérait un objet existant, ce même morceau de code te ferait une requête UPDATE.

    Donc ce que je te suggère c'est que ta classe DB, tu l'oublies. Tu te fais une entité par table (sauf tables de liaisons ou tables sur lesquelles tu n'agis pas). Tu lis un peu la doc sur les annotations Doctrine pour au moins lier tes objets. Ensuite tu te fais un fichier Repository par entité, et tu écris des requêtes natives, ou en DQL (ou même en morse avec du pipi dans la neige si ça te fait plaisir) mais tu ne fais pas de requêtes ailleurs. Les requêtes c'est dans les fichiers repo : qu'il s'agisse de requêtes natives ou pas => REPOSITORY. Une méthode = un requête. Le mapping des données tu peux le faire dans la méthode (pas fan) ou dans un autre service.

    Après pour le reste c'est à toi de voir comment tu veux t'organiser. Est-ce que tu veux directement appeler ton repository depuis ton contrôleur ? C'est possible. Est-ce que tu veux faire une classe manager qui fasse le lien entre tes repos et tes contrôleurs ? C'est possible aussi. Tu fais comme tu le sens : le but étant qu'à un moment donné ton contrôleur possède un service qui lui permette d'appeler les méthodes de ton repo.

    Le problème avec Symfony quand on est débutant c'est qu'on te dit "bah fais comme tu veux". Je peux te dire comment moi je fais, chacun des utilisateurs de Symfony peut te dire comment il fait mais ça ne t'aidera pas sachant que chacun fait différemment. Donc pour résumer :

    Ton contrôleur possèdera un service qu'il appellera pour te retourner le résultat de la méthode qui fait ta requête dans ton repository.
    Ce même contrôleur doit passer ce résultat à la template via un tableau. Dans ce tableau se trouvera la clé et la valeur.
    Tu accèdes dans twig à ces valeurs avec les variables nommées avec les clés du tableau précédent.
    Si tu as bien des objets, tu auras accès depuis twig à toutes les méthodes publiques de ces objets.

    Mais je crois que si on en arrive là, on a dépassé (et de loin) ton problème de configuration Symfony/Oracle.

  10. #10
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2012
    Messages
    128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2012
    Messages : 128
    Points : 62
    Points
    62
    Par défaut
    Bonjour,

    Alors j'ai bien lu ton message il est vraiment clair mais j'admet qu'il me reste quelques soucis...

    Donc dans mon projet test je veux voir par exemple la totalité de mes clients (customer)
    La table (déjà existante) est composée d'énormément de champs, je prends donc uniquement les champs principaux (sid, last_name, first_name) et je
    fais une entité customer.

    Un truc simple quoi.
    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
    <?php
     
    namespace RPConsulting\TestBundle\Entity;
     
    use Doctrine\ORM\Mapping as ORM;
     
    class Customer
    {
     
        private $sid;
        private $last_name;
        private $first_name;
     
        public function __construct($sid, $last_name, $first_name)
        {
            $this->sid = $sid;
            $this->last_name = $last_name;
            $this->first_name + $first_name;
        }
     
        public function getSid() {
            return $this->sid;
        }
     
        public function getLast_name() {
            return $this->last_name;
        }
     
        public function getFirst_name() {
            return $this->first_name;
        }
     
        public function setSid($sid) {
            $this->sid = $sid;
        }
     
        public function setLast_name($last_name) {
            $this->last_name = $last_name;
        }
     
        public function setFirst_name($first_name) {
            $this->first_name = $first_name;
        }
     
     
    }

    Maintenant, si je suis tes indications je fais donc un répertoire repository avec dedans une nouvelle classe CustomerRepository. Bon la déjà je doute. Je vous montre mon code.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?php
     
    namespace RPC\TestBundle\Repository;
     
    class CustomerRepository extends EntityRepository {
     
        public function allCustomer() {
            $conn = $this->container->get('database_connection');
            $sql = 'SELECT * FROM CUSTOMER';
            $rows = $conn->query($sql);
     
            return $rows;
        }
    }

    Ensuite mon controller... La vide total. Je vois pas comment je peux faire la liaison entre mon entité, mon repository et mon twig.

    Pour faire court voici mon code.

    Controller
    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
    <?php
     
    namespace RPConsulting\TestBundle\Controller;
     
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use RPConsulting\TestBundle\Entity;
    use RPConsulting\TestBundle\Repository;
     
     
    class TestController extends Controller
    {
        public function indexAction()
        {
          $em = $this->getDoctrine()->getEntityManager();
          $entities = $em->getRepository('RPConsultingTestBundle:Test')->allCustomer();
          return $this->render('RPConsultingTestBundle:Test:test.html.twig', array('entities' => $entities));
        }
    }
    Un truc comme ça peut etre ?? mais j'ai une erreur sur cette ligne...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $entities = $em->getRepository('RPConsultingTestBundle:Test')->allCustomer();
    Quand à mon twig un truc léger...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    {# empty Twig template #}
    <!DOCTYPE html>
    <html>
     <head>
        <title>RPC!</title>
      </head>
      <body>
        <p>
          Result: {{ entities}}
        </p>
      </body>
    </html>

    VOici les questions:
    -> Suis-je sur le bon chemin ou au contraire je pars complètement à l'ouest ?
    -> SI c'est bon pouvez vous me dire pk j'ai une erreur dans mon controlleur ?
    -> Plus généralement pouvez vous me dire mes erreurs dans chaque code ?

    Sinon oui on dépasse (et de loin) le problème de configuration Oracle/Symfony j'ai mal nommé mon sujet alors, mais à la base c'était vraiment pour essayer d'avoir un truc complet de A à Z afin que je puisse bien assimiler l'affaire...

    Merci d'avance pour vos réponses.

  11. #11
    Membre expérimenté Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Points : 1 310
    Points
    1 310
    Par défaut
    Si tu as des erreurs, ce serait bien que tu nous dises leur contenu.

    Je dirais qu'il te manque le lien entre ton entité et ton repository. Une annotation au dessus de ta classe Customer te permettra de récupérer son repository.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /**
     * @Entity(repositoryClass="RPC\TestBundle\Repository\CustomerRepository")
     */
    class Customer
    {
    }
    Le nommage de ta variable $entities dans ton contrôleur me fait doucement sourire : car si tu ne veux pas utiliser l'ORM et que tu utilises tes requêtes de cette manière, ce sont des tableaux que tu vas retourner : pas des entités. Encore une fois, si tu veux te passer de Doctrine, c'est ton choix mais il faut que tu fasses tout le boulot toi même pour mapper les résultats et récupérer des objets et là, la méthode de ton repository ne te retourne qu'un tableau.

    Pour des requêtes complexes, qu'il n'est pas possible d'écrire via le DQL, je trouve déjà ça chiant mais bon c'est justifié. Mais pour faire un select *, là c'est vraiment se casser le cul et perdre du temps pour rien de passer par une requête native.

    Blague à part, tu appeles le mauvais repository dans ton contrôleur, si tu veux appeler le repository de ton Customer, alors il faut appeler le repository de la bonne entité.
    Un indice : ce n'est pas RPConsultingTestBundle:Test

    Ensuite côté twig, tu n'afficheras pas grand chose en faisant
    Dans l'état actuel des choses, entities est un tableau donc une boucle en twig ne serait peut-être pas de trop, histoire d'afficher tes résultats un par un (si tu es vraiment feignant et que tu veux faire une boucle ou tu vas faire {{ entity }} tu peux, mais il te faudra une méthode __toString dans ton entité ... et il faudra aussi manipuler un objet, ce qui nous ramène à cette histoire de mapping).

    Le reste est plus ou moins cohérent :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public function indexAction()
    {
      // Récupération du service Doctrine, qui lui même va te donner l'entityManager
      $em = $this->getDoctrine()->getEntityManager();
      // L'entityManager te fournit le Repository associé à ton entité Test (c'est plutôt l'entité Customer qu'il faudrait mettre ici en l'occurrence) et appeler la méthode allCustomer() du repo
      $entities = $em->getRepository('RPConsultingTestBundle:Test')->allCustomer();
      // Tu vas afficher le template test.html.twig en lui passant en paramètre la variable entities qui correspondra au résultat de ta requête
      return $this->render('RPConsultingTestBundle:Test:test.html.twig', array('entities' => $entities));
    }

  12. #12
    Membre expérimenté Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Points : 1 310
    Points
    1 310
    Par défaut
    Une dernière chose : on est bien d'accord sur le fait que tu es débutant en Symfony, mais tout ce que tu demandes trouve une réponse dans la documentation officielle, et même avec le code généré par Symfony via les commandes (génération d'une entité, génération d'un CRUD).

    Un petit effort de recherche et d'analyse et tout devrait bien se passer.

  13. #13
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2012
    Messages
    128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2012
    Messages : 128
    Points : 62
    Points
    62
    Par défaut
    Merci pour ta patience.
    Oui je suis débutant, j'ai suivi un tuto avec une base MYSQL mais j'admet que le fait d'utiliser Une base Oracle déjà existante me perturbe.
    De plus avant de poser la question j'ai quand même lu des avis ou il est dit que Doctrine et Oracle ne sont pas tellement compatible. Voilà pourquoi je cherche à faire sans Doctrine (et pourtant avec Doctrine c'est quand même plus simple).

    Donc j'ai regarder ta réponse avec attention, je pense avoir tout bien appliquer (une boucle dans mon twig, un lien dans mon entité Customer quand à la __toString() pour l'instant j'en fais pas je voudrais juste etre capable de faire un truc simple).

    Soit dit en passant c'est vrai que j'aurais pu évité de nommer ma variable $entities surtout que j'utilise pas vraiment les entities.

    Donc à l'execution j'ai cette erreur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [Syntax Error] Expected Doctrine\Common\Annotations\DocLexer::T_IDENTIFIER or Doctrine\Common\Annotations\DocLexer::T_TRUE or Doctrine\Common\Annotations\DocLexer::T_FALSE or Doctrine\Common\Annotations\DocLexer::T_NULL, got '@' at position 37 in class RPConsulting\TestBundle\Entity\Customer.
    Ques ce que cela signifie ?

    Je remet le controleur et le début de customer le twig et le début du répository au cas ou il y aurait (encore) qqch qui n'irait pas.
    Controleur:
    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
    <?php
     
    namespace RPConsulting\TestBundle\Controller;
     
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
     
    class TestController extends Controller {
     
        public function indexAction() {
     
    // Récupération du service Doctrine, qui lui même va te donner l'entityManager
            $em = $this->getDoctrine()->getEntityManager();
            // L'entityManager te fournit le Repository associé à ton entité Test (c'est plutôt l'entité Customer qu'il faudrait mettre ici en l'occurrence) et appeler la méthode allCustomer() du repo
            $entities = $em->getRepository('RPConsultingTestBundle:Customer')->allCustomer();
            // Tu vas afficher le template test.html.twig en lui passant en paramètre la variable entities qui correspondra au résultat de ta requête
            return $this->render('RPConsultingTestBundle:Test:test.html.twig', array('entities' => $entities));
        }
     
    }
    Twig:
    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
    {# empty Twig template #}
    <!DOCTYPE html>
    <html>
        <head>
            <title>RPC!</title>
        </head>
        <body>
            <p>
                {% for entities in entities%}
                    <tr>
                        <td>{{ entities}}</td>
                    </tr>
                {% endfor %} 
            </p>
        </body>
    </html>
    Entité:
    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
    <?php
     
    namespace RPConsulting\TestBundle\Entity;
     
     
    use Doctrine\ORM\Mapping as ORM;
     
    /**
     * RPConsulting\TestBundle\Entity\Customer
     *
     * @ORM\Table(name="customer")
     * @ORM\@Entity(repositoryClass="RPConsulting\TestBundle\Repository\CustomerRepository")
     */
     
    class Customer
    {
    }
    Repo:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <?php
     
    namespace RPConsulting\TestBundle\Repository;
     
    use Doctrine\ORM\EntityRepository;
     
    class CustomerRepository extends EntityRepository {
    Donc en exécutant l'ensembl, j'ai l'erreur du début... Je la comprend pas.

  14. #14
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2012
    Messages
    128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2012
    Messages : 128
    Points : 62
    Points
    62
    Par défaut
    Ok c'est bon j'ai trouvé mon erreur, c'est juste que j'avais mal mis mes relations.. Je recherche et je vous tiens au courant

  15. #15
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2012
    Messages
    128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2012
    Messages : 128
    Points : 62
    Points
    62
    Par défaut
    Bon ok j'ai résolu mon problème. Donc maintenant voilà que j'ai une autre erreur. Cette fois ci un peu plus importante je pense.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ContextErrorException: Notice: Undefined property: RPConsulting\TestBundle\Repository\CustomerRepository::$container in
    Il m'indique cette ligne ci de customerRepository.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $conn = $this->container->get('database_connection');
    Donc la j'ai un problème de connexion, il aime pas le container... Pk ? Mon parameters.yml j'ai du ajouter les lignes sur les mails tout ça es ce vraiment obligatoire ?

    Merci d'avance.

  16. #16
    Membre expérimenté Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Points : 1 310
    Points
    1 310
    Par défaut
    En fait il s'agirait d'essayer de comprendre ce que tu écris même si tu le copies/colles.
    Même si là il s'agit du fonctionnement interne du framework, l'erreur n'est rien d'autre qu'une erreur classique de POO.

    Undefined property: RPConsulting\TestBundle\Repository\CustomerRepository::$container.
    Pour faire simple la classe CustomerRepository ne possède pas d'attribut container. DOOOONNC tu ne peux pas faire un $this->container dans ta classe CustomerRepository.

    "Oui mais Nico, en fait c'est toi qui m'a dit d'écrire cette ligne, et maintenant tu vas me dire qu'elle est pas bonne ?"
    - GRAAAAVE ! On efface tout et on recommence, cette ligne c'était pour tester la config facilement. Maintenant que tu veux qu'on fasse tout le projet va quand même falloir réorganiser ça.

    Explication : un controller classique généré par Symfony étend de la classe Controller du framework, qui elle même étend une classe abstraite ContainerAware. Du coup dans ce type de contrôleur, pour obtenir le service de connexion à la base, il faut passer par le container de service ... comme ceci !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $conn = $this->container->get('database_connection');
    Et on y arrive parce qu'en remontant les classes étendues et les interfaces implémentées on trouve ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /**
     * @var ContainerInterface
     *
     * @api
     */
    protected $container;
    Maintenant tu te trouves dans une classe CustomRepository qui étend visiblement la classe EntityRepository. Tu pourrais te dire qu'une classe de type repository possède déjà plus ou moins les méthodes qui lui permettent de faire des requêtes natives (ça semblerait logique vu que c'est là qu'on fait des requêtes). Alors on check un peu la classe EntityRepository parente et là PAF (ça fait des chocapics) ! Des méthodes en veux-tu en voilà pour faire plein de requêtes, y compris des requêtes natives.

    Un indice ... cette méthode (ainsi que la doc) pourrait te servir "createNativeNamedQuery($queryName)".
    ++

  17. #17
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2012
    Messages
    128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2012
    Messages : 128
    Points : 62
    Points
    62
    Par défaut
    Bonjour,

    Merci pour ta réponse j'ai travailler dessus mais j'ai un problème qui intervient au moment de la connection.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $conn = $this->container->get('database_connection');
    J'ai ce message d'erreur:
    FatalErrorException: Error: Call to a member function get() on a non-object in '+chemin'

    J'ai regarder mon parameters.yml pour moi tout est bon mais la le souci c'est sur le get.

    Le get est censé récupérer le parameters.yml. Alors plusieurs questions
    -> A quoi correspond le 'database_connection' ? A quoi il fait appel exactement ?
    -> cette méthode get fais partie de quelle classe ? EntityRepository ?


    Merci pour vos réponse j'ai bien regarder la doc et la méthode createNativeNamedQUery($query) mais le souci est avant çà.. :S

  18. #18
    Membre expérimenté Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Points : 1 310
    Points
    1 310
    Par défaut
    L'erreur et relativement explicite : tu essayes de faire un get depuis une variable qui n'est pas un objet.
    Donc à priori, là ou tu te trouves, $this->container n'est pas un objet, voire n'existe pas.

    Donne nous au moins le contenu de la méthode ou tu fais cet appel pour qu'on y voit un peu plus clair. Et surtout, dis nous dans quelle classe tu te trouves et de quoi elle étend.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    // Conteneur de service. Tu trouves cet attribut dans toutes les classes qui implémentent l'interface ContainerAwareInterface.
    // Logiquement ceci devrait être une instance de la classe Container.
    $this->container
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    // Récupération du service possédant la clé 'nom_du_service'.
    $conn = $this->container->get('nom_du_service');
    Dans ton exemple, tu affecte le service 'database_connection' à ta variable $conn.
    Mais compte tenu de l'erreur, tu n'arrives pas à avoir le container, donc à priori tu ne te trouves pas dans une classe qui est "container aware" et donc tu ne peux pas faire le get.

    Une dernière chose : le get n'est pas censé récupérer quoique ce soit dans parameters : il est censé récupérer un service. Il y a de grandes chances pour que ton parameters soit bon, là n'est pas le problème.

  19. #19
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2012
    Messages
    128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2012
    Messages : 128
    Points : 62
    Points
    62
    Par défaut
    Ahhh tout s'explique alors. Ca à l'air de passé maintenant. Seul Hic aucune données ne remontent...

    Pout t'expliquer le comment je fais je te file un peu de code. Dis moi si c'est la méthode idéale ou pas.. Ou ce que tu en penses..

    Donc j'ai fais une entité Connection (class Connect) que j'ai mis dans le répertoire Entity

    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
    <?php
     
    namespace RPConsulting\TestBundle\Entity;
     
     
    class Connect extends ContainerAware
    {
            /**
         * @var ContainerInterface
         *
         * @api
         */
        protected $container;
     
        public function __construct() {
            $this->container->get('database_connection');
        }
    }

    Dans mon CustomerRepository, j'ai une méthode allCustomer

    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
    <?php
     
    namespace RPConsulting\TestBundle\Repository;
     
    use Doctrine\ORM\EntityRepository;
     
    class CustomerRepository extends EntityRepository
    {
     
        public function allCustomer()
        {
            $conn = new \RPConsulting\TestBundle\Entity\Connect;
            $sql = 'SELECT CUST_SID, LAST_NAME, FIRST_NAME FROM CUSTOMER';
            $rows = $conn->query($sql);
     
            return $rows;
     
        }
    }
    et mon twig... Qui je pense doit être pas terrible aussi...

    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
    {# empty Twig template #}
    <!DOCTYPE html>
    <html>
        <head>
            <title>RPC!</title>
        </head>
        <body>
            <p>
                {% for entities in entities%}
                    <tr>
                        <td>{{ entities}}</td>
                    </tr>
                {% endfor %} 
            </p>
        </body>
    </html>

    Voila quand j’exécute mon testController j'ai aucune erreur mais aucune données ne remontent...

    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
    <?php
     
    namespace RPConsulting\TestBundle\Controller;
     
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
     
    class TestController extends Controller {
     
        public function indexAction() {
     
            $em = $this->getDoctrine()->getEntityManager();
            $entities = $em->getRepository('RPConsultingTestBundle:Customer')->allCustomer();
     
            return $this->render('RPConsultingTestBundle:Test:test.html.twig', array('entities' => $entities));
        }
     
    }
    Je sais pas j'essaye d'apprendre je lis la doc mais quand on a jamais fais de symfony avant c'est vraiment complique quand même.

  20. #20
    Membre expérimenté Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Points : 1 310
    Points
    1 310
    Par défaut
    ... ok.
    Dans l'ordre :

    • Ta classe Connect ne sert strictement à rien : tu peux la jeter, en plus le constructeur récupère le service database_connection mais ne l'affecte à aucune variable. C'est comme si tu ne faisais rien du tout.
    • Ta classe CustomerRepository n'a pas besoin de la classe Connect vu que de toute manière, comme je te l'ai dit dans un précédent post, elle possède déjà les méthodes nécessaires pour faire une requête native.
    • Le chargement du service database_connection n'a donc pas lieu d'être, comme je te l'ai déjà dit avant, ça n'était à utiliser que pour faire un test.
    • Il serait peut-être préférable, dans ton twig, de mettre une variable différente pour la collection et pour l'objet en cours (for entity in entities)
    • Tu n'as à priori pas fait de méthode __toString() donc il faut que tu fasses appel au getter qui va t'afficher la donnée de ton objet (exemple entity.lastname)

Discussions similaires

  1. Réponses: 28
    Dernier message: 28/07/2005, 14h12
  2. Accès BDD Oracle
    Par rgarnier dans le forum XMLRAD
    Réponses: 5
    Dernier message: 21/01/2005, 15h03
  3. Export Acces->Excel Requette sur bdd oracle
    Par cedrickb dans le forum Access
    Réponses: 2
    Dernier message: 31/12/2004, 14h27
  4. Connexion BDD oracle TNS protocol adapter error
    Par cedrickb dans le forum Access
    Réponses: 3
    Dernier message: 30/12/2004, 13h02
  5. Créer une BDD Oracle sur windows
    Par calimero82 dans le forum Administration
    Réponses: 7
    Dernier message: 25/10/2004, 15h30

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