op welk punt exception afhandelen?
Pagina: « vorige 1 2 3 volgende »
Ozzie PHP op 19/11/2013 18:06:42:
Hoe weet je nu dan op voorhand hoe groot dat bestand gaat worden?
Moet je dat altijd weten? Voor een paar regels configuratie? Of kun je het silent in een try stoppen en dan kijken wat er in de catch uitrolt ;)
Nogmaals, ik wil het toch maar even herhalen: exceptions zijn er niet alleen voor fouten. Je kunt ze ook gebruiken als een if ... else ...
Wat bedoel je Ward. Ik begrijp niet wat je bedoelt te zeggen. Kun je een voorbeeldje geven?
Een try/catch leent zich veel beter voor een systeem met een onbekende toestand. En voor onverwachte toestanden: de spreekwoordelijke uitzonderingen op de regel c.q. “exceptions to the rule”.
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
<?php
try {
$cacher = new FastRamCacher();
$cacher->setTurboBoost(true);
} catch (\CacherException $e) {
$cacher = new SlowDiskCacher();
}
?>
try {
$cacher = new FastRamCacher();
$cacher->setTurboBoost(true);
} catch (\CacherException $e) {
$cacher = new SlowDiskCacher();
}
?>
Nu hebben we eventuele problemen afgevangen. Het maakt eigenlijk ook niet uit welke problemen er precies optraden: dat staat in de log, maar in deze applicatie speelt het geen rol. Bovendien kunnen we de FastRamCacher nu updaten, herschrijven of vervangen, zonder dat onze oplossing daar hinder van heeft.
Overigens zie je hier meteen ook het nut van interfaces.
Maar wat ik nog wilde weten, is hoe het zit met het opslaan van een bestand.
Is het dan wel of inet de bedoeling dat je eerst kijkt hoeveel vrije schijfruimte er nog is? En zo ja, hoe werkt dat. Stel ik wil een array in een bestand opslaan, hoe weet ik dan vantevoren hoeveel kb dat bestand in beslag gaat nemen?
Want dan zou ik ook zomaar kunnen bedenken dat je de temp dir automatisch geleegd word en dat doe je ook niet zomaar.
Volgens mij is dit weer zo'n gevalletje wat op server niveau gedaan moet worden.
Daar krijg je als het goed is een mail van met de melding disk is 90% full.
Maar Ward zei dus eerder dit:
Ward van der Put op 19/11/2013 17:41:14:
Ik zou meer loggen. Maar verder heb ik er weinig op aan te merken.
Je kunt in een multi-processing omgeving namelijk zoiets verwachten:
1. Applicatie X vraagt via een if aan FileSystem of er genoeg ruimte is.
2. FileSystem antwoordt met (bool) ja of (int) 10 MB.
...
Je kunt in een multi-processing omgeving namelijk zoiets verwachten:
1. Applicatie X vraagt via een if aan FileSystem of er genoeg ruimte is.
2. FileSystem antwoordt met (bool) ja of (int) 10 MB.
...
En nu vraag ik me dus af hoe je vantevoren moet checken of er nog voldoende schijfruimte vrij is.
Of is het voldoende om gewoon zoiets te doen:
Code (php)
1
2
3
4
5
2
3
4
5
<?php
if (!file_put_contents($file, $data)) {
throw new FileSystemException("could not save file $file");
}
?>
if (!file_put_contents($file, $data)) {
throw new FileSystemException("could not save file $file");
}
?>
En dat je dan zelf een mail ontvangt met de foutmelding "could not save file foo.php" waarop je vervolgens zelf actie onderneemt door uit te zoeken wat er aan de hand is (kloppen de map-rechten of is de schijf vol)?
Aangezien je met een FileSystem class dicht tegen een OS aan zit te programmeren, zou ik verder inderdaad op fouten van PHP-functies vertrouwen. Dan is er inderdaad niets aan te merken op een if waarin de false een exception gooit. Alle functionaliteit voor file handling OOP gaan zitten nabouwen levert te weinig op.
Oké, maar nogmaals... hoe weet ik of ik vantevoren of er genoeg ruimte is??? Hoe kan je dat op voorhand controleren? Dan moet je eerst weten hoe groot de file gaat worden, maar dat kun je toch op voorhand nooit weten?
Wil je het exact weten, dan kun je bijvoorbeeld de output bufferen en de grootte van de outputbuffer controleren met ob_get_length().
Ward, en als ik het nu andersom zou doen. Ik sla gewoon een file op, en pas als het mislukt ga ik kijken wat er aan de hand is? (schijf vol of verkeerde map-rechten) Is dat niet een beter idee? Dan hoef ik op voorhand niks te controleren.
2)
Ik kwam trouwens zojuist dit scriptje tegen om te kijken hoe groot een variabele is. Wat is dan beter, dit scriptje of jouw variant met ob_get_length()?
En pas daarna controleren? Ach ja, ik ga ook altijd in een auto rijden en pas als ik er op de snelweg achterkom dat ik met 120 km/h de vangrail ben ingevlogen doordat ik opeens mijn linkervoorwiel verloor ga ik kijken of dat wiel er uberhaupt wel goed op zat...
Behalve bij grote dingen zoals een upload van een paar MB. Dan moet je vaak sowieso meer controleren, dus dan kan een controle van de schijfruimte er wel bij.
Als iemand door 1000 deelt bij bits en bytes, zou ik nog even doorgooglen :)
>> Als iemand door 1000 deelt bij bits en bytes, zou ik nog even doorgooglen :)
Oké prima, maar hoe hoort het dan wel? Hoe krijg ik het aantal bytes (of bits??) zodat ik dat kan vergelijken met de nog vrije schijfruimte?
@Wouter:
>> En pas daarna controleren? Ach ja, ik ga ook altijd in een auto rijden en pas als ik er op de snelweg achterkom dat ik met 120 km/h de vangrail ben ingevlogen doordat ik opeens mijn linkervoorwiel verloor ga ik kijken of dat wiel er uberhaupt wel goed op zat...
Wouter, het is gewoon een vraag hoor. Je hoeft niet zo vreemd te reageren???
Ik zal uitleggen wat ik bedoel, en dan mag jij daarna jouw reactie daar op geven.
Ik ga er vanuit dat er op mijn server altijd voldoende ruimte is om iets op te slaan. Dat is de normale situatie. Nu kun je 2 dingen doen.
a) Altijd als je iets opslaat gaan controleren hoe groot het bestand is en het daarna pas opslaan. Dit is een optie, maar zoals we zojuist hadden geconcludeerd is de normale situatie dat er altijd voldoende ruimte is.
b) Waarom zouden we iedere keer opnieuw gaan controleren hoeveel vrije schijfruimte er nog over is telkens als we iets willen opslaan? We hadden namelijk zojuist geconcludeerd dat de normale situatie is dat er altijd voldoende ruimte is. Als er dan ooit in dat ene enkele specifieke geval een keer te weinig ruimte is, dan returnt file_put_contents() keurig een false en kan ik in dat ene specifieke geval controleren hoeveel vrije schijfruimte er nog is en vervolgens een exception gooien.
In situatie A zit je altijd iets te controleren wat in 99,99% van de gevallen overbodig is.
In situatie B controleer je op voorhand nooit, enkel en alleen als gebleken is dat een bestand niet kan worden opgeslagen.
In zowel situatie A als situatie B kan het bestand niet worden opgeslagen. Zowel in situatie A en B wordt de webmaster hier middels een exception van op de hoogte gebracht.
In mijn optiek: situatie B is efficiënter, omdat je niet iedere keer onnodig aan het controleren bent.
En nu mag jij zeggen waarom je denkt dat situatie A beter is.
En om nog even in te gaan op je vergelijking:
>> Ach ja, ik ga ook altijd in een auto rijden en pas als ik er op de snelweg achterkom dat ik met 120 km/h de vangrail ben ingevlogen doordat ik opeens mijn linkervoorwiel verloor
Wat jij nu dus suggereert is dat je iedere keer voordat je gaat autorijden met een sleutel alle moeren van je 4 banden nog eens extra gaat vastdraaien om te voorkomen dat onderweg je wiel losschiet. Hoe reëel is dat?
Ozzie PHP op 20/11/2013 16:45:37:
@Ward:
>> Als iemand door 1000 deelt bij bits en bytes, zou ik nog even doorgooglen :)
Oké prima, maar hoe hoort het dan wel? Hoe krijg ik het aantal bytes (of bits??) zodat ik dat kan vergelijken met de nog vrije schijfruimte?
>> Als iemand door 1000 deelt bij bits en bytes, zou ik nog even doorgooglen :)
Oké prima, maar hoe hoort het dan wel? Hoe krijg ik het aantal bytes (of bits??) zodat ik dat kan vergelijken met de nog vrije schijfruimte?
http://stackoverflow.com/questions/7568949/measure-string-size-in-bytes-in-php
Verder is de term 'byte' platform dependent. Op sommige (erg oude) systemen zal een byte 16 bits kunnen zijn. Al defineert IEC 80000-13 een 'byte' als 8 bits. De term 'octet' zal altijd 8 bits zijn =]
Kilo is de SI afkorting voor 10^3, of 1000. Een kilobyte is dus eigenlijk 1000 bytes. Maar 1024, of 2^10, was stukken makkelijker om mee te werken. Dus zijn sommige mensen kilobyte als 1000 bytes gaan zien, en andere als 1024 bytes.
Gelukkig is er iets zoals een Kibibyte, kort voor kilo binary byte, deze zal altijd 1024 bytes zijn. Afkortingen: KiB, MiB, GiB etc.
Jij schijnt voor de SI kilobyte gekozen te hebben. Over het algemeen worden grotes in IEC (de ... binary bytes versie) weergeven en dan jammergenoeg met afkortingen als kB, MB, GB etc.
PS. wil je 100% duidelijk zijn over hoeveel bits je het hebt, praat dan altijd over bits of octets. Dus megabit, gibibit, kilooctet of gibioctet :p
PPS. sorry, het irriteert me dat het niet altijd goed gebruikt wordt.
>> Jij schijnt voor de SI kilobyte gekozen te hebben.
Geen idee, ik heb eerlijk gezegd nog nergens voor gekozen.
Ik zal even in m'n eigen jip en janneke taal de vraag stellen. Ik wil als ik een variabele heb weten hoeveel bit/byte/kb... whatever de inhoud van die variabele is. En dit aantal wil ik vergelijken met het resterende aantal bit/byte wat nog op m'n harde schijf vrij is.
Kun je mij daar bij helpen?
Ward heeft al gezegd dat ik dit moet gebruiken:
Ward van der Put op 19/11/2013 16:35:20:
Maar dan moet ik dus nog de filesize van de variabele hebben zodat ik die kan aftrekken van $bytes_available.
Wordt het dan zoiets als dit?
Code (php)
1
2
3
4
5
6
2
3
4
5
6
<?php
$bytes_available = disk_free_space('/');
$string = 'Cién cañones por banda';
$string_size = mb_strlen($string, '8bit');
$result = $bytes_available - $string_size;
?>
$bytes_available = disk_free_space('/');
$string = 'Cién cañones por banda';
$string_size = mb_strlen($string, '8bit');
$result = $bytes_available - $string_size;
?>
Ozzie, met '/' tel je alle ruimte op een station. De ruimte voor bijvoorbeeld een directory kan kleiner zijn. Dat hangt onder andere van het file system en natuurlijk de configuratie af.
Een PHP-string kan niet langer zijn dan 2 GB. Voor die tijd loop je tegen de geheugenlimiet van standaard 128 MB aan. Dat geeft een beetje de bovengrenzen aan.
Verder tellen veel providers alle ruimte die je gebruikt bij elkaar op. Bijvoorbeeld ook de tellingen voor je databases en e-mailaccounts wegen mee. Mailt iemand je een "leuke" bijlage, dan kan de webruimte die je overhoudt ineens lager uitvallen. (Vroeger deden sommige providers dat niet en kon je nogal eens besparen door afbeeldingen in een database te zetten: die telde niet mee bij de webruimte.)
Als we het dus hebben over één zin of een handvol alinea's, is dat maar een druppel op een gloeiende plaat. Ik zou dat niet gaan meten.
Volgens Wouter moet je altijd meten, volgens jou soms... en daarnaast weet ik niet eens HOE ik moet meten?
Soms wel en soms niet. Verder zit je wat mij betreft goed: standaardfuncties van PHP in een if verpakken en een false laten eindigen in een exception die je logt.
Jouw "Soms wel en soms niet." vind ik nog steeds wat lastig te interpreteren. Ik zou op zich wel een controlemogelijkheid kunnen inbouwen, maar hoe werkt dat dan?
Klopt deze code? Is dit de juiste manier om vrije schijfruimte te bepalen?
Code (php)
1
2
3
4
5
6
2
3
4
5
6
<?php
$bytes_available = disk_free_space('/');
$string = 'test string';
$string_size = mb_strlen($string, '8bit');
$result = $bytes_available - $string_size;
?>
$bytes_available = disk_free_space('/');
$string = 'test string';
$string_size = mb_strlen($string, '8bit');
$result = $bytes_available - $string_size;
?>
Exact hetzelfde tekstbestand kan bij een 16-bits karakterset twee keer groter zijn dan bij een 8-bits karakterset. Bepaal éérst wat je wilt opslaan, daarna pas hoe je dat gaat doen.
Je andere vraag hangt daarmee samen: waarom soms wel en soms niet? Omdat je soms iets móét opslaan en soms niet. Omdat sommige applicaties niet werken als je niets opslaat en andere gedeeltelijk wel. Omdat klanten met een betaald Pro-account soms voorgaan en klanten met een gratis instapaccount daarom soms achter het net mogen vissen. Verzin het maar...