Web36: Scritp ausführen und Ergebnis sichern

Hallo,

ich habe mehrere tolle RSS Feeds die auch sehr gefragt sind. Leider entspricht jede Abfrage einer Datenbankabfrage.
Um nun den Serverload etwas herunter zu dezimieren, möchte ich per php und Cronjob die Abfrage im 5 Min Tackt in eine andere Datei schreiben.

Mein Ansatz ist:
<?php

$quelle = 'http://www.heise.de/newsticker/heise-atom.xml';
$ziel = '/html/test/ziel.rss';

// Sichergehen, dass die Datei existiert und beschreibbar ist
if (is_writable($ziel)) {

// Quellendatei öffnen
if (!$quelleopen = implode('', file($quelle))) {
         print "Kann die Datei $quelle nicht öffnen";

}
    // zieldatei datei öffnen
    if (!$zielopen = fopen($ziel, "r+")) {
                         print "Kann die Datei $ziel nicht öffnen";
                         exit;
    }

// Schreibe Quelle in Ziel .
                    if (!fwrite($zielopen, $quelleopen)) {
                        print "Kann in die Datei $zielopen nicht schreiben";
                        exit;
    }

print "Fertig, in Datei $ziel wurde $quelle geschrieben";

fclose($quelleopen);
fclose($zielopen);

} else {
    print "Die Datei $ziel ist nicht schreibbar";
}
?>

Die URL http://www.heise.de/newsticker/heise-atom.xml nutze ich in diesem Fall um eine sichere Quelle zu haben die keinen Timeout auslöst.

Leider habe ich trozdem einen Error 600 obwohl die Schreibrechte richtig vergeben worden sind.

Jemand eine Vorahnung?

  1. Hello,

    ich habe mehrere tolle RSS Feeds die auch sehr gefragt sind. Leider entspricht jede Abfrage einer Datenbankabfrage.
    Um nun den Serverload etwas herunter zu dezimieren, möchte ich per php und Cronjob die Abfrage im 5 Min Tackt in eine andere Datei schreiben.

    Das habe ich zwar jetzt nicht verstanden, aber das muss ich auch nicht unbedingt.
    Ich frage mich nur, warum Du die Datei dann immer überschreibst?
    Dann brauchst Du auch vorher nicht zu gucken, ob sie vorhanden ist.

    Mein Ansatz ist:
    <?php

    $quelle = 'http://www.heise.de/newsticker/heise-atom.xml';
    $ziel = '/html/test/ziel.rss';

    // Sichergehen, dass die Datei existiert und beschreibbar ist

    hier baust Du Dir einen "TOCTOU"-Fehler. Wofür das is_writable() wirklich gut ist

    kann ich mir nicht denken. Vernünftige FehlerNUMMMERN bei fopen() wären wesentlich

    besser. Aber das kannst Du ja nicht ändern, wenn das PHP-Konzept hier kaputt ist.

    Jedenfalls ist die Abfrage fast) für die Füße...

    if (is_writable($ziel))

    {

    // Quellendatei öffnen

    #> if (!$quelleopen = implode('', file($quelle)))
    #  {

    Dafür fragst Du hier überhaupt nicht, ob file() Erfolg hatte.

    Implode() beschwert sich zwar mit einer Warnung, wenn file() false geliefert hat,

    aber richtig wäre es, das Ergebnis von file() abzufragen.

    Außerdem geht das inzwischen auch in einem Schritt:

    if (!$quelleopen = file_get_contents($quelle))
      {

    print "Kann die Datei $quelle nicht öffnen";

    }
      else   ## Wenn schon Kontrolle, dann auch konsequent
      {

    // zieldatei datei öffnen
        if (!$zielopen = fopen($ziel, "r+"))

    {

    print "Kann die Datei $ziel nicht öffnen";

    #                          exit;  ## Warum abbrechen und die Seite halbfertig hinterlassen?
          }
          else
          {

    // Schreibe Quelle in Ziel .

    ## willst Du hier wirklich den Inhalt der Datei überschreiben?
          ## dann hättest Du sie auch gelich mit 'wb+' öffnen können.

    if (!fwrite($zielopen, $quelleopen))

    {
                              print "Kann in die Datei $ziel nicht schreiben";

    exit;  ## hier auch wieder: Wieso Scriptabbruch?

    }

    }

    fclose($zieldatei);   ##  Datei schließen nicht vergessen.
         print "Fertig, in Datei $ziel wurde $quelle geschrieben";

    }

    # fclose($quelleopen);   ## $quelleopen ist kein Handle, sondern ein Stringbuffer
      # fclose($zielopen);     ## man kann nur Dateien schließen, die auch offen sind.

    }

    else
      {
          print "Die Datei $ziel ist nicht schreibbar";
          ## und woran liegt es? Ist sie nicht vorhanden, oder ist sie schreibgeschützt?

    }

    ?>

    Die URL http://www.heise.de/newsticker/heise-atom.xml nutze ich in diesem Fall um eine sichere Quelle zu haben die keinen Timeout auslöst.

    Leider habe ich trozdem einen Error 600 obwohl die Schreibrechte richtig vergeben worden sind.

    Könntest Du bitte mal die Original-Fehlermeldung nachliefern?

    Harzliche Grüße vom Berg und Frohe Weihnachtszeit

    Tom

    --
    Nur selber lernen macht schlau

    1. Hallo Tom,

      zuerst möchte ich dir einmal (hoffentlich verständlich) erörtern was ich denn überhaupt möchte.
      Hintergrund ich habe mehrere sehr gut abgerufene RSS-Feeds. Bei jedem Abruf eines RSS Feeds fragt ein phpscript die Datenbank ab.
      Soweit so gut, nun ist der Serverload aber aufgrund der RSS  Datenbankabfragen zeitweise in ungeahnte höhen geschnellt.
      Um dieses zu Unterbinden und nicht im Quelltext der RSS- Abfrage zu fummeln (zumal ich noch weitere RSS Feeds gerne Cachen möchte) habe ich mir diese zugegeben manuelle Lösung überlegt.

      Daher wird die Datei auch immer wieder Überschrieben, nähmlich mit dem ergebnis einer frischen Abfrage, welche per Cronjob alle 5 Minuten aus der Original PHPDatenbankabfrage geholt wird.

      Ich hoffe das ist Verständlich!?!?

      Die Fehlermeldung:
      Serverfehler!

      Die Anfrage kann nicht beantwortet werden, da im Server ein interner Fehler aufgetreten ist.

      Fehlermeldung:
      Premature end of script headers: test.php

      Sofern Sie dies für eine Fehlfunktion des Servers halten, informieren Sie bitte den Webmaster hierüber.
      Error 500

      Auch mit der "korrigierten" Fassung

      Hello,

      ich habe mehrere tolle RSS Feeds die auch sehr gefragt sind. Leider entspricht jede Abfrage einer Datenbankabfrage.
      Um nun den Serverload etwas herunter zu dezimieren, möchte ich per php und Cronjob die Abfrage im 5 Min Tackt in eine andere Datei schreiben.

      Das habe ich zwar jetzt nicht verstanden, aber das muss ich auch nicht unbedingt.
      Ich frage mich nur, warum Du die Datei dann immer überschreibst?
      Dann brauchst Du auch vorher nicht zu gucken, ob sie vorhanden ist.

      Mein Ansatz ist:
      <?php

      $quelle = 'http://www.heise.de/newsticker/heise-atom.xml';
      $ziel = '/html/test/ziel.rss';

      // Sichergehen, dass die Datei existiert und beschreibbar ist

      hier baust Du Dir einen "TOCTOU"-Fehler. Wofür das is_writable() wirklich gut ist

      kann ich mir nicht denken. Vernünftige FehlerNUMMMERN bei fopen() wären wesentlich

      besser. Aber das kannst Du ja nicht ändern, wenn das PHP-Konzept hier kaputt ist.

      Jedenfalls ist die Abfrage fast) für die Füße...

      if (is_writable($ziel))
        {

      // Quellendatei öffnen
      #> if (!$quelleopen = implode('', file($quelle)))
      #  {

      Dafür fragst Du hier überhaupt nicht, ob file() Erfolg hatte.

      Implode() beschwert sich zwar mit einer Warnung, wenn file() false geliefert hat,

      aber richtig wäre es, das Ergebnis von file() abzufragen.

      Außerdem geht das inzwischen auch in einem Schritt:

      if (!$quelleopen = file_get_contents($quelle))
        {

      print "Kann die Datei $quelle nicht öffnen";

      }
        else   ## Wenn schon Kontrolle, dann auch konsequent
        {

      // zieldatei datei öffnen
          if (!$zielopen = fopen($ziel, "r+"))
            {
                               print "Kann die Datei $ziel nicht öffnen";
      #                          exit;  ## Warum abbrechen und die Seite halbfertig hinterlassen?
            }
            else
            {

      // Schreibe Quelle in Ziel .
            ## willst Du hier wirklich den Inhalt der Datei überschreiben?
            ## dann hättest Du sie auch gelich mit 'wb+' öffnen können.

      if (!fwrite($zielopen, $quelleopen))
                            {
                                print "Kann in die Datei $ziel nicht schreiben";
                              exit;  ## hier auch wieder: Wieso Scriptabbruch?
                            }
          }

      fclose($zieldatei);   ##  Datei schließen nicht vergessen.
           print "Fertig, in Datei $ziel wurde $quelle geschrieben";

      }

      # fclose($quelleopen);   ## $quelleopen ist kein Handle, sondern ein Stringbuffer
        # fclose($zielopen);     ## man kann nur Dateien schließen, die auch offen sind.

      }
        else
        {
            print "Die Datei $ziel ist nicht schreibbar";
            ## und woran liegt es? Ist sie nicht vorhanden, oder ist sie schreibgeschützt?

      }
      ?>

      Die URL http://www.heise.de/newsticker/heise-atom.xml nutze ich in diesem Fall um eine sichere Quelle zu haben die keinen Timeout auslöst.

      Leider habe ich trozdem einen Error 600 obwohl die Schreibrechte richtig vergeben worden sind.

      Könntest Du bitte mal die Original-Fehlermeldung nachliefern?

      Harzliche Grüße vom Berg und Frohe Weihnachtszeit

      Tom

      1. Hello,

        Serverfehler!
        Die Anfrage kann nicht beantwortet werden, da im Server ein interner Fehler aufgetreten ist.

        Fehlermeldung:
        Premature end of script headers: test.php

        Sofern Sie dies für eine Fehlfunktion des Servers halten, informieren Sie bitte den Webmaster hierüber.
        Error 500

        Ich rate mal:
        Du benutzt PHP in der CGI-Version?

        Unter welchem User läuft der Cron-Job?
        Ich vermute, dass die Rechte (Owner + Group) nicht stimmen, und das Script deshalb schon eine Fehlermeldung verursacht, bevor es überhaupt ausgeführt werden kann.
        Hast Du es mal direkt in der Shell aufgerufen?

        Harzliche Grüße vom Berg und Frohe Weihnachtszeit

        Tom

        --
        Nur selber lernen macht schlau

        1. Hi Tom,

          Du benutzt PHP in der CGI-Version?
          Da ich keine lokale Installation habe, und der Webspace mit Apache läuft, denke ich einfach "NEIN".

          Unter welchem User läuft der Cron-Job?
          Noch garnicht, bisher führe ich die Datei immer per Hand aus.

          Hast Du es mal direkt in der Shell aufgerufen?
          Leider habe ich keinen Konsolenzugang, und keine lokale installation.

          Danke für die Wünsche ebenso zurück.

          Hello,

          Serverfehler!
          Die Anfrage kann nicht beantwortet werden, da im Server ein interner Fehler aufgetreten ist.

          Fehlermeldung:
          Premature end of script headers: test.php

          Sofern Sie dies für eine Fehlfunktion des Servers halten, informieren Sie bitte den Webmaster hierüber.
          Error 500

          Ich rate mal:
          Du benutzt PHP in der CGI-Version?

          Unter welchem User läuft der Cron-Job?
          Ich vermute, dass die Rechte (Owner + Group) nicht stimmen, und das Script deshalb schon eine Fehlermeldung verursacht, bevor es überhaupt ausgeführt werden kann.
          Hast Du es mal direkt in der Shell aufgerufen?

          Harzliche Grüße vom Berg und Frohe Weihnachtszeit

          Tom