Autoloader qui ne fonctionne pas

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Salut ! :-)

Je poste car j'ai un petit soucis et je n'arrive pas à le résoudre.

J'essaie de développer une petite appli php mais j'ai quelques soucis avec mon autoloader de classes.

J'ai une mon architecture comme ceci

Image utilisateur

Dans mon controller frontal j'ai ce code :

1
2
3
4
// /index.php
require('core/Autoloader.php');
Autoloader::registerAutoloader();
$db = new Database('localhost', 'php', 'root');

Ensuite dans mon Autoloader :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// /core/Autoload.php

<?php

class Autoloader
{
    public static function registerAutoloader()
    {
        spl_autoload_register([__CLASS__, 'autoloadCoreClass']);
    }

    private static function autoloadCoreClass($className)
    {
        var_dump($className);
        require(__DIR__ . DIRECTORY_SEPARATOR . $className . '.php');
    }
}

quand j'atterrie sur mon controller frontal, en voici l'erreur retourné :

1
2
3
4
5
6
<!-- /index.php -->

<!-- Le var_dump : -->
C:\wamp\www\php\core\Autoloader.php:12:string 'Database' (length=8)

Fatal error: Class 'Database' not found in C:\wamp\www\php\index.php on line 4

J'ai donc essayé d'aller require le fichier Database.php en considérant que je me situé dans index.php mais l'erreur persiste. (en rajoutant " 'core' . DIRECTORY_SEPARATOR " dans l'autoloader)

Ainsi je ne parviens pas à charger mes classes situé dans "core/"

Cependant en rajoutant un "use" avec le namespace correspondant dans index.php ela fonctionne, mais du coup si je dois faire cela à chaque nouvel appel d'une classe l'autoloader est quasiment inutile.

J'aimerais comprendre svp le problème qui se présente à moi. Cela fait maintenant 2 jours que je suis dessus.. Pas moyen de charger dynamiquement mes classes.

Si vous pouviez me mettre sur une piste ?

Merci et bonne soirée!

;-)

Édité par b.neb.19

+0 -0

Si utiliser use corrige le problème, c'est que ce n'est pas lié à l'auto-loader. Sans instruction use, il faut systématiquement appeler les classes avec leur espace de noms — l'instruction sert précisément à donner un alias qui évite de taper le préfixe du namespace.

Par exemple :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<?php
require('core/Autoloader.php');
Autoloader::registerAutoloader();

$db = new \Namespace\To\Database('localhost', 'php', 'root');  // OK
$db = new Database('localhost', 'php', 'root');                // Pas OK

use \Namespace\To\Database;

$db = new \Namespace\To\Database('localhost', 'php', 'root');  // OK
$db = new Database('localhost', 'php', 'root');                // OK

Par suite :

Cependant en rajoutant un "use" avec le namespace correspondant dans index.php cela fonctionne, mais du coup si je dois faire cela à chaque nouvel appel d'une classe l'autoloader est quasiment inutile.

…Pas vraiment, vu qu'utiliser use ne dispense pas d'inclure les fichiers contenant les classes. De plus, je crois voir que vous utilisez un IDE pour développer, et la plupart des IDE récents permettent d'ajouter automatiquement les instructions use nécessaires.


Au passage, saviez-vous que Composer peut se charger tout seul de l'auto-chargement, y compris des classes de votre projet, si tant est que vous suivez les (simples) conventions en vigueur ?

Édité par AmauryPi

+0 -0
Auteur du sujet

Merci pour ta répons :) !

Oui je m'étais renseigné sur l'autoloader de composer. J'ai donc appliqué la norme "psr-0" dans mon fichier composer.json. Mais pour le coup, mes classes situées dans "core/" ne respecte pas la norme. J'ai donc voulu créer mon autoloader.

J'ai pu suivre le tutoriel de Grafikart concernant l'autoloading (https://www.grafikart.fr/formations/programmation-objet-php/autoload) . Sauf erreur de ma part, il me semble que son code est quasiment similaire au moins, mais pour lui cela fonctionne. J'ai donc voulu demandé de l'aide pour que je puisse avancer.

Du coup, il serait bon dans mon Autoloader.php de faire un require avec le namespace de mes classes ? En procédant ainsi, je dois donc suivre à la lettre les noms de mes dossiers?

Merci encore pour ta réponse :).

Édité par b.neb.19

+0 -0
Auteur du sujet

Up

Mon autoloader dans core/ de fonctionne pas depuis.

Impossible de charger les fichiers qui sont situé au même endroit ( /core/ ) quand je les appels depuis /index.php

pour situé les choses :

  • ROOT / core/ Autoload.php Database.php

  • ROOT / index.php

Voici core/Autoloader.php :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

namespace Doc\Core;


class Autoloader
{

    public static function registerAutoload()
    {
        spl_autoload_register(array(__CLASS__, 'autoloadCoreClass'));
    }

    public static function autoloadCoreClass($className)
    {
        $filename = explode('\\', $className);
        $filename = end($filename) . '.php';
        if( is_readable($filename) ) {
            require "$filename";
        }
    }
}

Et voici /index.php :

1
2
3
4
5
6
<?php

require 'core/Autoloader.php';
Autoloader::registerAutoload();

new \Doc\Core\Database();

quand je me rend avec le navigateur sur /index.php, j'ai toujours cette erreur :

1
Fatal error: Class 'Doc\Core\Database' not found in C:\wamp\www\doc\index.php on line 6

Je n'arrive pas à comprendre pourquoi, je ne sais résoudre le problème. je fouille pourtant sur le net et cette méthode devrait pouvoir marcher correctement ..

Merci pour votre aide.

+0 -0

Vire l'appel à is_readable, peut-être que tu comprendras mieux.

EDIT: d'ailleurs cet appel est stupide ; une erreur dans le code doit faire l'objet d'une correction, pas être masquée silencieusement.

Accessoirement pourquoi require "$filename"; et pas require $filename; ?

Édité par MatTheCat

+0 -0

Commence par afficher $filename, il ne contient peut-être pas ce à quoi tu t'attends. Ensuite affiche le dossier courant.

Bref, c'est vraisemblablement un problème d'accès ou une erreur de chemin.

Quelque chose me choque à priori, tu vires les composants non terminaux du namespace. C'est voulu ? Parce qu'habituellement, 1 namespace = 1 sous-répertoire.

Édité par QuentinC

Ma plateforme avec 23 jeux de société classiques en 6 langues et 13000 joueurs: http://qcsalon.net/ | Apprenez à faire des sites web accessibles http://www.openweb.eu.org/

+0 -0
Auteur du sujet

Merci pour vos réponses.

J'ai solutionné le problème en mettant le path en absolue vers le fichier. J'ai mis require "$filename" car mon IDE me disait qu'il était mieux d'analyser la variable.

+0 -0

J'ai solutionné le problème en mettant le path en absolue vers le fichier.

Les chemins absolus, c'est le mal. Ca foirera à chaque fois que tu changeras d'environnement. DAns 5 ans quand tu changeras d'hébergement, tu seras content de ne pas comprendre pourquoi ça ne marche plus et de ne pas voir rapidement où est le problème ! Je suis d'avis que tu devrais éviter et que tu as sûrement effectivement un moyen.

Ma plateforme avec 23 jeux de société classiques en 6 langues et 13000 joueurs: http://qcsalon.net/ | Apprenez à faire des sites web accessibles http://www.openweb.eu.org/

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte