Door
Ozzie PHP
op 25-02-2014 00:42
gewijzigd op 25-02-2014 01:05
4.490 views
Ola,
Korte vraag. Ik zit me af te vragen... Stel ik heb 2 classes waarin ik de data van een request wil opslaan. In de ene class wil ik client data opslaan en in de andere server data. Voor welke mappenstructuur zouden jullie dan kiezen? A, B of C? (Ik snap dat er nog meer mogelijkheden zijn, maar ik zou graag weten welke van deze 3 jullie voorkeur heeft en waarom.)
A)
/request/
clientdata.php
serverdata.php
Of voor deze manier:
B)
/request/
data/
clientdata.php
serverdata.php
Of...
C)
/request/
data/
client/
data.php
server/
data.php
Het gaat me er vooral om wanneer je überhaupt over moet gaan tot het aanmaken van nieuwe directories. Je kunt zeggen dat beide classes onderdeel van het request zijn, en ze dus gewoon in de request map zetten (A). Je kunt ook zeggen dat het fenomeen "data" weliswaar tot het request behoort, maar een apart onderdeel daarvan is (B). En je kunt vervolgens binnen die data ook weer aparte mappen maken omdat het om verschillende typen, client en server, data gaat (C). Ben benieuwd naar jullie reacties en vooral hoe jullie daar mee omgaan en waar jullie je keuzes op baseren.
>> Maar het is toch niet zo dat bijv. een externe library een psr "library" nodig heeft om te kunnen werken? Een externe library kan bijv. een autoloader nodig hebben "op basis van de psr" richtlijnen, maar dat is het toch wel?
PSR-0 en PSR-4 gaan over autoloading, maar er is ook nog een PSR-1, -2 en -3. PSR-3 heeft interfaces voor loggers, alle OSS PHP logger libraries hebben deze PSR interfaces (en dus ook de PSR package) nodig om te werken.
>> [...] zijn er ook situaties waarin je een hoofdmap hebt, waar ook submappen in staan?
Waar haal ik zo'n package eigenlijk vandaan? Dus zonder de psr package werken sommige libraries niet? En hoe krijg je zo'n package dan werkend? Is dat een kwestie van de autoloader requiren?
>> >> [...] zijn er ook situaties waarin je een hoofdmap hebt, waar ook submappen in staan?
Ja, oke... maar dan praat je over het MVC principe waarbij je onderscheid maakt op basis van het type class (controller, model, view). Ik doelde meer op een library. Dus in het voorbeeld hebben we een hoofdmap "request". In het voorbeeld van Ward, staan alle bestanden in die hoofdmap. Zijn er ook situaties waarin je bepaalde bestanden in een submap zou zetten?
>> Waar haal ik zo'n package eigenlijk vandaan? Dus zonder de psr package werken sommige libraries niet? En hoe krijg je zo'n package dan werkend? Is dat een kwestie van de autoloader requiren?
Leer met composer omgaan (die zorgt voor het hele autoloading gedoe) en dan kun je die packages vlekkeloos van packagist afhalen (de plek waar alle OSS libraries van PHP staan). Het is bloedsimpel. Stel ik wil de monolog logger gebruiken (http://github.com/Seldaek/monolog). Dan open ik mijn terminal (cmd) en doe:
composer require monolog/monolog
Wat composer nu voor je doet is monolog installeren en alles wat monolog nodig heeft (bijv. die PSR-3 interfaces). Die komen dan allemaal in je vendor map te staan (of in een andere map als je Composer anders hebt geconfigueerd). In die vendor map staat ook een class autoloader van Composer die correct is ingesteld voor alle packages (zo heten die libraries) die hij heeft geinstalleerd. Even die autoloader requiren in je bootstrap en je bent klaar!
Nog mooier, je kan ook composer configueren om jouw eigen library classen goed te autoloaden. Ben je helemaal van het autoload verhaal af!
>> Zijn er ook situaties waarin je bepaalde bestanden in een submap zou zetten?
Al op die 3 linkjes gekeken...? Ik kan je vertellen dat 99% van wat je daar vind een library is en geen MVC structuur.
Kan je zo'n package niet handmatig erop zetten? Dat is in feite toch gewoon 1 map met bestanden en (sib)directories?
>> Al op die 3 linkjes gekeken...? Ik kan je vertellen dat 99% van wat je daar vind een library is en geen MVC structuur.
Jawel, maar die hebben zo'n andere opzet dan hoe ik het zelf doe. Ik vind dat veels te ingewikkeld.
Maar wellicht kan ik mijn vraag anders stellen. Ward, en ik denk ook jij aangezien je er geen opmerking over hebt gemaakt, zou dit doen:
/Vendor/
Request/
ClientData.php
ServerData.php
Mijn vraag is, waarom zet je de data niet in een aparte map. Wat is daar de reden voor. Zou een van jullie dat nog kunnen proberen uit te leggen zodat dat wat duidelijker wordt voor mij? Alvast bedankt.
Dat kan ook. Ik gebruik zelf meestal /Vendor/Package/Class.php maar je kunt gerust /Vendor/Package/Subpackage/Class.php gebruiken. Het hangt helemaal af van vooral de onderlinge hiërarchie van de klassen en sub-namespaces.
Je zou in jouw model bijvoorbeeld nog de clientdata kunnen preciseren:
Begrijp ik dan dat er niet echt een goed of fout is? Ik vind het nogal lastig om dus op de juiste manier onderscheid te maken. Wanneer zet je iets in een map en wanneer niet? En waarom geen map "data" met 2 submappen "client" en "server"? Pff... k zie het ff niet meer zo duidelijk momenteel.
Een map is een namespace of subnamespace. Je kunt ze ook "domeinen" noemen. Alles wat tot het exclusieve domein van "Foo" behoort, staat in de /Foo/ namespace. Alles wat niet bij "Foo" hoort, hoort ook niet in de /Foo/ namespace.
Ontwerpfouten maken we allemaal. De kunst is ze snel en elegant oplossen.
Je ontwerpt, denk ik, nog te veel vanuit een theoretisch ideaal. Daarom vind je tien theorieën die er op papier goed uitzien ook alle tien even goed.
Pas als je een concreet probleem aanpakt, merk je waar je theorie in de praktijk faalt. En dan los je dat gewoon op. Vergissen is menselijk en versienummers hebben we niet voor niets.
Ward, dankjewel voor je uitleg. Ik heb het al vaak genoeg niet handig gedaan, dus daarom ook dit gesprek, in de hoop dat ik nu de juiste aanpak ga volgen.
>> Alles wat tot het exclusieve domein van "Foo" behoort, staat in de /Foo/ namespace. Alles wat niet bij "Foo" hoort, hoort ook niet in de /Foo/ namespace.
Oké, maar laten we dan weer even het voorbeeld van de request erbij halen en voor het gemak doen alsof we 3 classes hebben. De basis request class, een class met daarin de client-data (get, files enz.) en een class met de server data.
Of we kunnen zeggen, de "basis" request class en de "data" zijn 2 verschillende "afdelingen" binnen het fenomeen request. Daarom zetten we de data in een aparte map.
Jij gaf zelf aan dat je voor de 1e versie zou kiezen (weliswaar met hoofdletters), en nu wil ik graag weten waarom. Waarom zou jij alles in één hoofdmap zetten en geen submappen gebruiken?
Dat is niet helemaal wat ik zei, Ozzie. Ik zou de uitwerking namespace/subnamespace/class en daarmee directory/subdirectory/bestand pas inkleuren wanneer ik iets concreets bouw. Niet al in een eerder stadium om een "logische" client/server-architectuur te krijgen. De logica ontbreekt namelijk wanneer je nog niet goed kunt invullen wat elk niveau zou moeten doen.
Laat ik het anders andersom formuleren. Zodra je een namespace/subnamespace/class.php en een directory/subdirectory/bestand.php toevoegt, heb je niet slechts een beslissing over class.php en bestand.php genomen, maar ook over de namespace en de directorystructuur: klaarblijkelijk hoort de class c.q. het bestand ergens bij, dus dat moet je ook aan iedereen kunnen uitleggen.
Als je dan toch de tweedeling client/server in data wilt handhaven, is dit een betere oplossing:
/request/
data/
client.php
server.php
Daarmee zeg je: (a) een request bevat data en (b) die data kennen we voor client en voor server.