Autoloading met namespaces

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Mark Hogeveen

Mark Hogeveen

08/04/2014 17:22:50
Quote Anchor link
Hallo ik heb een probleem dat moeilijk te omschrijven is.

Ik heb een index pagina in de public map. Waarop dus autoloading is enz.
Hier is de code van mijn autoloader:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
// In config/config.php staat de volgende regel:
define('BASE_PATH', $_SERVER['DOCUMENT_ROOT']);

// De autoloader:
function autoloader($class) {
    
    $namespace = str_replace('\\', DIRSEP, $class);
    $path = BASE_PATH . DIRSEP . $namespace . ".php";
    
    //echo $path . "<hr>";
    require_once($path);
}
spl_autoload_register("autoloader");


Ik heb bijvoorbeeld een bestand dat op de volgende locatie staat: BASE_PATH/library/Routing/Exception/RouteNotFoundException.php
En het heeft de namespace library/Routing/Exception
Dan werkt de autoloader niet. Als ik een exception gooi:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
throw new library/Routing/Exception/RouteNotFoundException("Route not found");


De error die ik krijg is:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
[08-Apr-2014 10:50:41] PHP Fatal error:  require_once(): Failed opening required '/var/lib/stickshift/5332555ce0b8cd545800016c/app-root/data/751740/library/Routing/Exception.php' (include_path='.:/usr/share/pear:/usr/share/php') in /var/lib/stickshift/5332555ce0b8cd545800016c/app-root/data/751740/web/index.php on line 18


Ik begrijp niet hoe php komt bij die locatie /var/lib/stickshift/5332555ce0b8cd545800016c/app-root/data/751740/library/Routing/Exception.php
Er is helemaal nergens een bestand dat Exception.php heet. Dit soort errors krijg ik alleen bij exceptions gooien, anders werkt het altijd.
Het bestand dat de autoloader zou moeten includen is BASE_PATH/library/Routing/Exception/RouteNotFoundException.php
De klasse RouteNotFoundException die in dat bestand staat doet wel Exception extenden (de ingebouwde exception class van PHP).
Gewijzigd op 08/04/2014 17:24:46 door Mark Hogeveen
 
PHP hulp

PHP hulp

20/04/2024 11:09:14
 
Wouter J

Wouter J

08/04/2014 17:24:43
Quote Anchor link
Voor namespaces gebruik je \ en niet /. Gebruik trouwens liever use statements in je code en als je dat niet doet, gebruik dan op zijn minst een FQCN (dus met de \ ervoor).

Als laatst wil ik je aanraden om altijd als eerste namespace element een vendornaam (jouw naam bijv.) te plaatsen.
 
Mark Hogeveen

Mark Hogeveen

08/04/2014 17:26:24
Quote Anchor link
Ah best wel goed dat het dan toch nog gedeeltelijk werkte.

toevoeging:
De namespaces die ik zelf definieer zijn al met backslashes (\)
Dus: namespace library\Routing\Exception



Toevoeging op 08/04/2014 17:37:08:

Ik weet wel ongeveer waar het probleem zit.
Het gaat erom hoe ik mijn exception instantieer.

Als ik dit doe, dan wordt het include pad: /var/lib/stickshift/5332555ce0b8cd545800016c/app-root/data/751740/library/Routing/library/Routing/RouteNotFoundException.php
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
throw new library\Routing\RouteNotFoundException("Route not found");

Dan is het weer dubbel dus.
Gewijzigd op 08/04/2014 17:38:17 door Mark Hogeveen
 
Frank Nietbelangrijk

Frank Nietbelangrijk

08/04/2014 18:17:39
Quote Anchor link
Waarom pak je niet direct de PSR-0 standaard?

https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
 
Ward van der Put
Moderator

Ward van der Put

08/04/2014 18:36:50
Quote Anchor link
Harry hogeveen op 08/04/2014 17:22:50:
Ik begrijp niet hoe php komt bij die locatie /var/lib/stickshift/5332555ce0b8cd545800016c/app-root/data/751740/library/Routing/Exception.php
Er is helemaal nergens een bestand dat Exception.php heet. Dit soort errors krijg ik alleen bij exceptions gooien, anders werkt het altijd.

Een Exception is ook een klasse. Een ingebouwde klasse zelfs.

Zodra je in de namespace Foo een throw new Exception gebruikt, gaat een autoloader op zoek naar bijvoorbeeld Foo\Exception via het pad library/Foo/Exception.php.

Je kunt dit omzeilen door \ toe te voegen voor de standaardklassen van PHP zelf, bijvoorbeeld throw new \Exception(...).
 
Mark Hogeveen

Mark Hogeveen

08/04/2014 19:09:39
Quote Anchor link
Dat is volgens mij het probleem!
Wat ik doe is throw new RouteNotFoundException();
en die extend de ingebouwde Exception klasse van php.
Een \ toevoegen voor de klasnaam bij het instantieren kan dus niet bij de ingebouwde klasse, dan zou die \ dus voor RouteNotFoundException(); moeten komen. Of is het ook opgelost als ik een \ voor Exception zet als ik hem extend, dus dan krijg je dit: class RouteNotFoundException extends \Exception { }
Gewijzigd op 08/04/2014 19:11:10 door Mark Hogeveen
 
Frank Nietbelangrijk

Frank Nietbelangrijk

08/04/2014 19:36:29
Quote Anchor link
Harry hogeveen op 08/04/2014 19:09:39:
Dat is volgens mij het probleem!
Wat ik doe is throw new RouteNotFoundException();
en die extend de ingebouwde Exception klasse van php.
Een \ toevoegen voor de klasnaam bij het instantieren kan dus niet bij de ingebouwde klasse, dan zou die \ dus voor RouteNotFoundException(); moeten komen. Of is het ook opgelost als ik een \ voor Exception zet als ik hem extend, dus dan krijg je dit: class RouteNotFoundException extends \Exception { }



Sh*t daar had ik niet aan gedacht omdat je die Exeption class met de volledige namespace aanriep. Maar inderdaad: gewoon extends \Exception

en dus inderdaad onthouden alle classen (ook van PHP) uit de global scope met een \ zoals \Mysqli en \DateTime etc.
Gewijzigd op 08/04/2014 19:38:41 door Frank Nietbelangrijk
 
Ward van der Put
Moderator

Ward van der Put

08/04/2014 19:37:37
Quote Anchor link
Die laatste inderdaad: class RouteNotFoundException extends \Exception { }
 
Mark Hogeveen

Mark Hogeveen

08/04/2014 19:37:57
Quote Anchor link
Oh dankje.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.