• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[PHP] Sichere Includes?

jeko

Lounge-Member
Hallo zusammen,

ich würde gerne den Include von Dateien mit einer eigenen Funktion realisieren, damit ich allfällige Fehler im Zusammenhang mit dem Include und der Datei sowie einige Berechtigungsfragen vor dem Include lösen kann. Vor allem die Berechtigungsabfragen möchte ich ungern in den einzubindenden Dateien durchführen lassen, da der Wartungsaufwand damit (m.E. unnötigerweise?) in die Höhe steigt.

Das Problem auf das ich stosse, ist das (alte) Problem mit dem Scope der Variablen in der eingebundenen Datei. Dieser ist nämlich auf den Scope der Umgebung in der die Datei eingebunden wird begrenzt - heisst, die Variablen sind dann nur meiner Funktion verfügbar, danach nicht mehr. Die Situation erfordert es im Moment noch nicht, dass die Variablen danach noch verfügbar sind, allerdings will ich nicht etwas implementieren und im Nachhinein merken, dass ich mir damit wieder mal selbst Steine in den Weg gelegt habe.

Gibt es dafür schon "schöne" Workarounds?

Grüsse
jeko
 
Naja um fehlerhafte includes zu vermeiden gibt es ja require.
Aber das ist nur die Hälfte von dem was du haben möchtest.

Verstehe ich dass richtig, dass du weitere PHP-Dateien bei Bedarf mittels einer Funktion nachladen möchtest?
 
Ich könnte mir vorstellen, dass es mit möglich ist mit $GLOBALS zu arbeiten. Habs jetzt nicht getestet. Selbst wenn es funktioniert: Als schön empfinde ich die Lösung nicht, da man sich damit den Scope ziemlich zumüllt und schnell mal eine Variable überschreibt.

Als schön würde ich eine Funktion empfinden, die einfach einen Array mit den gesetzen Variablen zurück gibt:
PHP:
function myInclude($script){
    $return = array();
    include($script);
    return $return;
}

Du müsstest dann halt innerhalb der Datei die Variablen dem Array zuweisen.

Als schöner würde ich da persönlich eine Klasse empfinden:
PHP:
class MyInclude{
    protected $_properties = array();

    public function __construct($path){
        include($path);
    }

    public function __set($key, $value){
        $this->_properties[$key] = $value;
    }

    public function __get($key){
        return $this->_properties[$key];
    }
}

In der includeten Datei könntest du dann so arbeiten:
PHP:
$this->foo = 'bar';

Und aufzurufen gänge das so:
PHP:
$inc = new MyInclude('foo.inc');
print $inc->foo;

Ist ungetestet, aber empfinde ich persönlich als die schönste Variante. Man hat alles schön gekapselt, kann Fehlermeldungen prima abfangen und überschreibt keine Variablen aus dem globalen Namespace.
 
Hallo Tom80, [-UFO-]Melkor,

danke für eure Antworten.

Tom80 schrieb:
Verstehe ich dass richtig, dass du weitere PHP-Dateien bei Bedarf mittels einer Funktion nachladen möchtest?
Genau :)

[-UFO-]Melkor: Gute Ansätze, danke dafür. Nur leider funktionieren die nur, wenn ich weitere Konventionen bestimmte, wie z.B. (Variante 1) dass jede includierte Datei sich darauf stützt, dass ein Array $return definiert ist und dieses Array dann befüllt. Das geht m.E. gegen dieses schwammig definierte "schön" das ich eingangs (auch schon in diesen viel- und nichtssagenden Quotes) erwähnte.

Die Klasse gefällt mir schon eher, da es eine einfache Erweiterung des Modulcharakters, den die meisten Dateien die ich einbinde besitzen, bietet.

Beide Möglichkeiten schlagen im Endeffekt aber spätestens ab dem Zeitpunkt fehl, wenn die eingebundene Datei auf globale Variablen zugreifen will - es sei denn, diese sind per global in den Scope eingebunden natürlich, was aber schwierig sein dürfte, da jede Datei unter Umständen andere globals einbinden müsste. Vielleicht setze ich hier aber trotzdem an, beim Drüberschauen über das Projekt hab ich gesehen, dass die Vorarbeit sich ausgezahlt hat und die meisten "globalen" Variablen auf die zugegriffen werden muss über statische Attribute von Klassen erreichbar sind.

Wahrscheinlich werde ich tatsächlich alles runterbrechen auf 1-2 Variablen und einen deiner Ansätze verfolgen; oder aber ich gehe alle $_GLOBALS durch und definiere sie im Scope der Methode/Funktion neu.

Ist und bleibt halt "unschön" - daher sind weiter Ansätze herzlich willkommen!

Dankeschön!

Grüsse
jeko
 
Wie wäre es mit dem Registry-Pattern? Global schafft immer Abhängigkeiten, die man mit einer Registry zwar nicht 100% vermeiden kann, aber immerhin etwas mindern kann.
Die sauberste, aber wohl auch lästigste Lösung, wäre das setzen der globalen Variablen by Reference:

PHP:
class MyInclude{
    protected $_vars = array();
    protected $_path;

    public function __construct($path){
        $this->_path = $path;
    }

    public function addVar($key, $value){
        $this->_vars[$key] = $value;
    }

    public function require(){
        foreach($this->_vars AS $key => $value){
            $$key = $value;
        }
        require $this->_path;
    }

}

Wäre die wohl sauberste Lösung, da nicht jedes Script Zugriff auf jede Variable hätte. Aber das einsetzen wäre wohl nicht mehr schön. Zudem muss man, wenn auch auf nicht-Objekte schreibend zugegriffen werden soll, darauf achten, die Variablen sauber als Referenzen zu übergeben.

Vom Aufwand her wäre eine Registry da natürlich effizienter.
 
Zurück
Oben