Hello,

Alors petit problème que je n'arrive pas à résoudre de moi même, je suis pourtant sûr ne pas être très loin d'y arriver. Les tableaux sont pas mon fort mais bon.

Donc en gros, j'ai dans une classe ArticlesEntity tout des getters :

<?php

  class ArticlesEntity extends Entity {

    public function getTitre() {
      return $this->titre;
    }

    public function getContenu() {
      return $this->contenu;
    }

    public function getStatut() {
      return $this->statut;
    }

    public function getVisible() {
      return $this->visible;
    }

    public function getCommentaires() {
      return $this->commentaires;
    }

    public function getCategorie() {
      return $this->categorie;
    }

    public function getTags() {
      return $this->tags;
    }    

  }

Donc dans la partie visible, pour appeler un de ces getters, j'ai juste à faire :

$articles = Database::getInstance()->getTable('articles')->find($_GET['id']);
$titre = $articles->titre;
$contenu = $articles->contenu;
$tags = $articles->tags;
// Etc...

Plutôt que d'avoir 36000 variables, j'aimerai juste avoir un tableau avec en paramètre le nom du getter.
Genre $datas['titre'], qui irai donc chercher $articles->titre.

Aussi simple que ça paraisse, je n'y arrive pas XD
J'avais réussi à pondre un truc comme ça :

foreach ($articles as $k => $v){ // $articles ayant toutes les données de la requête en tableau.
    $datas[$k] = $articles->$k;
  }

Donc quand je fais par exemple :

   echo $datas['titre'] ; // Me renvoi bien le titre, mais du résultat de la requête
   // Pas du getter getTitre()

En gros, ça va là si je veux les données brutes du résultat de la requête, parce que dans les getters pour le moment je ne return que ça, mais si je viens à faire comme dans la vidéo, un getter URL, qui elle ne se trouve pas dans ma table, je pourrai jamais appeler avec $data['url'].

J'espère ne pas avoir été trop dur à comprendre ^^'
Je vous aiderai à comprendre si besoin

Merci !

EDIT : Pour faire simple, si dans la class, je change le getter getTitre en getTitle, faire un $datas['title'] n'ira pas chercher le $articles->title qui ira chercher le getTitle()

17 réponses


Bonjour,

Sur la formation POO de Grafikart, il parle de "surcharge magique" pour la class Entity.

class Entity {

    /**
    * Surcharge Magique
    * @param string Nom de la propriétés à surcharger
    * @return appelle de méthode
    */
    public function __get($name) {
        $method = 'get'.ucfirst($name);
        $this->$name = $this->$method();
        return $this->$name;
    }
}

Celleci-vous permet d'appeler directement un élément $article->nom par exemple.

Genki
Auteur

Je l'ai déjà, désolé de pas l'avoir précisé, mais elle y est bien :)

<?php

  class Entity {

    public function __get($key) {
      $method = 'get'. ucfirst($key);
      $this->$key = $this->$method();
      return $this->$key;      
    }
  }

?>

(Et elle est bien appelé au bonne endroit, ça marche dans l'ensemble, mais je veux juste adapter mon code avec un tableau pour éviter d'avoir 300 variables qui renvoit tous à des getters)

Bonjour Genki,

pourquoi vouloir forcement faire un tableau ?
Ceci devrait fonctionner :

<?php 
foreach ($articles as $article){ // $articles ayant toutes les données de la requête en tableau.
    echo $article->titre;
  }
Genki
Auteur

Je veux les stocker dans un tableau pour les appeler plus tard. J'ai pas besoin de les afficher au moment ou je fais le foreach.
Donc pas d'echo :/

Peu importe, echo ou pas, c'était un exemple.

Ton but me semble flou, éclaircissons tout ça si tu le veux bien :)

  1. Tu souhaites récupérer un ou plusieurs articles ?
    Je pose la question parce qu'il y a un "s" à articles.
  2. Que te renvoie ta méthode find() ? Est-ce que tu peux me faire un var_dump s'il te plaît ?
Genki
Auteur

Je veux en récupérer un seul. C'est ce que Graf appelle une Entity.
La fonction find, me permet de selectionner dans ma table, l'article qui correspond avec l'ID passer en paramètre.

Il y a un 's' pour des raisons pratiques. Mais tout est encore en phase de test pour le moment donc ça peut venir à changer plus tard.
Le VD :

object(ArticlesEntity)#5 (10) {
  ["id"]=>
  string(1) "5"
  ["titre"]=>
  string(9) "Mon titre"
  ["contenu"]=>
  string(11) "Mon contenu"
  ["categorie"]=>
  string(7) "Journal"
  ["tags"]=>
  string(0) ""
  ["date"]=>
  string(10) "1431482024"
  ["date_modif"]=>
  string(10) "1431482024"
  ["commentaires"]=>
  string(1) "1"
  ["statut"]=>
  string(6) "publié"
  ["visible"]=>
  string(6) "public"
}

Du coup je ne comprend pas pourquoi tu veux convetir en tableau ?

Genki
Auteur

Pour m'éviter d'avoir ça dans mon fichier :

  $title = $articles->title;
  $content= $articles->content;
  $state = $articles->state ;
  $category = $articles->category;
  $comments = $articles->comments;
  $tags = $articles->tags;
  $visible = $articles->visible;
 // etc..
 // Et pouvoir ensuite appeler simplement un truc comme :
 echo $data['category']; // à la place de  $category = $articles->category;

Et pourquoi ne pas garder :

<?php 
echo $articles->category 

Tu peux aussi l'appeler où tu veux tant que tu n'écrases pas ta variable $articles, en plus tu y gagnes en performances (même si c'est peu)

Genki
Auteur

Mouais, j'y avais pas vraiment pensé vu que j'étais focalisé sur un tableau :p
Je voulais faire ça automatiquement, c'est pour ça. Avoir une seule variable, mais le paramètre serait le getter

Après si tu veux vraiment un tableau et sans getter :

Dans ton ta classe Entity tu rajoutes :

<?php
class Entity
{
// ...
    public function toArray()
    {
      return get_class_vars(get_class($this));
    }

// ...
}

puis après ton find() :

<?php 
$data = $article->toArray(); // au passage data ne prend pas de "s" c'est déjà au pluriel, et article non plus vu que c'est une entité

echo $data['titre']; // devrait afficher le titre :)
Genki
Auteur

L'idée est bonne mais ça ne fonctionne pas.

un VD de $data renvoit 0.
Il ne contient rien :/

Arf,

effectivement je n'avais pas pensé à l'héritage.
Mais si tu mets la méthode toArray() dans ArticlesEntity et non dans Entity ça fonctionne normalement. Tu confirmes ?

Je vais essayer de chercher une solution pour pouvoir le mettre dans la classe mère, ça va être plus lourd mais tu pourras l'utiliser pour toutes tes classes après.

Est-ce que ça fonctionne dans ArticlesEntity ?
Si non est-ce que ça fonctionne mieux avec ça (à mettre dans Entity) :

<?php
class Entity
{
// ...
    public function toArray()
    {
      return get_class_vars(get_called_class());
    }
// ...
}
Genki
Auteur

Ni dans l'une, ni dans l'autre, dans tous les cas, ça renvoit un tableau vide

bonjour
tu peux modifier ton script de connexion à la bdd de maniere à ce que tes requetes renvoient par defaut un tableau associatif

$connection = new PDO($connection_string);
//$connection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); 
$connection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); 

ou

$options = array(PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_ASSOC);
$connection = new PDO($connection_string, $options);

et le tour est joué

Salut, beaucoup de prise de tête pour pas grand chose...
Un cast suffit :

<?php $tableau = (array) $objet; ?>

Ou encore un extract()..
<?php extract($objet); ?> pour avoir les variables créées implicitement.

http://php.net/manual/fr/function.extract.php