autoloading psr-0 psr-4
Twee vraagjes...
1) Bij een psr-4 autoloader kun je een namespace en een directory toevoegen. Bijv. setNamespace('foo', 'path/to/foo'). Begrijp ik goed dat je aan een psr-0 autoloader alleen maar een pad toevoegt, zonder een namespace?
2) Stel een library laadt volgens het psr-0 autoloading principe, en de top-level namespace van die library is 'foo'. Kun je diezelfde library dan ook laden met een psr-4 autoloader, door dit te doen:
setNamespace('foo', 'path/to/foo') ?
1) ja
2) ja
Oké, thanks Dos.
Dus stel we doen $aPsr0Autoloader->registerNamespace('Ozzie\\Cms', 'src/'); en vragen de Ozzie\Cms\Admin\AdminService interface op, dan wordt deze geladen uit src/Ozzie/Cms/Admin/AdminService.php
Als we echter $aPsr4Autoloader->registerNamespace('Ozzie\\Cms\\', 'src/'); doen dan wordt deze geladen uit src/Admin/AdminService.php.
Op deze manier kun je dus nutteloze mappen verwijderen, die alleen mappen hebben. Dan krijg je bijv. iets als:
Code (php)
1
2
3
4
5
6
2
3
4
5
6
<?php
$psr4Autoloader->registerNamespace(array(
'Ozzie\\Cms' => 'vendor/ozzie-cms',
'Ozzie\\Framework\\' => 'vendor/ozzie-framework',
));
?>
$psr4Autoloader->registerNamespace(array(
'Ozzie\\Cms' => 'vendor/ozzie-cms',
'Ozzie\\Framework\\' => 'vendor/ozzie-framework',
));
?>
En dan kun je klassen als Ozzie\Cms\Admin\AdminService in vendor/ozzie-cms/Admin/AdminService.php vinden en Ozzie\Framework\Routing\Router in vendor/ozzie-framework/Routing/Router.php
Dus ja, deze configuratie is hetzelfde:
Code (php)
1
2
3
4
2
3
4
<?php
$psr0Autoloader->registerNamespace('Ozzie\\Cms', 'vendor/ozzie-cms');
$psr4Autoloader->registerNamespace('Ozzie\\Cms\\', 'vendor/ozzie-cms/Ozzie/Cms');
?>
$psr0Autoloader->registerNamespace('Ozzie\\Cms', 'vendor/ozzie-cms');
$psr4Autoloader->registerNamespace('Ozzie\\Cms\\', 'vendor/ozzie-cms/Ozzie/Cms');
?>
Merk overigens op dat PSR-4 een successor van PSR-0 is, het is een vervanger. PSR-0 is nu dus "deprecated".
Gewijzigd op 07/05/2014 22:37:25 door Wouter J
$prs0Autoloader->setPath('library');
En dat dan \foo\bar zou geladen worden worden via 'library/foo/bar.php' maar dat heb ik dus verkeerd begrepen.
>> Merk overigens op dat PSR-4 een successor van PSR-0 is, het is een vervanger. PSR-0 is nu dus "deprecated".
Oké... dus als er een library is die met PSR-0 werkt, dan kun je die gewoon prima autoloaden via een PSR-4 autoloader. Correct?
Code (php)
1
2
3
4
2
3
4
<?php
$psr0Autoloader->registerNamespace('Ozzie\\Cms', 'vendor/ozzie-cms');
$psr4Autoloader->registerNamespace('Ozzie\\Cms\\', 'vendor/ozzie-cms/Ozzie/Cms');
?>
$psr0Autoloader->registerNamespace('Ozzie\\Cms', 'vendor/ozzie-cms');
$psr4Autoloader->registerNamespace('Ozzie\\Cms\\', 'vendor/ozzie-cms/Ozzie/Cms');
?>
Waarom zet je bij de psr-4 autoloader een slach achter de namespace en bij de psr-0 autoloader niet?
"Er zit maar 1 verschil tussen PSR-0 en PSR-4: In PSR-4 wordt de namespace niet opgenomen in het path, in PSR-0 wel."
Er is nog een verschil:
- PSR-0 zegt "Each _ character in the CLASS NAME is converted to a DIRECTORY_SEPARATOR. The _ character has no special meaning in the namespace."
- PSR-4 zegt "Underscores have no special meaning in any portion of the fully qualified class name."
Hieruit volgt dat het antwoord op de vraag
"Oké... dus als er een library is die met PSR-0 werkt, dan kun je die gewoon prima autoloaden via een PSR-4 autoloader. Correct?"
nee is. Niet 100% van de gevallen in elk geval. Doe het dus ook niet.
PS. "In PSR-4 wordt de namespace prefix niet opgenomen in het path, in PSR-0 is er geen prefix die je weg kunt laten." misschien ietsjes duidelijker?
Gewijzigd op 07/05/2014 23:32:59 door Dos Moonen
Maar wel vreemd... waarom heb ik dat dan ooit erin gebouwd vraag ik me af. Verkeerd gekeken bij de specs van psr-0? Vreemd...
>> PS. "In PSR-4 wordt de namespace prefix niet opgenomen in het path, in PSR-0 is er geen prefix die je weg kunt laten." misschien ietsjes duidelijker?
"In PSR-4 wordt de namespace prefix niet opgenomen in het path"
Dit is duidelijk.
"in PSR-0 is er geen prefix die je weg kunt laten."
Dit is me niet duidelijk. :-s
Heb je een voorbeeldje?
Je geeft een path op.
De autoloader vervangt alle namespace separators en underscores in de class name door DIRECTORY_SEPARATOR.
Vervolgent plakt de autoloader het achter het path en probeert het dat .php bestand te laden.
PSR-4:
Je geeft een path en namespace prefix op.
De autoloader returned als de FQN niet begint met de namespace prefix.
De autoloader haalt de prefix van de FQN af.
De autoloader vervangt in het restant alle namespace separators door DIRECTORY_SEPARATOR.
Vervolgent plakt de autoloader het achter het path en probeert het dat .php bestand te laden.
Gewijzigd op 08/05/2014 09:23:11 door Dos Moonen
Wouter koppelt bij de PSR-0 autoloader wél een namespace aan het pad. Dat klopt dan dus niet?
>> De autoloader returned als de FQN niet begint met de namespace prefix.
Als ie niet returnet, maar simpelweg niks doet, dan is het toch ook goed? Komt op hetzelfde neer neem ik aan?
Dan heeft hij toen hij dat schreef, net als ik toen mijn eerste post in dit topic schreef, PSR-0 en PSR-4 niet recent nog eens doorgenomen had.
"Als ie niet returnet, maar simpelweg niks doet, dan is het toch ook goed? Komt op hetzelfde neer neem ik aan?"
Ja, persoonlijk ben ik het liefst zo snel mogelijk uit een functie/methode. Maar er is ook de single point of exit gedachten gang die handig is bij talen waar je zelf memory management moet uitvoeren. PHP doet dat voor je, dus return ik het liefst zo snel mogelijk.
Wat ik bedoel is... je kunt dit doen (wat jij waarschijnlijk doet)
Maar je kunt ook dit doen (zoals ik het doe)
Jij returnt dus als niet aan de voorwaarde wordt voldaan. Ik doe alleen iets als wél aan de voorwaarde wordt voldaan en return nooit iets. Vooral een kwestie van persoonlijke voorkeur?
Ja.
Toevoeging op 08/05/2014 14:30:21:
Toch nog even een vraag...
Je kan dan toch ook een psr-0 loader maken waar je wel een namespace aan kan toevoegen?
Dus stel je hebt een PDF library volgens psr-0. Dan zou (correct me if I'm wrong) toch iedere class-naam met dezelfde namespace moeten beginnen? Bijv. PDF? Dan zou ik toch ook een eigen psr-0 autoloader kunnen maken waarbij bijv. de top level namespace verwijst naar de library? Of werkt dat niet?