Namespaces
Ik maak in een project veel gebruik van classes, die include ik allemaal in een index.php file. vanuit die file laad ik ook alle pagina's in waar ik vervolgens de functionaliteit van de classes kan gebruiken. Nu zei iemand dat Namepsaces veel handiger waren omdat je eigenlijk per file alleen moet inladen wat er nodig is. Waarom is het gebruik van Namepsace beter, ookal moet je nog steeds de class op dezelfde manier includen?
https://secure.php.net/manual/en/language.oop5.autoload.php ). Dan worden je classes "automagisch" geladen op het moment dat je ze nodig hebt (en dus *alleen* de classes die je nodig hebt). Met namespaces (wat sowieso wel handig is, om "ruzie" tussen twee verschillende classes met dezelfde naam te voorkomen) kun je dan eenvoudig je namespace structuur "op" je directory structuur leggen.
Maar dit kan ook prima zonder namespaces:
Ik denk dat ze doelen op "autoloading" ( Code (php)
1
2
3
4
5
6
2
3
4
5
6
<?php
include('autoload.php'); //stelt autoloader in, maar laadt nog geen classes
$x = new \Foo\Bar(); //class Bar in namespace Foo wordt automatisch geladen
//uit (bijvoorbeeld) {root}/Foo/Bar.php
?>
include('autoload.php'); //stelt autoloader in, maar laadt nog geen classes
$x = new \Foo\Bar(); //class Bar in namespace Foo wordt automatisch geladen
//uit (bijvoorbeeld) {root}/Foo/Bar.php
?>
Maar dit kan ook prima zonder namespaces:
Code (php)
1
2
3
4
5
6
2
3
4
5
6
<?php
include('autoload.php'); //stelt autoloader in, maar laadt nog geen classes
$x = new Foo_Bar(); //class Foo_Bar wordt automatisch geladen
//uit (bijvoorbeeld) {root}/Foo/Bar.php
?>
include('autoload.php'); //stelt autoloader in, maar laadt nog geen classes
$x = new Foo_Bar(); //class Foo_Bar wordt automatisch geladen
//uit (bijvoorbeeld) {root}/Foo/Bar.php
?>
Gewijzigd op 25/07/2018 17:36:10 door Rob Doemaarwat
mogelijke implementatie voor een autoloader (interne link), mogelijk heb je hier iets aan.
Ik had redelijk recent een reactie gegeven over een Toevoeging op 26/07/2018 14:58:35:
Thomas van den Heuvel op 25/07/2018 22:51:29:
Ik had redelijk recent een reactie gegeven over een mogelijke implementatie voor een autoloader (interne link), mogelijk heb je hier iets aan.
Ik ga het eventjes doorlezen, dankjewel!
Jorn Reed op 26/07/2018 14:57:52:
En dat autoload.php, dat heeft toch weer iets met vendor te maken? Waar je bijvoorbeeld phpmailer mee inlaad ofzo?
Hoeft niet, kan wel. Composer ( https://getcomposer.org/ ) levert bijvoorbeeld een autoload.php af, maar je kunt 'm ook zelf schrijven zoals in Thomas z'n voorbeeld. Ik had het hier gedaan om de details even "buiten beeld" te laten.
Rob Doemaarwat op 26/07/2018 17:03:26:
Hoeft niet, kan wel. Composer ( https://getcomposer.org/ ) levert bijvoorbeeld een autoload.php af, maar je kunt 'm ook zelf schrijven zoals in Thomas z'n voorbeeld. Ik had het hier gedaan om de details even "buiten beeld" te laten.
Jorn Reed op 26/07/2018 14:57:52:
En dat autoload.php, dat heeft toch weer iets met vendor te maken? Waar je bijvoorbeeld phpmailer mee inlaad ofzo?
Hoeft niet, kan wel. Composer ( https://getcomposer.org/ ) levert bijvoorbeeld een autoload.php af, maar je kunt 'm ook zelf schrijven zoals in Thomas z'n voorbeeld. Ik had het hier gedaan om de details even "buiten beeld" te laten.
En in die autoload include je dan bijvoorbeeld de classes die je gebruikt? Want stel ik gebruik een shoppingcart class. heb ik die alleen nodig op de winkelwagen pagina. En dus niet op bijvoorbeeld de hoofdpagina etc.
Dit voorkomt dat je altijd maar alle classes moet includen, voor die ene keer dat je 'm nodig hebt. Zeker bij grote projecten is dit uiteindelijk niet meer te doen.
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
$x = new \Foo\Bar();
//PHP ontdekt nu dat ie class \Foo\Bar nog niet kent.
//De autoloader krijgt dus een aanroep met als parameter 'Foo\Bar'
//De autoloader doet z'n ding, en laadt (bijvoorbeeld) bestand {root}/Foo/Bar.php
//(met daarin dus de definitie van class \Foo\Bar)
//\Foo\Bar is nu wel beschikbaar, en kan dus worden gebruikt om $x aan te maken.
//(als het bestand of de class alsnog niet bestaat, krijg je alsnog een Class "'Foo\Bar' not found")
//PHP ontdekt nu dat ie class \Foo\Bar nog niet kent.
//De autoloader krijgt dus een aanroep met als parameter 'Foo\Bar'
//De autoloader doet z'n ding, en laadt (bijvoorbeeld) bestand {root}/Foo/Bar.php
//(met daarin dus de definitie van class \Foo\Bar)
//\Foo\Bar is nu wel beschikbaar, en kan dus worden gebruikt om $x aan te maken.
//(als het bestand of de class alsnog niet bestaat, krijg je alsnog een Class "'Foo\Bar' not found")
De autoloader voor bovenstaand geval zou er dus als volgt uit kunnen zien (dit is dan dus autoload.php in mijn eerdere voorbeelden):
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
spl_autoload_register(function($class_name){
//$class_name bevat dus de gezochte class = 'Foo\Bar'
$root = '/waar/je/classes/staan/';
$filename = $root . str_replace('\\','/',$class_name) . '.php';
//$filename is nu dus '/waar/je/classes/staan/Foo/Bar.php'
//(let op hoofdletters; strtolower d'r omheen als je altijd lowercase filenames gebruikt)
//het bestand includen
require($filename);
});
?>
spl_autoload_register(function($class_name){
//$class_name bevat dus de gezochte class = 'Foo\Bar'
$root = '/waar/je/classes/staan/';
$filename = $root . str_replace('\\','/',$class_name) . '.php';
//$filename is nu dus '/waar/je/classes/staan/Foo/Bar.php'
//(let op hoofdletters; strtolower d'r omheen als je altijd lowercase filenames gebruikt)
//het bestand includen
require($filename);
});
?>
En deze functie wordt dus automatisch aangeroepen zodra je een (nog) onbekende class gebruikt.
Gewijzigd op 26/07/2018 19:08:47 door Rob Doemaarwat
Sidenote: wellicht is spl_autoload (een klein beetje) sneller dan require, en ook flexibeler. Het eerste kun je meten, het tweede hangt af van hoe flexibel je je code wilt opzetten. Als je bijvoorbeeld "class overrides" wilt maken van classes, zonder daarbij de bron aan te passen (denk aan (geversionde) libraries enzo) biedt spl_autoload mogelijk uitkomst, dit staat ook uitgelegd in de eerder gelinkte reactie.