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