simson: require "löschen"

Hallo,

vermutlich eine etwas merkwürdige Frage:
Ist es möglich mit require('irgendwas.php') importierten Code wieder zu löschen bzw. das require wieder rückgängig zu machen?

Ich brauche den Code aus dem require um einige Bedingungen zu prüfen. Da die Datei allerdings später noch mal an anderer Stelle mit anderen Vorgaben noch mal mit require_once importiert werden muss, müsste ich des erst require irgendwie wieder rückgängig machen.
Das require_once kann auch nicht in ein require geändert werden und muss auf jeden Fall ausgeführt werden.

Hoffe ich konnte mein Problem einigermaßen verständlich darstellen.
Bin für jeden Tipp dankbar

MfG
simson

  1. Hallo

    Ich brauche den Code aus dem require um einige Bedingungen zu prüfen.

    dafür schreibst Du Dir am besten eine Funktion oder einen Satz von Funktionen.

    Da die Datei allerdings später noch mal an anderer Stelle mit anderen Vorgaben

    und an der Stelle solltest Du die zu dieser Stelle passenden Funktionen verwenden.

    Ich vermute daher, dass Du eher ein konzeptionelles Problem hast.

    Freundliche Grüße

    Vinzenz

    1. Hallo

      Ich brauche den Code aus dem require um einige Bedingungen zu prüfen.

      dafür schreibst Du Dir am besten eine Funktion oder einen Satz von Funktionen.

      Genau das versuche ich zu vermeiden, denn ich will die vorhandenen Funktionen nutzen.

      Da die Datei allerdings später noch mal an anderer Stelle mit anderen Vorgaben

      und an der Stelle solltest Du die zu dieser Stelle passenden Funktionen verwenden.

      Ich vermute daher, dass Du eher ein konzeptionelles Problem hast.

      Ich kann an dem Konzept nichts ändern. Auf den Code, den ich importiere hab ich quasi keinen direkten Zugriff. Kann ihn also nicht ändern, brauche aber kurzzeitig Funktionen davon.

      1. Hi!

        Ich kann an dem Konzept nichts ändern. Auf den Code, den ich importiere hab ich quasi keinen direkten Zugriff. Kann ihn also nicht ändern, brauche aber kurzzeitig Funktionen davon.

        Dann werd doch mal spezifischer. Ich kann mir grad nicht vorstellen, warum ein einmaliges einfuegen der benoetigten Funktionen nicht genuegt.

        Vielleicht hast Du doch ein konzeptionelles Problem. Im aufrufenden Script.

        1. Hallo Steel,

          Ich kann an dem Konzept nichts ändern. Auf den Code, den ich importiere hab ich quasi keinen direkten Zugriff. Kann ihn also nicht ändern, brauche aber kurzzeitig Funktionen davon.

          Dann werd doch mal spezifischer. Ich kann mir grad nicht vorstellen, warum ein einmaliges einfuegen der benoetigten Funktionen nicht genuegt.

          Vielleicht hast Du doch ein konzeptionelles Problem. Im aufrufenden Script.

          oder die Funktionen sind zu speziell geschrieben (Verwendung globaler oder gar superglobaler Variablen fällt mir ein, oder sie erzeugen eine Ausgabe - was man allerdings mit den Funktionen zur Ausgabesteuerung abfangen könnte, oder oder ...)

          Vielleicht sollte sich der Ausgangsposter mal den Artikel Entwicklung wiederverwendbarer Software von Achim Schrepfer in SELFHTML aktuell durcharbeiten.

          Freundliche Grüße

          Vinzenz

  2. hallo,

    Ist es möglich mit require('irgendwas.php') importierten Code wieder zu löschen bzw. das require wieder rückgängig zu machen?

    Nein. Es sei denn, du veränderst von Hand deinen Scriptcode. Was du aber machen kannst, ist, die "Wirkung" aufzuheben, das heißt, das, was dein Code bewirkt, wieder rückgängig zu machen. Das _kann_ mit einem Bündel von diversen Funktionen praktiziert werden. Es gibt darüber übrigens grade einen interessanten Teilthread hier im Forum, der dir allerhand Hinweise bieten sollte.

    Hoffe ich konnte mein Problem einigermaßen verständlich darstellen.

    Nicht wirklich.

    Grüße aus Berlin

    Christoph S.

    --
    Visitenkarte
    ss:| zu:) ls:& fo:) va:) sh:| rl:|
  3. Hallo simson,

    Wie andere Leute bereits erwähnt haben, hast Du mit absoluter Sicherheit ein konzeptionelles Problem, das Du am besten vollkommen anders löst. Allerdings gibt es unter Umständen eine Lösung, die das erreicht, was Du willst, wenn sie auch extrem eklig und absolut nicht empfehlenswert ist (um das mindeste zu sagen):

    Ich brauche den Code aus dem require um einige Bedingungen zu prüfen. Da die Datei allerdings später noch mal an anderer Stelle mit anderen Vorgaben noch mal mit require_once importiert werden muss, müsste ich des erst require irgendwie wieder rückgängig machen.

    Ich nehme an, dass in der Datei direkt Code ist und nicht bloß Funktionen - sonst könntest Du die einfach beliebig oft mit require_once einbinden (sie würde ja dann nur einmal eingebunden werden effektiv) und die Funktionen einfach aufrufen - der einzige Grund also ist, dass Code direkt darin vorkommt.

    Wenn Du sicherstellen willst, dass der Code später per require_once eingebunden wird, musst Du dafür sorgen, dass der interne Zähler von PHP beim ersten Einbinden *nicht* anspringt, so dass PHP noch denkt, dass die Datei noch nicht eingebunden wurde. Das kannst Du am einfachsten durch file_get_contents + eval erreichen, also:

    eval ('?>'.file_get_contents ('datei').'<?php');

    anstelle von (was Du jetzt hast):

    require 'datei';

    Ein require_once *nach* dem eval() + file_get_contents() wird die Datei trotzdem noch einmal einbinden. Das ganze eval()-Konstrukt wird allerdings auf die Schnauze fliegen, wenn in der einzubindenden Datei irgendwo an wichtiger Stelle __FILE__ verwendet wird. Wenn das der Fall ist, funktioniert meine Lösung nicht.

    Jetzt kann zusätzlich das Problem auftreten, dass in der Datei Klassen oder Funktionen definiert werden, die dann beim späteren require_once() wieder definiert werden und somit PHP mit einem Fatal Error abbricht. Auch dafür gibt es eine (teilweise) Abhilfe: Die runkit-Erweiterung. Wenn Du keine C-Erweiterungen installieren kannst, funktioniert meine Lösung nicht [1].

    Runkit bietet Dir nun eine Methode runkit_function_remove(), mit der Du bereits definierte Funktionen "löschen" kannst. Wenn Du dies nun mit allen Funktionen in der eingebundenen Datei machst, nachdem Du sie eingebunden und verwendet hast, dann ist es so, als ob sie nicht eingebunden war.

    Runkit kann jedoch keine Klassen entfernen. Wenn in der Datei Klassen definiert werden, funktioniert meine Lösung nicht.

    Ferner: Wenn in der Datei selbst per require_once() wieder Dateien eingebunden werden, die direkt Code enthalten, der ausgeführt werden soll, funktioniert meine Lösung nicht.

    Als Alternative zu "per normalem eval() einbinden" könntest Du ferner versuchen, ob Du mit dem PHP-Sandboxing-Verfahren von runkit nicht auch zum Ziel kommen könntest - dazu musst Du allerdings eine PHP-Installation haben, die mit Thread-Unterstützung gebaut ist, dann könntest Du z.B. folgendes probieren:

    $php = new Runkit_Sandbox();  
    $php->require ('datei');
    

    (Ob das klappt und das require nur in der Sandbox bleibt oder ob das auch global gilt, weiß ich nicht - evtl. musst Du die Sandbox auch vorher mit anderem Kram initialisieren, wie z.B. globale Variablen o.ä. - siehe die Runkit-Doku.)

    ---------------------------- schnipp -----------------------------

    Bist Du Dir sicher, dass Du nicht doch lieber konzeptionelle Probleme aus Deinem Code entfernen willst?

    Viele Grüße,
    Christian

    [1] In den pecl-Snapshots für Windows (d.h. vorkompilierte C-Erweiterungen für Windows) ist runkit nicht enthalten, nur der Vorgänger classkit, der jedoch nicht das kann, was Du brauchst, den Link zur ZIP mit den ganzen DLLs gebe ich Dir trotzdem mal: http://snaps.php.net/win32/pecl5.3-win32-latest.zip

    Und das letzte UNIX-Release wird auch nicht funktionieren, Installation erfolgt über:

    cvs -d :pserver:cvsread@cvs.php.net:/repository checkout pecl/runkit
    cd pecl/runkit
    phpize
    ./configure --enable-runkit --enable-runkit-modify --enable-runkit-super --enable-runkit-sandbox
    make
    make install