Heinz: PHP unlink funktioniert nicht

Moin alle zusammen, Aus irgendeinem Grund funktioniert das löschen einer ics-Datei bei mir nicht, jedenfalls nicht im gleichen Script, sondern nur wenn ich das extra ausführe. Ich habe ein Formular mit mehrer Submit-Button. Wenn der Button ics gedrückt wird, wird eine ics-Datei mit allen daten erstellt, gespeichert und dann aufgerufen bzw. heruntergeladen. Nun will ich nach dem runterladen die Datei wieder löschen, damit ich nicht soviel auf dem Server habe. Ich hab das mit unlink($ics); und mit unlink($filename . '.ics'); versucht und einmal mit einer Funktion und die dann in der if-Abfrage aufgerufen. Beides funktioniert nicht.

if(isset($_POST['ics'])){			
	// Termindatei erstellen und speichern
	$ics = new ICS($start, $ende, $name, $description, $location, $filename);
	$ics->save();
	
	// Termindatei herunterladen
	header('Location: ./' . $filename . '.ics');
	
	// Termindatei löschen
	if(file_exists($ics)){
		unlink($ics);
	}

Wenn ich eine extra Datei erstelle wo nur unlink($filename . '.ics'); drinsteht und die aufrufe, wird die jeweilige Datei gelöscht.

Was ist falsch?
Viele Dank im voraus
Heinz

  1. Tach!

    // Termindatei erstellen und speichern $ics = new ICS($start, $ende, $name, $description, $location, $filename); $ics->save();

    In $ics ist nun ein Objekt abgelegt, sprich: eine Instanz der Klasse ICS.

    // Termindatei löschen if(file_exists($ics)){ unlink($ics); }

    Sowohl file_exists() als auch unlink() möchten einen Dateinamen haben.

    Wenn ich eine extra Datei erstelle wo nur unlink($filename . '.ics'); drinsteht und die aufrufe, wird die jeweilige Datei gelöscht.

    Da rufst du die Funktion ja auch mit einem Dateinamen auf. Vorausgesetzt, in $filename ist ein Dateiname ohne Endung als String enthalten.

    Was ist falsch?

    Ein Objekt ist kein String mit einem Dateinamen als Inhalt.

    dedlfix.

    1. Hallo,

      Sowohl file_exists() als auch unlink() möchten einen Dateinamen haben.

      Das hab ich jetzt behoben indem ich da den Dateinamen eingetragen habe. Problem ist jetzt, dass er mir sagt, dass dir Datei nicht existiert. Kann es sein, dass er die Datei erst löscht und dann mit header() aufrufen will? Ich hab an der reinfolge nichts geändert... Woran liegt das dann?

      Heinz

  2. Hi,

    mal ganz abgesehen davon, daß $ics keinen Dateinamen enthält (siehe Antwort von dedlfix):

    	// Termindatei herunterladen
    	header('Location: ./' . $filename . '.ics');
    

    Das sagt, daß der Browser irgendwann in der Zukunft (nämlich dann, wenn ihn die Response erreicht) einen neuen Request stellen soll für die Datei.

    	// Termindatei löschen
    	if(file_exists($ics)){
    		unlink($ics);
    	}
    

    Unmittelbar danach (also noch lange, bevor der Browser die Response bekommen hat und noch viel länger bevor der Browser den neuen Request gestellt hat), wird die Datei entsorgt. Der Browser hat also dann gar keine Chance, sich die Datei zu holen, da sie ja schon gelöscht ist …

    cu,
    Andreas a/k/a MudGuard

    1. Ok,
      und wie bekomme ich das hin, dass ich die Datei dann runterladen kann?

      Heinz

      1. Hello,

        on the fly erzeugen und gar nicht erst auf der Platte abspeichern.

        Liebe Grüße
        Tom S.

        --
        Es gibt nichts Gutes, außer man tut es
        Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
        1. Hi,
          danke damit funktioniert es.

          Gruß
          Heinz

          1. Hello,

            könntest Du bitte mal einen Link auf deine ICS-Klasse posten? Da gibt es doch scheinbar dutzende. Ich wüsste gerne, was die macht.

            Liebe Grüße
            Tom S.

            --
            Es gibt nichts Gutes, außer man tut es
            Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
            1. Hi,

              könntest Du bitte mal einen Link auf deine ICS-Klasse posten?

              Ich weiß zwar nicht genau was du mit "Link auf ICS-Klasse" meinst, aber meine ICS-Klasse sieht so aus:

              class ICS{
              	var $name;
              	var $data;
              	
              	function ICS($start, $end, $name, $description, $location, $filename){
              		$this->name = $filename;
              		$this->data = "BEGIN:VCALENDAR\nVERSION:2.0\nMETHOD:PUBLISH\nBEGIN:VEVENT\nDTSTART:" . date("Ymd\THis",strtotime($start)) . "\nDTEND:" . date("Ymd\THis",strtotime($end)) . "\nLOCATION:" . $location . "\nTRANSP: OPAQUE\nSEQUENCE:0\nUID:\nDTSTAMP:" . date("Ymd\THis") . "\nSUMMARY:" . $name . "\nDESCRIPTION:" . $description . "\nPRIORITY:1\nCLASS:PUBLIC\nBEGIN:VALARM\nTRIGGER:-PT30M\nACTION:DISPLAY\nDESCRIPTION:Reminder\nEND:VALARM\nEND:VEVENT\nEND:VCALENDAR\n";
              	}
              	
              	function save(){
              		header("Content-type:text/calendar");
              		header('Content-Disposition: attachment; filename="'.$this->name.'.ics"');
              		header('Content-Length: '.strlen($this->data));
              		header('Connection: close');
              		echo $this->data;
              	}
              }
              

              Gruß
              Heinz

              1. Hello,

                könntest Du bitte mal einen Link auf deine ICS-Klasse posten?

                Ich weiß zwar nicht genau was du mit "Link auf ICS-Klasse" meinst,

                es gibt dutzende fertige ICS-Klassen, die ganz viel können aber manchmal auch etwas falsch machen...

                aber meine ICS-Klasse sieht so aus:

                class ICS{
                	var $name;
                	var $data;
                	
                	function ICS($start, $end, $name, $description, $location, $filename){
                		$this->name = $filename;
                		$this->data = "BEGIN:VCALENDAR\nVERSION:2.0\nMETHOD:PUBLISH\nBEGIN:VEVENT\nDTSTART:" . date("Ymd\THis",strtotime($start)) . "\nDTEND:" . date("Ymd\THis",strtotime($end)) . "\nLOCATION:" . $location . "\nTRANSP: OPAQUE\nSEQUENCE:0\nUID:\nDTSTAMP:" . date("Ymd\THis") . "\nSUMMARY:" . $name . "\nDESCRIPTION:" . $description . "\nPRIORITY:1\nCLASS:PUBLIC\nBEGIN:VALARM\nTRIGGER:-PT30M\nACTION:DISPLAY\nDESCRIPTION:Reminder\nEND:VALARM\nEND:VEVENT\nEND:VCALENDAR\n";
                	}
                	
                	function save(){
                		header("Content-type:text/calendar");
                		header('Content-Disposition: attachment; filename="'.$this->name.'.ics"');
                		header('Content-Length: '.strlen($this->data));
                		header('Connection: close');
                		echo $this->data;
                	}
                }
                

                Da würde ich jetzt die Methode save() umbenennen in toHTML(), noch eine toString() hinzufügen, die einen String ohne Header erzeugt und eine save() bauen, die tatsächlich eine Datei als Ziel hat.

                Liebe Grüße
                Tom S.

                --
                Es gibt nichts Gutes, außer man tut es
                Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
                1. Tach!

                  Da würde ich jetzt die Methode save() umbenennen in toHTML(), noch eine toString() hinzufügen, die einen String ohne Header erzeugt und eine save() bauen, die tatsächlich eine Datei als Ziel hat.

                  Wenn man denn so viel Funktionalität braucht. save() ist sicherlich in seinem Fall entbehrlich. Einen Kalender-Eintrag braucht man am Server eher nicht im ICS-Format, das für die Einarbeitung in die Kalender von Clients gedacht ist. toHTML() wäre aber in jedem Fall falsch. send() oder output() sind zwar auch keine Glanzleistungen, aber könnten schon eher als beschreibende Namen hinkommen.

                  dedlfix.

                  1. Hello,

                    [toHTML()]
                    stimmt!

                    Ich hatte dabei auch toHTTPformat() im Sinn. Jedenfalls wollte ich damit ausdrücken, dass die Ausgabe wie erforderlich nur erst vorbereitet (als String) wird, der dann mit save() als Datei gespeichert oder dann eben mit send()/response() abgeschickt werden kann.

                    Liebe Grüße
                    Tom S.

                    --
                    Es gibt nichts Gutes, außer man tut es
                    Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.