Ik probeer eigen classes d.m.v. composer te autoloaden. Hiervoor heb ik een directory genaamd app/custom/myclass.php in de class heb ik de volgende namespace
<?php
namespace custom;
?>
Nu heb ik in de composer.json het volgende
"autoload": {
"psr-4": {
"custom\\": "app/"
}
}
wanneer ik een composer.update uitvoer krijg ik helaas de melding dat de class niet bestaat. Wat doe ik hier fout?
Je moet het zo zien... stel je wilt een namespace "Reshad\CustomPackage" gebruiken, dan kun je met psr-4 zorgen dat je die prefix vanuit welke map dan ook kunt gebruiken.
dus stel dit is je mappen-structuur:
Lijkt me niet echt efficiënt om dezelfde namespace naar 2 verschillende mappen te laten verwijzen eerlijk gezegd.
[size=xsmall]Toevoeging op 27/06/2014 00:40:59:[/size]
Reshad, ik zou eerst een directorystructuur maken, die jij zelf prettig en overzichtelijk vindt. Daarna zou ik me gaan bezighouden met het autoloaden. Je bent vrij om het te doen zoals je het zelf fijn vindt.
Lijkt me niet echt efficiënt om dezelfde namespace naar 2 verschillende mappen te laten verwijzen eerlijk gezegd.
Dit is juist de kracht van psr-4, zodat je je mappen kan indelen zoals je wilt.
Zonder dat je je hoeft te houden aan een bepaalde mappen stuctuur.
Anders kun je net zo goed psr-0 gebruiken.
---------
Ik ga er even vanuit dat je het zo wilt dan:
`-- app
| `-- JsonFetcher.php
Het maakt eigenlijk niet uit wat je namespace is, als je het ook maar goed in je JsonFetcher.php declareert.
Je zou nu dit kunnen hebben:
>> Dit is juist de kracht van psr-4, zodat je je mappen kan indelen zoals je wilt.
Zonder dat je je hoeft te houden aan een bepaalde mappen stuctuur.
Dat kan toch nog steeds? Het lijkt me handiger om dan een Test namespace te maken. Je koppelt nu 1 namespace aan 2 folders. Stel dat de classes 50/50 verdeeld zijn dan betekent het dat je in 50% van de gevallen een onnodige controle uitvoert.
Je kunt dan beter een aparte Reshad\Test namespace aanmaken die naar de test-map verwijst.
[size=xsmall]Toevoeging op 27/06/2014 00:54:24:[/size]
Reshad, je hebt verschillende type autoloaders die op een bepaalde manier autoloaden. PSR-0 en PSR-4 zijn de bekendste. Maar je kunt ook zelf een autloader maken.
Het principe is dat als een class nog niet geladen is (via require) de naam van die class naar de autoloader wordt gestuurd. Op basis van die naam, en op basis van de namespaces die jij hebt ingesteld, wordt de class geladen.
Heel simpel... even de basis-gedachte. Je hebt een class Foo(). Die zet jij in het mapje "Reshad". Vervolgens zeg je tegen de autoloader: stel de namespace Reshad in op het pad "Reshad".
Vervolgens doe jij:
$foo = new Reshad\Foo();
De autoloader ziet nu de namespace "Reshad". Aha! Bij deze namespace hoort de map "Reshad". Blijkbaar moet ik dus het bestand "Reshad/Foo.php" requiren.
[size=xsmall]Toevoeging op 27/06/2014 02:23:30:[/size]
Ozzie PHP op 27/06/2014 00:49:28
Dat kan toch nog steeds? Het lijkt me handiger om dan een Test namespace te maken. Je koppelt nu 1 namespace aan 2 folders. Stel dat de classes 50/50 verdeeld zijn dan betekent het dat je in 50% van de gevallen een onnodige controle uitvoert.
Je kunt dan beter een aparte Reshad\Test namespace aanmaken die naar de test-map verwijst.
Ik bewaar liever mijn unit tests in een aparte map indien mogelijk.
En qua performance maakt het niks uit, zolang je maar
composer dump-autoload -o
uitvoerd.
Overigens zou ik op deze manier in een production omgeving mijn tests nu makkelijk uit de autoloader kunnen halen. Wat weer een performance winst is ten opzichte van jouw manier.
Dit is juist de kracht van psr-4, zodat je je mappen kan indelen zoals je wilt.
Was dat maar waar. PSR-4 schrijft juist heel expliciet een directorystructuur voor. Met de highlights in vet:
[...] This PSR also describes where to place files that will be autoloaded according to the specification.
3. When loading a file that corresponds to a fully qualified class name ...
i. A contiguous series of one or more leading namespace and sub-namespace names, not including the leading namespace separator, in the fully qualified class name (a "namespace prefix") corresponds to at least one "base directory".
ii. The contiguous sub-namespace names after the "namespace prefix" correspond to a subdirectory within a "base directory", in which the namespace separators represent directory separators. The subdirectory name MUST match the case of the sub-namespace names.
iii. The terminating class name corresponds to a file name ending in .php. The file name MUST match the case of the terminating class name.
Met andere woorden: basisdirectory, subdirectory én bestandsnaam liggen in PSR-4 alle drie vast.