2014-07-25 1 views
0

Je continue d'essayer de savoir quel est le problème avec ce script de chargeur de classe très simple. Le chargeur de classe ressemble à ceci:spl_autoload_register charge la classe deux fois

#src/vendors/Autoloading/lib/ClassLoader.php 

namespace App\Vendors\Autoloading; 

class ClassLoader 
{ 
    private $path; 

    function __construct($path) 
    { 
     $this->path   = $path; 
    } 

    public function load($class) 
    { 
     if(file_exists( $class = str_replace(array('\\', '_'), DIRECTORY_SEPARATOR, $this->path) . '.php')){ 
      require $class; 
      return true; 
     } 
    } 

    public function register() 
    { 
     return spl_autoload_register([$this, 'load']); 
    } 
} 

Le chargeur de classe initiale avait plus des méthodes et des fonctions pour valider les noms de fichiers ... mais, dans le processus de débogage je devais à cette étroite. Par conséquent, ce chargeur de classe est requis dans un fichier autoload.php, comme vous pouvez le voir ci-dessous.

#src/vendors/autoload.php 

namespace App\Vendors; 

require 'Autoloading/lib/ClassLoader.php'; 
$autoload = new Autoloading\ClassLoader('path/Foo/FooClass'); 
$autoload->register(); 

Le FooClass.php est situé dans src/Foo/FooClass.php

namespace App\Foo; 
class FooClass{} 

et il n'y a en réalité aucun problème avec la partie autoloading, la classe se charge très bien, mais il est fait deux fois qui me montre le dessous Erreur. Je l'appelle à partir d'un fichier index.php

<?php 

use \App\Foo\FooClass; 
FooClass::somefunction(); 

Juste en utilisant qui génère cette erreur.

Fatal error: Cannot redeclare class path\foo\FooClass in /path/to/index.php on line 4

Répondre

1

Votre fonction autoloading est erroné:

public function load($class) 
{ 
    if (
     file_exists( 
      $class = str_replace(
       array('\\', '_'), 
       DIRECTORY_SEPARATOR, 
       $this->path) 
      . '.php') 
    ) { 
     require $class; 
     return true; 
    } 
} 

La fonction est calles avec le nom du classe à charger (si impossible, la fonction ne devrait rien faire).

Ce que vous faites est ignorer le nom de la classe, et en créer un nouveau basé sur le chemin avec lequel l'autoloader est créé. Cela chargera toujours le même fichier, avec la même classe, même s'il y a différentes classes à charger. Cela explique pourquoi vous obtenez l'erreur, car quel que soit le nom de classe passé, vous incluez toujours le fichier associé au chemin.

Vous souhaitez probablement utiliser un autochargeur PSR-0 ou PSR-4 approprié. Je vous recommande d'utiliser celui qui accompagne Composer, car vous utiliserez probablement Composer tôt ou tard. Pourquoi ne pas commencer aujourd'hui?

+0

Merci, mais je reçois toujours la même erreur. Je dois faire quelque chose de mal. Pouvez-vous me montrer comment vous instanciez au moins le classLoader? –

+0

Qu'avez-vous changé? "Still" implique que vous avez changé quelque chose, et que "still" ne fonctionne pas. Vous êtes censé UTILISER la variable $ class, ajouter le chemin, convertir le nom de classe en un autre chemin, ajouter ".php" à la fin, et exiger ce fichier s'il existe. Ne changez pas $ class, créez un nouveau nom de fichier $. – Sven

+0

J'ai fait ceux qui me font confiance. Je ne suis pas à la traîne, j'ai juste passé des heures à essayer de comprendre cela. Je reçois le fichier 'can not redeclare class' –

1

Essayez d'utiliser require_once au lieu de require. Votre autochargeur ne gardera aucune trace des fichiers qui ont été chargés jusqu'à présent.

Voici comment je mets le mien. Je n'utilise pas de cours. Peut-être que cela vous aidera

function PlatformAutoloader($classname) { 
    try { 
     // Change \ to/so namespacing will work 
     $classname = strtolower(str_replace('\\', DIRECTORY_SEPARATOR, $classname)); 

     if([email protected]_once(DIR_CLASSES . DIRECTORY_SEPARATOR . $classname . '.php')) return false; 
    } catch(Exception $e) { 
     return false; 
    } 
} 
spl_autoload_register('PlatformAutoloader'); 
+0

L'autochargeur n'est pas censé être déclenché deux fois pour la même classe. – Sven

+0

Non. Cela n'a rien changé –

+0

Quel genre d'exception espérez-vous attraper? Y a-t-il une fonction interne à PHP qui appelle des exceptions? – Sven

1

Vérifiez si la classe existe déjà en utilisant class_exists avant de vérifier le fichier

+1

Si la classe existe déjà, l'autochargeur ne doit pas être déclenché deux fois, n'est-ce pas? – Sven

+0

@Mark Baker. C'est la toute première chose que j'ai faite. Je suis 100% c'est l'autoloading qui le charge deux fois –