|
10. Bestanden lezen en schrijven.
10.1 Bestanden lezen.
Er zijn diverse manieren om een bestand te lezen. De meest gebruikte functie is fopen.
fopen moet je aan roepen met een bestandsnaam en een parameter waarin je aangeeft hoe je
het bestand wilt openen. Je kan dan kiezen uit de opties r, r+, w, w+, a en a+. Verderop in dit
hoofdstuk zal je duidelijk worden wat die opties betekenen.
Als voorbeeld laat ik hier zien hoe je de logfiles van apache kan uitlezen. Denk nou niet dat je
gelijk een manier hebt gevonden om gelijk een nieuwe webalizer te bouwen want er komt heel wat meer
bij kijken :).
Als je een bestand wilt op wilt openen dan kijk je natuurlijk eerst of het wel aanwezig is. Mocht je de
exacte bestandsnaam weten van het bestand dat je wilt openen dan maak je gebruik van de file_exists()
functie:
<code> <?php
$bestand = "/var/log/httpd/access_log";
if (!file_exists($bestand)) {
print "Bestand niet gevonden";
} else {
print "Bestand gevonden";
}
?>
</code>
Mocht je nu niet precies weten hoe de bestanden heten en je wilt ook de file attributen
van de bestanden weten dan lees je de directory uit met de functie readdir(). Je moet
de directory wel eerst openen en na afloop sluiten zodat er geen handles blijven openstaan. In
het onderstaande voorbeeld maak ik een array aan waarin alle bestandsnamen worden gezet. Tenslotte
print ik ze nog even uit om te laten zien wat voor bestanden er in staan:
<code> <?php
$dir = "/var/log/httpd/";
$file_array = array();
$filesfound = opendir($dir);
while ($file = readdir($filesfound)) {
if ($file != "." && $file != "..") {
array_push($file_array, $file);
}
}
closedir($filesfound);
while (list($key, $val) = each ($file_array)) {
print $key . " = " . $val;
}
?>
</code>
Om nu de bestands eigenschappen te weten te komen kan je gebruik maken van een aantal functies. We
willen echter alleen weten of we de bestanden mogen lezen. Als we de bestanden mogen lezen dan openen
we ze met de fopen() functie. We geven dan als parameter voor de rechten een r mee. Om te kijken of
je al aan het einde van het bestand bent aangekomen test je dat met feof().
<code> <?php
$dir = "/var/log/httpd/";
$file_array = array();
$filesfound = opendir($dir);
while ($file = readdir($filesfound)) {
if ($file != "." && $file != "..") {
array_push($file_array, $file);
}
}
closedir($filesfound);
while (list($val) = each ($file_array)) {
$file = $dir.$file_array[$val];
if (!is_readable($file)) {
print "Je hebt geen rechten om het bestand te lezen.";
} else {
$filepointer = fopen ($file, r);
while (!feof($filepointer)) {
$buffer = fgets($filepointer, 4096);
print $buffer."<br>";
}
fclose($filepointer);
}
}
?>
</code>
Bovenstaande is alleen maar een voorbeeld om een bestand uit te lezen. Als je er echt iets nuttigs mee
zou willen doen zou je kunnen overwegen om een database te maken en daar alle gedeeltes van de strings
in te zetten. Aan de hand van de tijden die je dan in de database hebt staan en de tijden die je uit het
bestand leest kan je dan de beslissing nemen of je de string wilt opslaan.
10.2 Bestanden schrijven.
De gegevens die we in het bovenstaande voorbeeld uitlezen zullen we gelijk gebruiken om te laten zien
hoe je daarmee een kort rapport kan schrijven. Hou er rekening mee dat de plek waar het bestand moet
worden geschreven voldoende rechten moet hebben (onder Unix). Voor het gemak zullen we even uitgaan
van de /tmp dir. We nemen een groot gedeelte van de code zoals we die in het vorige voorbeeld gebruikt
hebben. In plaats van het printen naar het scherm gaan we nu echter de individuele regels opdelen en een
gedeelte ervan in variabelen zetten. De regel die we willen uitlezen kan er ongeveer zo uit zien:
<voorbeeld>
marvin.northernlight.com - - [16/May/2000:22:01:57 +0200]
"GET /robots.txt HTTP/1.1" 200 115 "-" "Gulliver/1.3"
</voorbeeld>
In dit voorbeeld laat ik zien hoe je het totaal gegenereerde verkeer tot dan aan toe eruit kan vissen.
Met een beetje fantasie kan je natuurlijk nog veel meer gegevens verzamelen. Het resultaat schrijven
we in het bestand.
<code> <?php
$dir = "/var/log/httpd/";
/*
Vars voor de plek waar we het rapport willen schrijven en de naam ervan.
*/
$reportdir = "/tmp/";
$reportfile = "sitereport";
$file_array = array();
$filesfound = opendir($dir);
while ($file = readdir($filesfound)) {
if ($file != "." && $file != "..") {
array_push($file_array, $file);
}
}
closedir($filesfound);
/*
De w parameter zorgt ervoor dat het bestand kan worden aangemaakt. Als het al bestaat
dan maakt het een nieuw bestand aan met die naam. Door de datum aan de bestandsnaam toe
te voegen krijgen we een mooi overzicht per datum.
*/
$datum = (date("-d-M-Y"));
$report = fopen ($reportdir.$reportfile.$datum.".txt", w);
while (list($val) = each ($file_array)) {
$file = $dir.$file_array[$val];
if (!is_readable($file)) {
print "Je hebt geen rechten om het bestand te lezen.";
/*
We willen op dit moment niet de error logs uitlezen dus als het bestand
mag worden gelezen checken we ook of het een error_log is.
*/
} else if (substr($file_array[$val],0,3) != "err") {
$fs = 0;
$filepointer = fopen ($file, r);
while (!feof($filepointer)) {
$buffer = fgets($filepointer, 4096);
/*
We zijn nu op het punt aangekomen dat we
de string gaan splitsen en de waardes in
de diverse arrays zetten die we er voor
aanmaken. Onderstaande code maakt een
array $a aan waarin de hosname in key 0
zit, de verbruikte bestandsomvang in key 9.
Om alles bij te houden hebben we een var
voor de bestandsomvang.
*/
$a = explode(" ", $buffer);
while(list($key, $val) = each ($a)) {
/*
We hoeven natuurlijk niet te weten
wat localhost genereerde dus die
filteren we eruit. Let hierbij op
dat localhost, je eigen ipnr en je
eigen hostname allemaal verkeer
genereerde die je niet hoeft mee te
tellen.
*/
if ($a[0] != "localhost") {
if (intval($a[9]) > 0) {
$fs = intval($fs) + intval($a[9]);
}
}
}
}
fclose($filepointer);
/*
Nu we een bestand hebben gelezen kunnen we een
rapport genereren. Aangezien we voor ieder
logfile willen weten wat het verbruik is doen
we dat op deze plek (net voordat het eventuele
volgende bestand zal worden gelezen).
*/
fputs ($report, "Rapport voor het bestand $file.\n");
fputs ($report, "Totaal verbruikte aantal Kilobytes is: $fs\n");
}
}
/*
Bestand afsluiten.
*/
fclose ($report);
?>
</code>
Het gegenereerde bestand staat nu in je /tmp dir. Ik wil er wel even bij opmerken dat je voor het
uitlezen van dit soort bestanden beter een taal als Perl kan gebruiken. PHP is veel meer geschikt
om kleinere bestanden uit te lezen. Dit voorbeeld is alleen maar gebruikt om je duidelijk te maken
hoe je bestanden kan uitlezen en de gegevens ervan in een nieuw bestand kan opslaan.
|