fopen() Funktion erlauben/verbieten
Herbert H
- php
Hallo zusammen,
ich bin gerade halb am Verzweifeln was den gebrauch von fopen() angeht:
Beim Ausführen einer PHP Datei auf meinem Server sollen einfach ein paar Daten in eine neu angelegte XML Datei geschrieben werden. Der Einfachheit halber sind es auch erstmal nur Testdaten. Das ganze sieht bei mir so aus:
$xmlFile = "test.xml";
$xmlHandle = fopen($xmlFile, "w") or die("fopen fehlgeschlagen !!!");
$xmlString = "<daten><name>Max Mustermann</name>email>test@test.test</email><strasse>Teststrasse</strasse></daten>";
fwrite($xmlHandle, $xmlString);
fclose($xmlHandle);
Wenn ich NUR diesen code in eine allein stehende PHP Datei schreibe und diese dann ausführe macht es auch genau was es sollte. Mein eigentliches Ziel ist es allerdings, diesen Code in ein bestehendes System zu integrieren.
Ich habe auf meinem Server ein frisches Magento Shop System aufgesetzt bei dem ja etliche vielschichtige Scripte, Module etc ineinander übergreifen. Ich erwarte jetzt nicht, dass sich hier Magento-erfahrene User zu Wort melden sondern habe lediglich die Frage ob es sein kann, dass die fopen() Funktion zur Laufzeit irgendwo deaktiviert werden kann.
Denn wenn ich den Code in eine bestehende Datei dieses Systems integriere funktioniert er nicht mehr. Stattdessen erhalte ich die in der or die() Maßnahme angegebene Fehlermeldung. Dabei sei noch gesagt, dass diese Datei im exakt selben Verzeichnis liegt wie die funktionierende Testdatei die nur den obrigen Code enthält.
Ist es also irgendwie möglich, Funktionalitäten wie fopen(), fwrite() etc für Bestimmte Dateien oder auch direkt zur Laufzeit zu erlauben bzw zu verbieten?
Ich bedanke mich im Voraus für alle hilfreichen Tips!
Hi,
habe lediglich die Frage ob es sein kann, dass die fopen() Funktion zur Laufzeit irgendwo deaktiviert werden kann.
disable_functions existiert, ist allerdings nicht zur Laufzeit, sondern nur in der php.ini setzbar.
Denn wenn ich den Code in eine bestehende Datei dieses Systems integriere funktioniert er nicht mehr. Stattdessen erhalte ich die in der or die() Maßnahme angegebene Fehlermeldung.
Wenn fopen gar nicht erlaubt wäre, würdest du aber eine Meldung bekommen, die auch das aussagt.
Dein Problem liegt ziemlich sicher woanders.
Prüfe bspw. mit is_writable, ob PHP an dieser Stelle die Datei beschreiben darf.
MfG ChrisB
Hi,
habe lediglich die Frage ob es sein kann, dass die fopen() Funktion zur Laufzeit irgendwo deaktiviert werden kann.
disable_functions existiert, ist allerdings nicht zur Laufzeit, sondern nur in der php.ini setzbar.
Denn wenn ich den Code in eine bestehende Datei dieses Systems integriere funktioniert er nicht mehr. Stattdessen erhalte ich die in der or die() Maßnahme angegebene Fehlermeldung.
Wenn fopen gar nicht erlaubt wäre, würdest du aber eine Meldung bekommen, die auch das aussagt.
Dein Problem liegt ziemlich sicher woanders.
Prüfe bspw. mit is_writable, ob PHP an dieser Stelle die Datei beschreiben darf.MfG ChrisB
Ich habe es mal mit is_writable probiert:
Beim Ausführen der Testdatei erhalte ich zunächst false, vermultich weil die Datei noch nicht existiert. Sie wird dann allerdings erstellt und auch korrekt mit Inhalt gefüllt. Wenn ich das Script dann nochmal laufen lasse erhalte ich auch ein true, soweit scheint hier alles OK zu sein.
Mit der Systemdatei sieht das etwas anders aus. Dort erhalte ich immer false als Rückgabewert, egal wie oft ich es Versuche und ungeachtet ob die XML Datei schon angelegt wurde oder nicht.
Auch wenn ich die Datei zunächst erstelle und dann manuell alle Berechtigungen setze (777) macht das keinen Unterschied.
Hi,
bitte sinnvoll zitieren, nicht gedankenlos einfach alles.
Mit der Systemdatei sieht das etwas anders aus. Dort erhalte ich immer false als Rückgabewert, egal wie oft ich es Versuche und ungeachtet ob die XML Datei schon angelegt wurde oder nicht.
Beachte, dass du auch Schreibrechte im Verzeichnis brauchst.
MfG ChrisB
Beachte, dass du auch Schreibrechte im Verzeichnis brauchst.
Stimmt, das habe ich auch schon überprüft. Und wie gesagt befinden sich beide PHP Dateien (Systemdatei und meine Testdatei) im selben Verzeichnis.
Hallo,
Stimmt, das habe ich auch schon überprüft. Und wie gesagt befinden sich beide PHP Dateien (Systemdatei und meine Testdatei) im selben Verzeichnis.
Nur so eine Idee:
Wird die PHP-Datei vielleicht per include() oder so in eine andere Datei eingebunden? Liegt diese andere Datei vielleicht in einem anderen Verzeichnis?
Du kannst ja die Testdatei test.xml schon mal ablegen und dann mit file_exists() prüfen, ob sie überhaupt gefunden wird.
Freundliche Grüsse, Thomas
Hello,
Wird die PHP-Datei vielleicht per include() oder so in eine andere Datei eingebunden? Liegt diese andere Datei vielleicht in einem anderen Verzeichnis?
Das ist ebenfalls eine Möglichkeit.
Die sollte aber spätestens dann ausscheiden, wenn absolute Pfade im Dateisystem angegeben werden.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hi!
$xmlHandle = fopen($xmlFile, "w") or die("fopen fehlgeschlagen !!!");
[...] ob es sein kann, dass die fopen() Funktion zur Laufzeit irgendwo deaktiviert werden kann.
Daran liegt es bestimmt nicht. (Mir ist auch nur eine Konfigurationsoption bekannt, die man im Script nicht mehr ändern kann.)
Denn wenn ich den Code in eine bestehende Datei dieses Systems integriere funktioniert er nicht mehr. Stattdessen erhalte ich die in der or die() Maßnahme angegebene Fehlermeldung.
Das heißt, dass die Funktion aufgerufen werden konnte, denn sonst hätte sich PHP mit einer Fehlermeldung darüber beschwert. Vielmehr wird es so sein, dass die Funktion nicht fehlerfrei laufen konnte. Vermutlich konnte die Datei nicht erzeugt werden, weil Rechte fehlen. Die genaue Fehlermeldung wird üblicherweise ausgegeben, aber das wird dein System deaktiviert haben, wenn du nichts siehst. error_reporting auf E_ALL und display_errors auf on setzen sollte helfen.
Lo!
$xmlFile = "test.xml";
$xmlHandle = fopen($xmlFile, "w") or die("fopen fehlgeschlagen !!!");
$xmlString = "<daten><name>Max Mustermann</name>email>test@test.test</email><strasse>Teststrasse</strasse></daten>";
fwrite($xmlHandle, $xmlString);
fclose($xmlHandle);
Ich hoffe doch, du erzeugst dein XML nicht auch später zu Fuß. Dein aktuelles XML hat einen Syntaxfehler, mit einem XML-Parser wäre das nicht passiert.
Das Maskieren von entsprechenden Zeichen kannst du dir dann auch sparen, das macht der XML-Parser für dich - ebenso ist natürlich eine XML-Deklaration vorhanden, die bei dir ebenfalls fehlt.
~~~php
$xml = new SimpleXMLElement('<daten />');
foreach($this->pages as $value) {
$item = $xml->addChild('name', 'Max Mustermann');
$item = $xml->addChild('email', 'test@example.com');
}
echo $xml->asXML();
Das kommt davon, wenn man auf die Schnelle etwas kopiert :)
Die foreach-Schleife war natürlich Unsinn:
$xml = new SimpleXMLElement('<daten />');
$item = $xml->addChild('name', 'Max Mustermann');
$item = $xml->addChild('email', 'test@example.com');
echo $xml->asXML();
Ich hoffe doch, du erzeugst dein XML nicht auch später zu Fuß. Dein aktuelles XML hat einen Syntaxfehler, mit einem XML-Parser wäre das nicht passiert.
Sorry, das Tag-Zeichen ist beim Copy Paste verlorengegangen. Der Original String ist korrekt - von meinem Testscript wird die Datei auch korrekt erzeugt und lässt sich dann im Browser anzeigen.
Daran liegt es also nicht.
Sorry, das Tag-Zeichen ist beim Copy Paste verlorengegangen.
So schnell kanns gehen - darum einen XML-Parser verwenden, da solche Dinge garnicht erst passieren können.
Der Original String ist korrekt - von meinem Testscript wird die Datei auch korrekt erzeugt und lässt sich dann im Browser anzeigen.
Daran liegt es also nicht.
Das sagte ich auch nicht - es ging mir nur darum, dich darauf hinzuweisen, dass du hier möglicherweise sehr unsinnig arbeitest - zusätzliche Infos gibts hier gratis :)
Hello,
ich nehme an, dass PHP bei Dir als CGI/FastCGI läuft. Dann wäre es nämlich durchaus erklärlich:
Wenn Du das CMS laufen lässt, läuft es unter einem anderen User, als wenn Du dein Testscript startest. Dass "777" für die Datei nichts bringt, ist dann auch noch nachvollziehbar, denn vermutlich darf dein CMS überhaupt nicht auf den Pfad zugreifen, also schon nicht in die betroffenen Verzeichnisse eintreten, bzw. sie verändern.
"777" ist sowieso Mist. Das reißt nur Löcher in die Sicherheitsstruktur des ganzen Systems.
Sorge dafür, dass das CMS einer Gruppe angehört, die in dem betroffnen Verzeichnispfad schreiben und lesen darf. Übereigne das betroffene Verzeichnis dieser Gruppe. Setze das GID-Flag für diesen Pfad an geeigneter Stelle und stelle die UMASK für den Benutzer des CMS entsprechend ein, sodass für Verzeichnisse 770 (oder 774) und für Dateien 660 (oder 664) als Vorgabe übrig bleibt. Das müsste mWn einer umask von 003 entsprechen.
Die Umask muss in der Shell-Konfiguration des betroffenen Users (der des CMS) eingestellt werden.
Dann sollte es dauerhaft funktionieren.
Noch besser wäre es wahrschinlich, für den Owner des Verzeichnisses nebst Unterverzeichnissen den CMS-User einzutragen und den FTP-User, falls einer notweindig ist, mit den oben erwähnten Gruppenrechten zu bedenken. Dann muss der CMS-User aber trotzdem in derselben Gruppe sein, damit er nach einem Filezugriff des FTP-Users auch noch auf dessen Dateien zugreifen darf.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg