controle
De vraag luidt: wat controleer jij?
Ik zag zojuist in een ander topic dat iemand alvorens een view te includen ging controleren of de view wel bestaat. Op zich niks mis mee, maar hoe ver ga jij hierin? Controleer jij ALTIJD of een bestand aanwezig is alvorens je het gaat parsen of laden? Ook als je zeker weet dat dat bestand gewoon altijd aanwezig is? En wat doe je met bijv. met configuratiesettings die je ophaalt op basis van hun ID? Haal je die gelijk op omdat je weet dat de setting bestaat? Of controleert jouw get() functie stiekem nog even of je wel een geldige ID hebt ingegeven?
Ik ben benieuwd...
Intern voer je een controle alleen uit wanneer dat meer oplevert dan kost. Een baten/lasten-verhouding is er meestal wel ergens.
Als je elke require bijvoorbeeld in een file_exists() verpakt, verdubbel je het aantal uitstapjes naar het file system. Dat zijn de kosten/lasten. Kun je vervolgens niets zonder vereist bestand, dan zijn de opbrengsten/baten nul. Einde van de vergelijking is dan dat het niets oplevert en alleen maar iets kost en dan doe je dat dus niet.
Zo'n vergelijking kan natuurlijk ook anders uitpakken. Bijvoorbeeld een uitstapje naar een database heeft vrij hoge kosten/lasten. Dan levert het al gauw meer op om eerst even te controleren of een ID die je in een query stopt wel voldoet aan de ID's in het datamodel.
Alles wat dynamisch is controleren (get,post,etc) alles wat statisch (include,etc) is zou niet nodig hoeven zijn.
@Ward:
>> Kun je vervolgens niets zonder vereist bestand, dan zijn de opbrengsten/baten nul.
Oké, en in zo'n geval gebruik jij dan neem ik aan gewoon een require die uitmondt in een fatal error als het bestand niet bestaat?
@Michael:
>> Alles wat dynamisch is controleren (get,post,etc) alles wat statisch (include,etc) is zou niet nodig hoeven zijn.
Oké. Dat lijkt mij inderdaad een mooie stelregel. Maar ik zie dus heel vaak code voorbijkomen waarin bijv. wordt gecontroleerd of een bepaalde view wel bestaat. Als je uitgaat van een MVC model, dan controleer je eerst of iemand een geldige route heeft aangeroepen. Als de route (URL) klopt, dan hoef je vervolgens toch niet ook nog eens te controleren of de view wel bestaat?
Ozzie PHP op 13/12/2013 11:00:57:
>> Kun je vervolgens niets zonder vereist bestand, dan zijn de opbrengsten/baten nul.
Oké, en in zo'n geval gebruik jij dan neem ik aan gewoon een require die uitmondt in een fatal error als het bestand niet bestaat?
Oké, en in zo'n geval gebruik jij dan neem ik aan gewoon een require die uitmondt in een fatal error als het bestand niet bestaat?
Inderdaad. Moet je maar opletten bij het uploaden. Required betekent immers: vereist.
Er zijn overigens frameworks die precies het tegenovergestelde doen. Die gebruiken een view, een controller, een plug-in en zelfs een template of een afbeelding wanneer die aanwezig is in de daarvoor bestemde directory. Ze implementeren dus via file_exists() een omgekeerde beslissingsregel: is het geïnstalleerd, dan moet het kennelijk worden gebruikt.
Lijkt mij niet handig of verstandig, want zo bouw je een kaartenhuis dat volledig afhankelijk is van de directory- en bestandsstructuur.
Ik ben dan wel nog even benieuwd hè... met mijn filesystem class kan ik een bestand laden (via file_get_contents). Nu check ik dus in die load() method eerst of het bestand bestaat. Zo niet dan gooi ik een exception. Dit had ik ingebouwd omdat mijn filecacher gebruik maakt van het filesystem. Als ik dan een bestand wil loaden en het bestaat niet, gooit het filesystem een exception. Nu zit ik me dus af te vragen of ik de verantwoordelijkheid niet moet verplaatsen. De controle weghalen uit de load() method van het filesystem en in plaats daarvan een is_file() toepassen in de load() method van de cacher. Wat vind jij? Normaal gesproken kan het toch niet gebeuren dat een bestand zomaar van de server verdwijnt? Of kan zoiets in uitzonderlijke gevallen wel gebeuren door een hick-up van de server of iets dergelijks?
Gewijzigd op 13/12/2013 11:41:19 door Ozzie PHP
Als ik het zo lees, is je filesystem-klasse weinig meer dan een OOP-wrapper voor PHP-functies. Dat voegt alleen overhead toe die je juist bij een cache niet wilt.
Maar mijn andere vraag... is het mogelijk dat een bestand zomaar ineens van de server verdwijnt? Niet omdat je het bestand zelf hebt verwijderd (hetzij handmatig of dmv code) maar echt buiten jouw "schuld" om. Kan een bestand zomaar ineens verdwijnen? Bijv. omdat de server een hick-up heeft? Of komt zoiets nooit voor?
Ozzie PHP op 13/12/2013 11:40:54:
Maar mijn andere vraag... is het mogelijk dat een bestand zomaar ineens van de server verdwijnt? Niet omdat je het bestand zelf hebt verwijderd (hetzij handmatig of dmv code) maar echt buiten jouw "schuld" om. Kan een bestand zomaar ineens verdwijnen? Bijv. omdat de server een hick-up heeft? Of komt zoiets nooit voor?
Er zijn natuurlijk altijd wel situatie te bedenken. Zo was er bij mijn hosting laatst een probleem opgetreden waarbij ze een backup moesten terug zetten, maar deze backups bleken corrupt te zijn waar door een oudere backup werd terug gezet. Als ik dan een dag voor dat probleem een bestand erop had gezet, was ie niet meer te vinden. Je kunt je afvragen hoe vaak dit voorkomt en of dit een probleem is.
Ozzie PHP op 13/12/2013 11:40:54:
Maar mijn andere vraag... is het mogelijk dat een bestand zomaar ineens van de server verdwijnt? Niet omdat je het bestand zelf hebt verwijderd (hetzij handmatig of dmv code) maar echt buiten jouw "schuld" om. Kan een bestand zomaar ineens verdwijnen? Bijv. omdat de server een hick-up heeft? Of komt zoiets nooit voor?
Ja, bijvoorbeeld bij een beschadigde schijf kunnen bestanden corrupt en daardoor onleesbaar worden. Kleine kans dat je daarvan last hebt, want bij de meeste servers is het bestandssysteem bijvoorbeeld met een RAID-configuratie redundant uitgevoerd.
Waar je eerder last van hebt, is onprofessioneel ge*** van sommige providers. Bijvoorbeeld wanneer een server kapot gaat en ze de back-up van 24 uur geleden terugzetten op een nieuwe zonder je even in te seinen...
Maar nu de cruciale vraag. Bij sommige cruciale bestanden die je requiret werkt niks meer als die bestanden niet bestaan. Als het echter gaat om een view/template dan zou de rest van de website nog gewoon kunnen werken. Echter, als ik niet zou controleren of een view bestaat... en er is inderdaad een back-up teruggeplaatst en het bestand ontbreekt, dan zal ik hier misschien nooit achter komen, omdat ik er niet op controleer en dus ook geen melding ontvang. Wellicht dan toch een goed idee om altijd te controleren of een bestand bestaat?
md5_file() wordt vaak gebruikt voor downloads: heeft een bestand een andere MD5-hash gekregen, dan is het gewijzigd. Je hoeft dan niet allerlei klassen en applicaties vol te stoppen met controles, maar voert op een hoger niveau een volledige "server integrity check" uit. Kun je meteen mee controleren of je server niet gecompromitteerd is.
Als je toch een controle gaat bouwen, waarom dan niet een kleine applicatie schrijven die de integriteit van alle kritieke bestanden controleert? Bijvoorbeeld Voor nu gaat het me om iets heel simpels. Bijvoorbeeld, iemand roept de pagina www.mijnsite.nl/contact aan. Als je dan de bijbehorende view/template gaat laden, zou je dan wel of niet file_exists() gebruiken om eerst te controleren of die view bestaat? Of laad je de view/template direct in?
Ozzie PHP op 13/12/2013 12:29:35:
Oeh... dat lijkt me een mooi project voor "ooit" :-) Hoe zou je zoiets moeten aanpakken dan?
Voor nu gaat het me om iets heel simpels. Bijvoorbeeld, iemand roept de pagina www.mijnsite.nl/contact aan. Als je dan de bijbehorende view/template gaat laden, zou je dan wel of niet file_exists() gebruiken om eerst te controleren of die view bestaat? Of laad je de view/template direct in?
Voor nu gaat het me om iets heel simpels. Bijvoorbeeld, iemand roept de pagina www.mijnsite.nl/contact aan. Als je dan de bijbehorende view/template gaat laden, zou je dan wel of niet file_exists() gebruiken om eerst te controleren of die view bestaat? Of laad je de view/template direct in?
Doe het dan meteen goed. Een contactpagina is typisch iets dat zelden verandert. Die haal je dus op uit je file cache. De rest komt er pas in twee situaties aan te pas bij een cache-update: als de contactgegevens veranderen óf als de template verandert (en die verandering meer behelst dan een aanpassing van een CSS-bestand).
Daarna pas is de volgende vraag aan de orde. Aangezien je view/template nu alleen nog maar eens in de zoveel maanden hoeft aan te spreken voor een cache-update, kun je daarin inderdaad prima file_exists() gebruiken óf een uitstapje maken naar je eigen FileSystem-klasse. Dat kost overhead, maar voor één request per zoveel maanden speelt dat geen rol.
Gaat het dan fout, door een ontbrekend bestand, dat blijf je de cache gebruiken en stuur je een noodkreet-mailtje naar de webmaster.
Bouw geen losse klassen maar denk in oplossingen. Wat je links weglaat, moet er rechts soms bij. Wat je nu niet doet, moet je later alsnog doen.
Hmmm, oké... maar ook als je de contactpagina uit de cache zou halen, moet je een bestand ophalen. En zeker bij een cache-pagina lijkt het me handig om te kijken of de cache wel bestaat. Dus dan krijg je daar alsnog een file_exists. Of mis ik nu iets?
Inderdaad, in de cache is file_exists() onmisbaar. Sterker nog, je zult soms ook nog de datum en tijd van het cachebestand willen controleren om na te gaan of het cachebestand niet verouderd is, dus is hiervoor nog een uitstapje langs het filesystem nodig.
Gaat het filesystem de tijd van het bestand controleren?
Controles zijn soms overbodig. Je kunt bijvoorbeeld elke nacht via een cronjob de complete cache vernieuwen of elk uur de oudste 10% updaten. Verzin maar een werkbare beslissingsregel.
Je kunt de controle buiten het filesystem om doen door een last-modified te registreren bij de content in de database. Achterom wil je als admin vaak ook nog een cache-update kunnen forceren, bijvoorbeeld omdat je een template hebt aangepast.
Wel nuttig om daar eens naar te kijken, want je kunt er gigantische snelheidswinst mee boeken, tot een factor 10. Bij elk HTTP-verzoek een complete HTML-pagina in elkaar fietsen met queries en echo's is minder vanzelfsprekend dan het lijkt.
Allright, thanks voor de tips!