Partage
  • Partager sur Facebook
  • Partager sur Twitter

[code SOLID] D : Dependency Inversion

Uncaught Error: Call to undefined function

Sujet résolu
    16 septembre 2019 à 12:35:29

    Bonjour, 

    J'ai une erreur que je n'arrive pas à comprendre, je ne comprends pas pourquoi la fonction d'une classe est "undefined" quand je l'appelle alors que, pour moi, elle existe puisque définie dans la classe....

    Pour info, Mon code est celui d'un site internet (https://github.com/OpenClassrooms-Student-Center/learn-solid-php-code) que je dois améliorer pour appliquer le principe "Dependency Inversion", dans le cadre du cours https://openclassrooms.com/fr/courses/6031956-creez-une-application-web-en-php-de-qualite-professionnelle/6107791-d-comme-dependency-inversion-principle

    Voici mon code :

    • \src\Classes\Tools\DatabaseInterface.php
    <?php
    
    namespace App\Classes\Tools;
    
    interface DatabaseInterface
    {
    	public static function getInstance();
    
    	public function getConnexion();
    }
    • src\Classes\Tools\Database.php

    <?php
    
    namespace App\Classes\Tools;
    
    use App\Classes\Tools\DatabaseInterface;
    use PDO;
    
    class Database implements DatabaseInterface
    {
        private static $instance = false;
    
        protected $connexion;
    
        private function __construct()
        {
            $this->connexion = new PDO(PDO_DSN, USER, PASSWD);
            $this->connexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }
    
        private function __clone()
        {
        }
    
        public static function getInstance()
        {
            if (self::$instance === false) {
                self::$instance = new self();
            }
    
            return self::$instance;
        }
    
        public function getConnexion()
        {
            return $this->connexion;
        }
    }
    • \src\Classes\Album\Repository.php
     
    <?php
    
    namespace App\Classes\Album;
    
    use App\Classes\Tools\DatabaseInterface;
    use App\Classes\Music\Music;
    use PDO;
    
    class Repository
    {
        private $database;
    
        public function __construct(DatabaseInterface $database)
        {
            $this->database = $database;
        }
    
        public static function read($id)
        {
            $db = $this->database::getInstance()->getConnexion();
            $sth = $db->prepare('SELECT * FROM albums WHERE id=:id');
    
            $data = array('id' => $id);
            $sth->execute($data);
            $line = $sth->fetch(PDO::FETCH_ASSOC);
    
            return Album::initialize($line);
        }
    
        public static function getPlayList($id)
        {
            $db = $this->database::getInstance()->getConnexion();
    
            $sth = $db->prepare('SELECT * FROM songs WHERE id_album=:id_album');
    
            $data = array('id_album' => $id);
    
            $sth->execute($data);
    
            $lignes = $sth->fetchAll(PDO::FETCH_ASSOC);
            $musiques = array();
            foreach ($lignes as $ligne) {
                $musiques[] = Music::initialize($ligne);
            }
    
            return $musiques;
        }
    
        public static function new(Album $album)
        {
            $db = $this->database::getInstance()->getConnexion();
            $sth = $db->prepare('insert into albums set id=:id,title=:title, author=:author, file=:file, created_at=:created_at');
    
            $sth->execute([
                'id' => $album->getId(),
                'title' => $album->getTitle(),
                'author' => $album->getAuthor(),
                'created_at' => $album->getCreatedAt(),
                'file' => $album->getFile(),
            ]);
        }
    
        public static function update(Album $album)
        {
            $db = $this->database::getInstance()->getConnexion();
    
            $sth = $db->prepare('update albums set title=:title, author=:author, file=:file where id =:id');
    
            $sth->execute([
                'id' => $album->getId(),
                'title' => $album->getTitle(),
                'author' => $album->getAuthor(),
                'file' => $album->getFile(),
            ]);
        }
    
        public static function delete(Album $album)
        {
            $db = $this->database::getInstance()->getConnexion();
            $sth = $db->prepare('delete from albums where id=:id');
    
            $sth->execute(['id' => $album->getId()]);
        }
    
        public static function getListAlbums($limit)
        {
            $db = $this->database::getInstance()->getConnexion();
    
            $sth = $db->query("SELECT * FROM albums LIMIT $limit");
    
            $rawAlbums = $sth->fetchAll(PDO::FETCH_ASSOC);
            $albums = [];
            foreach ($rawAlbums as $rawAlbum) {
                $albums[] = Album::initialize($rawAlbum);
            }
    
            return $albums;
        }
    
        public static function getAllAlbums()
        {
            $db = $this->database::getInstance()->getConnexion();
    
            $sth = $db->query('SELECT * FROM albums');
    
            $rawAlbums = $sth->fetchAll(PDO::FETCH_ASSOC);
            $albums = [];
            foreach ($rawAlbums as $rawAlbum) {
                $albums[] = Album::initialize($rawAlbum);
            }
    
            return $albums;
        }
    }
    
    • src/public/index.php
     
    <?php
    
    require_once '../config/config.php';
    require_once '../config/config_db.php';
    require_once '../vendor/autoload.php';
    
    use App\Classes\Album\Repository as AlbumRepository;
    use App\Classes\Album\Collection as AlbumCollection;
    use App\Controllers\PublicController;
    use App\Classes\Tools\View;
    use App\Classes\Album\Ui as AlbumUi;
    use App\Classes\Music\Ui as MusicUi;
    
    use App\Classes\Tools\Database;
    
    // initialisation des variables
    $title = '';
    $c = '';
    $header = file_get_contents('../ui/fragments/header.frg.html');
    $footer = file_get_contents('../ui/fragments/footer.frg.html');
    $skeleton = '../ui/pages/galerie.html.php';
    $controller = new PublicController();
    $database = Database::getInstance();
    
    try {
        $getRequest = $_GET;
        $action = isset($getRequest['a']) ? $getRequest['a'] : '';
    
        switch ($action) {
            case 'ecouter':
                $title = "Ecoute de l'album";
                if (isset($getRequest['id'])) {
                    $albumId = $getRequest['id'];
                    $ListOfMusics = AlbumRepository($database)::getPlayList($albumId);
                    if (count($ListOfMusics) == 0) {
                        $c = 'Album vide, Ajoutez des pistes';
                    } else {
                        $i = 0;
                        foreach ($ListOfMusics as $Music) {
                            $ui = MusicUi::factory($Music);
                            if ($i < 1) {
                                $c = '<section id="album_view" class="span6">' . $ui->makePlayer();
                                $c .= '<ol>';
    
                                $c .= '<li class="playing">' . $ui->makeHtml() . '</li>';
                                $i = 1;
                            } else {
                                $c .= '<li>' . $ui->makeHtml() . '</li>';
                            }
                        }
                        $c .= '</ol></section>';
                    }
    
                    $album = AlbumRepository($database)::read($albumId);
                    $albumUi = new AlbumUi($album);
                    $c .= $albumUi->displayAlbumInfos();
                }
                break;
    
            case 'aide':
                return View::sendHttpResponse($controller->help());
                break;
    
            default:
                $title = 'Les derniers Albums enregistrés';
                $selectionOfAlbums = AlbumRepository($database)::getListAlbums(20);
                $selectionOfAlbums = new AlbumCollection($selectionOfAlbums);
                $c = $selectionOfAlbums->viewHtml();
    
                $allAlbums = AlbumRepository($database)::getAllAlbums();
                $allAlbums = new AlbumCollection($allAlbums);
                $c .= $allAlbums->viewTable();
        }
    } catch (Exception $e) {
        $c = $e->getMessage();
        $c .= "<pre>{$e->getTraceAsString()}</pre>";
    }
    
    ob_start();
      require_once $skeleton;
      $html = ob_get_contents();
    ob_end_clean();
    echo $html;
    

    La ligne 66 dans index.php est : $selectionOfAlbums = AlbumRepository($database)::getListAlbums(20);

    Je ne comprends pas pourquoi la méthode getListAlbum() de la classe Repository (renommée "AlbumRepository" dans index.php) n'est pas reconnue...

    Est-ce une erreur de syntaxe ?

    Merci pour votre aide.


    • Partager sur Facebook
    • Partager sur Twitter
      16 septembre 2019 à 13:07:27

      Salut,

      AlbumRepository est un alias de Repository, il faut faire new AlbumRepository($db) pûis ensuite utiliser l'objet créé et appeler la méthode.

      => manque de base OO

      -
      Edité par christouphe 16 septembre 2019 à 13:08:28

      • Partager sur Facebook
      • Partager sur Twitter
        16 septembre 2019 à 15:25:30

        Merci Christouphe :),

        Malheureusement, je continue de bloquer... 

        Voici mon index.php modifié (en espérant avoir bien compris les propos de Christouphe :

        <?php
        
        require_once '../config/config.php';
        require_once '../config/config_db.php';
        require_once '../vendor/autoload.php';
        
        use App\Classes\Album\Repository as AlbumRepository;
        use App\Classes\Album\Collection as AlbumCollection;
        use App\Controllers\PublicController;
        use App\Classes\Tools\View;
        use App\Classes\Album\Ui as AlbumUi;
        use App\Classes\Music\Ui as MusicUi;
        
        use App\Classes\Tools\Database;
        
        // initialisation des variables
        $title = '';
        $c = '';
        $header = file_get_contents('../ui/fragments/header.frg.html');
        $footer = file_get_contents('../ui/fragments/footer.frg.html');
        $skeleton = '../ui/pages/galerie.html.php';
        $controller = new PublicController();
        $database = Database::getInstance();
        $albumRepository = new AlbumRepository($database);
        
        try {
            $getRequest = $_GET;
            $action = isset($getRequest['a']) ? $getRequest['a'] : '';
        
            switch ($action) {
                case 'ecouter':
                    $title = "Ecoute de l'album";
                    if (isset($getRequest['id'])) {
                        $albumId = $getRequest['id'];
                        $ListOfMusics = $albumRepository::getPlayList($albumId);
                        if (count($ListOfMusics) == 0) {
                            $c = 'Album vide, Ajoutez des pistes';
                        } else {
                            $i = 0;
                            foreach ($ListOfMusics as $Music) {
                                $ui = MusicUi::factory($Music);
                                if ($i < 1) {
                                    $c = '<section id="album_view" class="span6">' . $ui->makePlayer();
                                    $c .= '<ol>';
        
                                    $c .= '<li class="playing">' . $ui->makeHtml() . '</li>';
                                    $i = 1;
                                } else {
                                    $c .= '<li>' . $ui->makeHtml() . '</li>';
                                }
                            }
                            $c .= '</ol></section>';
                        }
        
                        $album = $albumRepository::read($albumId);
                        $albumUi = new AlbumUi($album);
                        $c .= $albumUi->displayAlbumInfos();
                    }
                    break;
        
                case 'aide':
                    return View::sendHttpResponse($controller->help());
                    break;
        
                default:
                    $title = 'Les derniers Albums enregistrés';
                    $selectionOfAlbums = $albumRepository::getListAlbums(20);
                    $selectionOfAlbums = new AlbumCollection($selectionOfAlbums);
                    $c = $selectionOfAlbums->viewHtml();
        
                    $allAlbums = $albumRepository::getAllAlbums();
                    $allAlbums = new AlbumCollection($allAlbums);
                    $c .= $allAlbums->viewTable();
            }
        } catch (Exception $e) {
            $c = $e->getMessage();
            $c .= "<pre>{$e->getTraceAsString()}</pre>";
        }
        
        ob_start();
          require_once $skeleton;
          $html = ob_get_contents();
        ob_end_clean();
        echo $html;
        

        Effectivement, cela a résolu l'erreur de "function undefined" dans l'index.php.

        Désormais,  une erreur est déclenchée dans la méthode que je n'arrivais à appeler en premier lieu : getListAlbum() du Repository  : 

        Il y a donc un problème avec la ligne 

                $db = $this->database::getInstance()->getConnexion();
        

        de la classe src/Classes/Album/Repository.php

        Mais je sèche encore, surtout que la syntaxe $this->database::getInstance()->getConnexion() est explicitement demandée d'être utilisée dans les consignes de  l'exercice.... https://openclassrooms.com/fr/courses/6031956-creez-une-application-web-en-php-de-qualite-professionnelle/6107791-d-comme-dependency-inversion-principle

        Une idée s'il-vous-plait ?

        • Partager sur Facebook
        • Partager sur Twitter
          16 septembre 2019 à 15:43:40

          tu es sur un conexte statique dans Repository, donc c'est plutôt self::database::getInstance()-<getConnexion();

          Ta classe devrait être abstract

          -
          Edité par christouphe 16 septembre 2019 à 15:46:13

          • Partager sur Facebook
          • Partager sur Twitter
            16 septembre 2019 à 15:56:05

            AH ben merci, c'est bien ce que je pensais ... conclusion, je laisse tomber, marre de bosser sur des bases faussées. Merci beaucoup pour ton aide Christouphe :)

            • Partager sur Facebook
            • Partager sur Twitter

            [code SOLID] D : Dependency Inversion

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown