Warum eine Konfiguration nicht als Variablen in Dateien speichern

Möglichkeiten zum Lesen von Konfigurationsdateien, Vor und Nachteile

Gegeben sei ein kleiner Hash, als Referenz in einer Datei notiert:

# Datei data.pl
foo => { bar => 123} };

Ein Lesen dieser Datei mit my $ref = do "data.pl" liefert die Referenz zurück. Nun könnte man annehmen, daß dieses Lesen sehr performant sei, weil man ja unmittelbar eine Referenz bekommt. Diese Annahme jedoch erweist sich als Trugschluss, wie untenstehender Benchmark zeigt:


          Rate Perlvar inifile  Binary
Perlvar 1177/s      --    -50%    -69%
inifile 2353/s    100%      --    -39%
Binary  3855/s    228%     64%      --

Dateiinhalt kompilieren, INI oder Binary lesen

use strict;
use warnings;
use Benchmark qw(cmpthese);
use Data::Dumper;
use IO::File;
use Config::Tiny;

# Datenstruktur in Datei data.pl: { foo => { bar => 123} }
# deselben Daten nun nach data.bin serialisieren
my $data = do "data.pl";
my $fh = IO::File->new;
$fh->open("data.bin", O_CREAT|O_RDWR|O_TRUNC|O_BINARY) or die $!;
foreach my $e( keys %$data){
    foreach my $a( keys %{$data->{$e}} ){
        my $v = $data->{$e}{$a};
        $fh->print( pack("NNN", length $e, length $a, length $v).$e.$a.$v );
    }
}

cmpthese(10000, {
    'inifile' => sub{
        my $cfi = Config::Tiny->new;
        $cfi->read('data.ini');
    },
    'Perlvar' => sub{ do "data.pl" },
    'Binary' => sub{
        my $fh = IO::File->new;
        $fh->open("data.bin", O_RDONLY|O_BINARY);
        my $eav = {};
        while( read($fh, my $bin, 12) ){
            my ($elen,$alen,$vlen) = unpack "NNN", $bin;
            read($fh, my $ent, $elen);
            read($fh, my $att, $alen);
            read($fh, my $val, $vlen);
            $eav->{$ent}{$att} = $val;
        }
        $eav;
    }
});

# Aufbau der INI Datei data.ini
[foo]
bar=123

Es zeigt sich, daß das Lesen derselben Daten, die binär serialisiert in einer Datei vorliegen, viermal so schnell vonstatten geht, einschließlich der Wiederherstellung der Datenstruktur und auch die INI-Datei ist schneller geparst! Nun, die Performance ist die eine Sache. Es gibt jedoch weitere Gründe, die dagegen sprechen, Variablen nicht auf diese Art und Weise aus Dateien einzubinden.

Eine Frage der Sicherheit

Dateien, die mit do oder require eingebunden werden, enthalten Code, der kompiliert wird. Hier besteht also die Gefahr, daß mit dem Einbinden der Konfiguration ein Code ausgeführt wird der die Ausführung eines Programmes behindern und im schlimmsten Fall Schaden anrichten kann.

Die Frage der Skalierbarkeit

Nicht selten kommt es vor, daß man mit verschiedenen Programmiersprachen, z.B. mit Perl und mit PHP auf einunddieselbe Variablen einer Konfiguration greifen möchte. Redundante Konfigurationen sind schlecht, das sind Inkonsistenzen vorprogrammiert.

Gilt das auch für PHP?

Selbstverständlich! Grundsätzlich ist auch in PHP alles was von draußen kommt tainted, also als verdorben zu betrachten. Von daher ist es möglich, über Dateien die mit require oder include eingebunden werden, Code einzuschleusen, ganz genauso wie das auch in Perl möglich ist. Und was die Performance betrifft, ist auch in PHP das Parsen von INI-Dateien performanter als das Einbinden von Variablen per require, zumal parse_ini_file() in C implementiert ist.


Datenschutzerklärung: Diese Seite dient rein privaten Zwecken. Auf den für diese Domäne installierten Seiten werden grundsätzlich keine personenbezogenen Daten erhoben. Das Loggen der Zugriffe mit Ihrer Remote Adresse erfolgt beim Provider soweit das technisch erforderlich ist. s​os­@rolf­rost.de.